Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 3/4] gpio: raspberrypi-exp: Driver for RPi3 GPIO expander via mailbox service
From: Baruch Siach @ 2018-01-14  6:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1313448378.43279.1515839595810@email.1und1.de>

Hi Stefan,

Thanks for reviewing. Please find below a few questions.

On Sat, Jan 13, 2018 at 11:33:15AM +0100, Stefan Wahren wrote: 
> > +	default RASPBERRYPI_FIRMWARE
> > +	depends on OF_GPIO && RASPBERRYPI_FIRMWARE && \
> > +		(ARCH_BCM2835 || COMPILE_TEST)
> 
> Since this is default on RASPBERRYPI_FIRMWARE, we could remove it from the dependencies.

This driver does not work when RASPBERRYPI_FIRMWARE is not enabled. So the 
driver should not be selectable, regardless of its default enable/disable 
state.

> > +	help
> > +	  Turn on GPIO support for the expander on Raspberry Pi 3 boards, using
> > +	  the firmware mailbox to communicate with VideoCore on BCM283x chips.
> > +

[...]

> > --- /dev/null
> > +++ b/drivers/gpio/gpio-raspberrypi-exp.c
> > @@ -0,0 +1,258 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + *  Raspberry Pi 3 expander GPIO driver
> > + *
> > + *  Uses the firmware mailbox service to communicate with the
> > + *  GPIO expander on the VPU.
> > + *
> > + *  Copyright (C) 2017 Raspberry Pi Trading Ltd.
> 
> 2018?

Why? Raspberry Pi Trading Ltd added no code to this driver in 2018.

[...]

> > +static struct platform_driver rpi_exp_gpio_driver = {
> > +	.driver	= {
> > +		.name		= MODULE_NAME,
> > +		.owner		= THIS_MODULE,
> 
> Please drop this, too.

Why? Recent GPIO drivers include this line. I have seen no commits removing 
.owner from GPIO drivers in mainline or in current development tree.

baruch

-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -

^ permalink raw reply

* [PATCH 1/3] ARM: dts: rockchip: drop veyron's nonstandard 'backlight-boot-off'
From: Heiko Stuebner @ 2018-01-13 18:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180106004757.8239-1-briannorris@chromium.org>

Am Freitag, 5. Januar 2018, 16:47:55 CET schrieb Brian Norris:
> This was used out-of-tree as a hack for resolving issues where some
> systems expect the backlight to turn on automatically at boot, while
> others expect to manage the backlight status via a DRM/panel driver.
> Those issues have since been fixed upstream in pwm_bl.c without device
> tree hacks, and so this un-documented property should no longer be
> useful.
> 
> Signed-off-by: Brian Norris <briannorris@chromium.org>

applied (for 4.17 though)


Thanks
Heiko

^ permalink raw reply

* [PATCH v5] perf tools: Add ARM Statistical Profiling Extensions (SPE) support
From: Arnaldo Carvalho de Melo @ 2018-01-13 18:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180112192737.872407152ac251adccee3f61@arm.com>

Em Fri, Jan 12, 2018 at 07:27:37PM -0600, Kim Phillips escreveu:
> 'perf record' and 'perf report --dump-raw-trace' supported in this
> release.
> 
> Example usage:
> 
>  # perf record -e arm_spe/ts_enable=1,pa_enable=1/ dd if=/dev/zero of=/dev/null count=10000
>  # perf report --dump-raw-trace
> 
> Note that the perf.data file is portable, so the report can be run on
> another architecture host if necessary.

Failed for these distros:

  10    36.39 centos:6                      : FAIL gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
  37    35.28 oraclelinux:6                 : FAIL gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
  39    37.41 ubuntu:12.04.5                : FAIL gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

  CC       /tmp/build/perf/util/arm-spe-pkt-decoder.o
cc1: warnings being treated as errors
util/arm-spe-pkt-decoder.c: In function 'arm_spe_pkt_desc':
util/arm-spe-pkt-decoder.c:277: error: declaration of 'index' shadows a global declaration
/usr/include/string.h:489: error: shadowed declaration is here
mv: cannot stat `/tmp/build/perf/util/.arm-spe-pkt-decoder.o.tmp': No such file or directory
make[4]: *** [/tmp/build/perf/util/arm-spe-pkt-decoder.o] Error 1

Just rename 'index' to 'idx'

  14   110.68 debian:9                      : FAIL gcc (Debian 6.3.0-18) 6.3.0 20170516
  15   115.91 debian:experimental           : FAIL gcc (Debian 7.2.0-17) 7.2.1 20171205
  26   124.97 fedora:25                     : FAIL gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1)
  27   126.05 fedora:26                     : FAIL gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)
  28   126.40 fedora:27                     : FAIL gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)
  29   119.77 fedora:rawhide                : FAIL gcc (GCC) 7.2.1 20170829 (Red Hat 7.2.1-1)
  36   127.59 opensuse:tumbleweed           : FAIL gcc (SUSE Linux) 7.2.1 20171020 [gcc-7-branch revision 253932]
  43   106.21 ubuntu:16.04                  : FAIL gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609
  50   114.48 ubuntu:16.10                  : FAIL gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
  51   112.79 ubuntu:17.04                  : FAIL gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406
  52   115.37 ubuntu:17.10                  : FAIL gcc (Ubuntu 7.2.0-8ubuntu3) 7.2.0
  53   112.14 ubuntu:18.04                  : FAIL gcc (Ubuntu 7.2.0-16ubuntu1) 7.2.0
5

  LD       /tmp/build/perf/util/scripting-engines/libperf-in.o
  CC       /tmp/build/perf/util/intel-bts.o
  CC       /tmp/build/perf/util/arm-spe.o
util/arm-spe.c:165:19: error: unused function 'arm_spe_update_queues' [-Werror,-Wunused-function]
static inline int arm_spe_update_queues(struct arm_spe *spe)
                  ^
1 error generated.
mv: cannot stat '/tmp/build/perf/util/.arm-spe.o.tmp': No such file or directory
/git/linux/tools/build/Makefile.build:96: recipe for target '/tmp/build/perf/util/arm-spe.o' failed

^ permalink raw reply

* [PATCH v2] ARM: dts: rename oxnas dts files
From: Daniel Golle @ 2018-01-13 17:35 UTC (permalink / raw)
  To: linux-arm-kernel

Other platforms' device-tree files start with a platform prefix, such as
sun7i-a20-*.dts or at91-*.dts.
This naming scheme turns out to be handy when using multi-platform build
systems such as OpenWrt.
Prepend oxnas files with their platform prefix to comply with the naming
scheme already used for most other platforms.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: also apply changes in Makefile

 arch/arm/boot/dts/Makefile                                            | 4 ++--
 arch/arm/boot/dts/{wd-mbwe.dts => ox810se-wd-mbwe.dts}                | 0
 ...pogoplug-series-3.dts => ox820-cloudengines-pogoplug-series-3.dts} | 0
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename arch/arm/boot/dts/{wd-mbwe.dts => ox810se-wd-mbwe.dts} (100%)
 rename arch/arm/boot/dts/{cloudengines-pogoplug-series-3.dts => ox820-cloudengines-pogoplug-series-3.dts} (100%)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d0381e9caf21..6a014afa0ee5 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -711,8 +711,8 @@ dtb-$(CONFIG_ARCH_ACTIONS) += \
 dtb-$(CONFIG_ARCH_PRIMA2) += \
 	prima2-evb.dtb
 dtb-$(CONFIG_ARCH_OXNAS) += \
-	wd-mbwe.dtb \
-	cloudengines-pogoplug-series-3.dtb
+	ox810se-wd-mbwe.dtb \
+	ox820-cloudengines-pogoplug-series-3.dtb
 dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-apq8060-dragonboard.dtb \
 	qcom-apq8064-arrow-sd-600eval.dtb \
diff --git a/arch/arm/boot/dts/wd-mbwe.dts b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
similarity index 100%
rename from arch/arm/boot/dts/wd-mbwe.dts
rename to arch/arm/boot/dts/ox810se-wd-mbwe.dts
diff --git a/arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
similarity index 100%
rename from arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
rename to arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
-- 
2.15.1

^ permalink raw reply related

* [PATCH] ARM: dts: rename oxnas dts files
From: Daniel Golle @ 2018-01-13 17:32 UTC (permalink / raw)
  To: linux-arm-kernel

Other platforms' device-tree files start with a platform prefix, such as
sun7i-a20-*.dts or at91-*.dts.
This naming scheme turns out to be handy when using multi-platform build
systems such as OpenWrt.
Prepend oxnas files with their platform prefix to comply with the naming
scheme already used for most other platforms.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 arch/arm/boot/dts/{wd-mbwe.dts => ox810se-wd-mbwe.dts}                    | 0
 ...nes-pogoplug-series-3.dts => ox820-cloudengines-pogoplug-series-3.dts} | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename arch/arm/boot/dts/{wd-mbwe.dts => ox810se-wd-mbwe.dts} (100%)
 rename arch/arm/boot/dts/{cloudengines-pogoplug-series-3.dts => ox820-cloudengines-pogoplug-series-3.dts} (100%)

diff --git a/arch/arm/boot/dts/wd-mbwe.dts b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
similarity index 100%
rename from arch/arm/boot/dts/wd-mbwe.dts
rename to arch/arm/boot/dts/ox810se-wd-mbwe.dts
diff --git a/arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
similarity index 100%
rename from arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
rename to arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
-- 
2.15.1

^ permalink raw reply

* [PATCH v2 3/4] gpio: raspberrypi-exp: Driver for RPi3 GPIO expander via mailbox service
From: Peter Robinson @ 2018-01-13 14:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1313448378.43279.1515839595810@email.1und1.de>

On Sat, Jan 13, 2018 at 10:33 AM, Stefan Wahren <stefan.wahren@i2se.com> wrote:
> Hi Baruch,
>
>> Baruch Siach <baruch@tkos.co.il> hat am 11. Januar 2018 um 20:44 geschrieben:
>>
>>
>> From: Dave Stevenson <dave.stevenson@raspberrypi.org>
>>
>> Pi3 and Compute Module 3 have a GPIO expander that the
>> VPU communicates with.
>> There is a mailbox service that now allows control of this
>> expander, so add a kernel driver that can make use of it.
>>
>> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
>> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
>> ---
>> v2:
>>   * Rename driver to gpio-raspberrypi-exp
>>   * Populate the gpiochip parent device pointer
>>   * Use macro for the mailbox base GPIO number
>>   * Drop linux/gpio.h and GPIOF_DIR_*
>>   * Check and print firmware error value
>>   * Use devm_gpiochip_add_data(); drop .remove
>>   * A few more minor tweaks
>> ---
>>  drivers/gpio/Kconfig                |   9 ++
>>  drivers/gpio/Makefile               |   1 +
>>  drivers/gpio/gpio-raspberrypi-exp.c | 258 ++++++++++++++++++++++++++++++++++++
>>  3 files changed, 268 insertions(+)
>>  create mode 100644 drivers/gpio/gpio-raspberrypi-exp.c
>>
>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
>> index d6a8e851ad13..8df901c75bef 100644
>> --- a/drivers/gpio/Kconfig
>> +++ b/drivers/gpio/Kconfig
>> @@ -128,6 +128,15 @@ config GPIO_AXP209
>>       help
>>         Say yes to enable GPIO support for the AXP209 PMIC
>>
>> +config GPIO_RASPBERRYPI_EXP
>> +     bool "RaspberryPi 3 Exp GPIO"
>
> How about "RaspberryPi 3 GPIO Expander" ?
>
> Why not tristate? On arm64 it's preferred to have a kernel module.

And on all generic distros, like Fedora, that cater for generic
kernels with support for 100s of devices where most things are modular
to keep the kernel as small as possible.

>> +     default RASPBERRYPI_FIRMWARE
>> +     depends on OF_GPIO && RASPBERRYPI_FIRMWARE && \
>> +             (ARCH_BCM2835 || COMPILE_TEST)
>
> Since this is default on RASPBERRYPI_FIRMWARE, we could remove it from the dependencies.
>
>> +     help
>> +       Turn on GPIO support for the expander on Raspberry Pi 3 boards, using
>> +       the firmware mailbox to communicate with VideoCore on BCM283x chips.
>> +
>>  config GPIO_BCM_KONA
>>       bool "Broadcom Kona GPIO"
>>       depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
>> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
>> index 4bc24febb889..71021b0e71da 100644
>> --- a/drivers/gpio/Makefile
>> +++ b/drivers/gpio/Makefile
>> @@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_ARIZONA)  += gpio-arizona.o
>>  obj-$(CONFIG_GPIO_ATH79)     += gpio-ath79.o
>>  obj-$(CONFIG_GPIO_ASPEED)    += gpio-aspeed.o
>>  obj-$(CONFIG_GPIO_AXP209)    += gpio-axp209.o
>> +obj-$(CONFIG_GPIO_RASPBERRYPI_EXP)   += gpio-raspberrypi-exp.o
>>  obj-$(CONFIG_GPIO_BCM_KONA)  += gpio-bcm-kona.o
>>  obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o
>>  obj-$(CONFIG_GPIO_BRCMSTB)   += gpio-brcmstb.o
>> diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
>> new file mode 100644
>> index 000000000000..95b1957a69fa
>> --- /dev/null
>> +++ b/drivers/gpio/gpio-raspberrypi-exp.c
>> @@ -0,0 +1,258 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + *  Raspberry Pi 3 expander GPIO driver
>> + *
>> + *  Uses the firmware mailbox service to communicate with the
>> + *  GPIO expander on the VPU.
>> + *
>> + *  Copyright (C) 2017 Raspberry Pi Trading Ltd.
>
> 2018?
>
>> + */
>> +
>> +#include <linux/err.h>
>> +#include <linux/gpio/driver.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/dma-mapping.h>
>
> I can't see any DMA handling, so please remove it.
>
>> +#include <soc/bcm2835/raspberrypi-firmware.h>
>> +
>> +#define MODULE_NAME "raspberrypi-exp-gpio"
>> +#define NUM_GPIO 8
>> +
>> +#define RPI_EXP_GPIO_BASE    128
>> +
>> +#define RPI_EXP_GPIO_DIR_IN  0
>> +#define RPI_EXP_GPIO_DIR_OUT 1
>> +
>> +struct rpi_exp_gpio {
>> +     struct gpio_chip gc;
>> +     struct rpi_firmware *fw;
>> +};
>> +
>> +/* VC4 firmware mailbox interface data structures */
>> +
>> +struct gpio_set_config {
>> +     u32 gpio;
>> +     u32 direction;
>> +     u32 polarity;
>> +     u32 term_en;
>> +     u32 term_pull_up;
>> +     u32 state;
>> +};
>> +
>> +struct gpio_get_config {
>> +     u32 gpio;
>> +     u32 direction;
>> +     u32 polarity;
>> +     u32 term_en;
>> +     u32 term_pull_up;
>> +};
>> +
>> +struct gpio_get_set_state {
>> +     u32 gpio;
>> +     u32 state;
>> +};
>> +
>> +static int rpi_exp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
>> +{
>> +     struct rpi_exp_gpio *gpio;
>> +     struct gpio_get_config get;
>> +     int ret;
>> +
>> +     gpio = gpiochip_get_data(gc);
>> +
>> +     get.gpio = off + RPI_EXP_GPIO_BASE;     /* GPIO to update */
>> +
>> +     ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
>> +                                 &get, sizeof(get));
>> +     if (ret || get.gpio != 0) {
>> +             dev_err(gc->parent,
>> +                     "Failed to get GPIO %u config (%d %x)\n", off, ret,
>> +                     get.gpio);
>
> Can't we change this to fit in 2 lines?
>
>> +             return ret ? ret : -EIO;
>> +     }
>> +     return get.polarity;
>> +}
>> +
>> +static int rpi_exp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
>> +{
>> +     struct rpi_exp_gpio *gpio;
>> +     struct gpio_set_config set_in;
>> +     int ret;
>> +
>> +     gpio = gpiochip_get_data(gc);
>> +
>> +     set_in.gpio = off + RPI_EXP_GPIO_BASE;  /* GPIO to update */
>> +     set_in.direction = RPI_EXP_GPIO_DIR_IN;
>> +     set_in.polarity = rpi_exp_gpio_get_polarity(gc, off);
>
> This could fail, so please check the return code.
>
>> +                                     /* Retain existing setting */
>> +     set_in.term_en = 0;             /* termination disabled */
>> +     set_in.term_pull_up = 0;        /* n/a as termination disabled */
>> +     set_in.state = 0;               /* n/a as configured as an input */
>> +
>> +     ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
>> +                                 &set_in, sizeof(set_in));
>> +     if (ret || set_in.gpio != 0) {
>> +             dev_err(gc->parent,
>> +                     "Failed to set GPIO %u to input (%d %x)\n",
>> +                     off, ret, set_in.gpio);
>
> see above
>
>> +             return ret ? ret : -EIO;
>> +     }
>> +     return 0;
>> +}
>> +
>> +static int rpi_exp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
>> +{
>> +     struct rpi_exp_gpio *gpio;
>> +     struct gpio_set_config set_out;
>> +     int ret;
>> +
>> +     gpio = gpiochip_get_data(gc);
>> +
>> +     set_out.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
>> +     set_out.direction = RPI_EXP_GPIO_DIR_OUT;
>> +     set_out.polarity = rpi_exp_gpio_get_polarity(gc, off);
>
> This could also fail.
>
>> +                                     /* Retain existing setting */
>> +     set_out.term_en = 0;            /* n/a as an output */
>> +     set_out.term_pull_up = 0;       /* n/a as termination disabled */
>> +     set_out.state = val;            /* Output state */
>> +
>> +     ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
>> +                                 &set_out, sizeof(set_out));
>> +     if (ret || set_out.gpio != 0) {
>> +             dev_err(gc->parent,
>> +                     "Failed to set GPIO %u to output (%d %x)\n", off, ret,
>> +                     set_out.gpio);
>> +             return ret ? ret : -EIO;
>> +     }
>> +     return 0;
>> +}
>> +
>> +static int rpi_exp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
>> +{
>> +     struct rpi_exp_gpio *gpio;
>> +     struct gpio_get_config get;
>> +     int ret;
>> +
>> +     gpio = gpiochip_get_data(gc);
>> +
>> +     get.gpio = off + RPI_EXP_GPIO_BASE;     /* GPIO to update */
>> +
>> +     ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
>> +                                 &get, sizeof(get));
>> +     if (ret || get.gpio != 0) {
>> +             dev_err(gc->parent,
>> +                     "Failed to get GPIO %u config (%d %x)\n", off, ret,
>> +                     get.gpio);
>> +             return ret ? ret : -EIO;
>> +     }
>> +     return !get.direction;
>> +}
>> +
>> +static int rpi_exp_gpio_get(struct gpio_chip *gc, unsigned int off)
>> +{
>> +     struct rpi_exp_gpio *gpio;
>> +     struct gpio_get_set_state get;
>> +     int ret;
>> +
>> +     gpio = gpiochip_get_data(gc);
>> +
>> +     get.gpio = off + RPI_EXP_GPIO_BASE;     /* GPIO to update */
>> +     get.state = 0;          /* storage for returned value */
>> +
>> +     ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
>> +                                      &get, sizeof(get));
>> +     if (ret || get.gpio != 0) {
>> +             dev_err(gc->parent,
>> +                     "Failed to get GPIO %u state (%d %x)\n", off, ret,
>> +                     get.gpio);
>> +             return ret ? ret : -EIO;
>> +     }
>> +     return !!get.state;
>> +}
>> +
>> +static void rpi_exp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
>> +{
>> +     struct rpi_exp_gpio *gpio;
>> +     struct gpio_get_set_state set;
>> +     int ret;
>> +
>> +     gpio = gpiochip_get_data(gc);
>> +
>> +     set.gpio = off + RPI_EXP_GPIO_BASE;     /* GPIO to update */
>> +     set.state = val;        /* Output state */
>> +
>> +     ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
>> +                                      &set, sizeof(set));
>> +     if (ret || set.gpio != 0)
>> +             dev_err(gc->parent,
>> +                     "Failed to set GPIO %u state (%d %x)\n", off, ret,
>> +                     set.gpio);
>> +}
>> +
>> +static int rpi_exp_gpio_probe(struct platform_device *pdev)
>> +{
>> +     int err = 0;
>> +     struct device *dev = &pdev->dev;
>> +     struct device_node *np = dev->of_node;
>> +     struct device_node *fw_node;
>> +     struct rpi_firmware *fw;
>> +     struct rpi_exp_gpio *rpi_gpio;
>> +
>> +     fw_node = of_parse_phandle(np, "firmware", 0);
>> +     if (!fw_node) {
>> +             dev_err(dev, "Missing firmware node\n");
>> +             return -ENOENT;
>> +     }
>> +
>> +     fw = rpi_firmware_get(fw_node);
>> +     if (!fw)
>> +             return -EPROBE_DEFER;
>> +
>> +     rpi_gpio = devm_kzalloc(dev, sizeof(*rpi_gpio), GFP_KERNEL);
>> +     if (!rpi_gpio)
>> +             return -ENOMEM;
>> +
>> +     rpi_gpio->fw = fw;
>> +     rpi_gpio->gc.parent = dev;
>> +     rpi_gpio->gc.label = MODULE_NAME;
>> +     rpi_gpio->gc.owner = THIS_MODULE;
>> +     rpi_gpio->gc.of_node = np;
>> +     rpi_gpio->gc.base = -1;
>> +     rpi_gpio->gc.ngpio = NUM_GPIO;
>> +
>> +     rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in;
>> +     rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out;
>> +     rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction;
>> +     rpi_gpio->gc.get = rpi_exp_gpio_get;
>> +     rpi_gpio->gc.set = rpi_exp_gpio_set;
>> +     rpi_gpio->gc.can_sleep = true;
>> +
>> +     err = devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
>> +     if (err)
>> +             return err;
>> +
>> +     platform_set_drvdata(pdev, rpi_gpio);
>
> Since we use devm_gpiochip_add_data, we can drop this.
>
>> +
>> +     return 0;
>> +}
>> +
>> +static const struct of_device_id rpi_exp_gpio_ids[] = {
>> +     { .compatible = "raspberrypi,firmware-gpio" },
>> +     { }
>> +};
>> +MODULE_DEVICE_TABLE(of, rpi_exp_gpio_ids);
>> +
>> +static struct platform_driver rpi_exp_gpio_driver = {
>> +     .driver = {
>> +             .name           = MODULE_NAME,
>> +             .owner          = THIS_MODULE,
>
> Please drop this, too.
>
> Thanks
> Stefan
>
> _______________________________________________
> linux-rpi-kernel mailing list
> linux-rpi-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rpi-kernel

^ permalink raw reply

* Headless chicken mode over recent exploits
From: Russell King - ARM Linux @ 2018-01-13 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

I would like to bring to people's attention that there seems to be a
lot of "headless chicken mode" going on with the current set of issues.
I guess vendors have to be seen to be doing _something_ even if what
they're doing has no technical reasoning what so ever.

I've recently had the following pointed out to me:

  "To provide additional protection, the update for CVE-2017-13218
   included in this bulletin reduces access to high-precision timers,
   which helps limits side channel attacks (such as CVE-2017-5715,
   CVE-2017-5753, and CVE-2017-5754) of all known variants of ARM
   processors."

CVE-2017-13218 reads:

  "Access to CNTVCT_EL0 could be used for side channel attacks. This
   could lead to local information disclosure with no additional
   execution privileges needed. User interaction is not needed for
   exploitation.
   Product: Android. Versions: Android kernel. Android ID: A-68266545."

I'm worried about this.

If the processor that you're trying to exploit is SMP, then this kind
of mitigation does nothing to mitigate the attack - all you then need is
to spawn a separate thread that spends all its time incrementing a local
variable.  You then have something that is almost a cycle counter.

I have a working implementation of this exact kind of time source which
several people have over the last week independently verified allows
programs such as "spectre.c" to still read the "The Magic Words are
Squeamish Ossifrage." string, thereby proving that the side-channel
remains very much usable with no help from any hardware timer.

However, the same is still possible with two processes with a shared
mapping, so the need for multiple threads is not necessary - just two
or more CPUs.

So my conclusion is the above CVE is basically misleading - it does
nothing to mitigate against these attacks, and I worry that it will
lead people to conclude (incorrectly) that disabling access to the
ARM architected timer is sufficient to stop the attacks.  It isn't,
and so its pointless to do so.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* [PATCH v2 7/8] arm64: allow ID map to be extended to 52 bits
From: Marc Zyngier @ 2018-01-13 12:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <46563f7c-2a7e-14e8-8614-cf74414dca7e@arm.com>

On Fri, 12 Jan 2018 11:48:49 +0000,
Kristina Martsenko wrote:
> 
> On 09/01/18 19:29, Kristina Martsenko wrote:
> > On 22/12/17 15:23, Catalin Marinas wrote:
> >> From: Kristina Martsenko <kristina.martsenko@arm.com>
> >>
> >> Currently, when using VA_BITS < 48, if the ID map text happens to be
> >> placed in physical memory above VA_BITS, we increase the VA size (up to
> >> 48) and create a new table level, in order to map in the ID map text.
> >> This is okay because the system always supports 48 bits of VA.
> >>
> >> This patch extends the code such that if the system supports 52 bits of
> >> VA, and the ID map text is placed that high up, then we increase the VA
> >> size accordingly, up to 52.
> >>
> >> One difference from the current implementation is that so far the
> >> condition of VA_BITS < 48 has meant that the top level table is always
> >> "full", with the maximum number of entries, and an extra table level is
> >> always needed. Now, when VA_BITS = 48 (and using 64k pages), the top
> >> level table is not full, and we simply need to increase the number of
> >> entries in it, instead of creating a new table level.
> >>
> >> Tested-by: Bob Picco <bob.picco@oracle.com>
> >> Reviewed-by: Bob Picco <bob.picco@oracle.com>
> >> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> >> [catalin.marinas at arm.com: reduce arguments to __create_hyp_mappings()]
> >> [catalin.marinas at arm.com: reworked/renamed __cpu_uses_extended_idmap_level()]
> >> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> >> ---
> >>  arch/arm/include/asm/kvm_mmu.h       |  5 +++
> >>  arch/arm64/include/asm/assembler.h   |  2 -
> >>  arch/arm64/include/asm/kvm_mmu.h     |  7 +++-
> >>  arch/arm64/include/asm/mmu_context.h | 18 +++++++--
> >>  arch/arm64/kernel/head.S             | 76 +++++++++++++++++++++---------------
> >>  arch/arm64/kvm/hyp-init.S            | 17 ++++----
> >>  arch/arm64/mm/mmu.c                  |  1 +
> >>  virt/kvm/arm/mmu.c                   | 10 ++++-
> >>  8 files changed, 87 insertions(+), 49 deletions(-)
> >>
> >> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
> >> index 8dbec683638b..8c5643e2eea4 100644
> >> --- a/arch/arm/include/asm/kvm_mmu.h
> >> +++ b/arch/arm/include/asm/kvm_mmu.h
> >> @@ -211,6 +211,11 @@ static inline bool __kvm_cpu_uses_extended_idmap(void)
> >>  	return false;
> >>  }
> >>  
> >> +static inline unsigned long __kvm_idmap_ptrs_per_pgd(void)
> >> +{
> >> +	return PTRS_PER_PGD;
> >> +}
> >> +
> >>  static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
> >>  				       pgd_t *hyp_pgd,
> >>  				       pgd_t *merged_hyp_pgd,
> >> diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
> >> index 49ea3def4bd1..942fdb5ef0ad 100644
> >> --- a/arch/arm64/include/asm/assembler.h
> >> +++ b/arch/arm64/include/asm/assembler.h
> >> @@ -344,10 +344,8 @@ alternative_endif
> >>   * tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map
> >>   */
> >>  	.macro	tcr_set_idmap_t0sz, valreg, tmpreg
> >> -#ifndef CONFIG_ARM64_VA_BITS_48
> >>  	ldr_l	\tmpreg, idmap_t0sz
> >>  	bfi	\valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
> >> -#endif
> >>  	.endm
> >>  
> >>  /*
> >> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> >> index b3f7b68b042d..8d663ca0d50c 100644
> >> --- a/arch/arm64/include/asm/kvm_mmu.h
> >> +++ b/arch/arm64/include/asm/kvm_mmu.h
> >> @@ -273,7 +273,12 @@ void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
> >>  
> >>  static inline bool __kvm_cpu_uses_extended_idmap(void)
> >>  {
> >> -	return __cpu_uses_extended_idmap();
> >> +	return __cpu_uses_extended_idmap_table();
> >> +}
> >> +
> >> +static inline unsigned long __kvm_idmap_ptrs_per_pgd(void)
> >> +{
> >> +	return idmap_ptrs_per_pgd;
> >>  }
> >>  
> >>  /*
> >> diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
> >> index accc2ff32a0e..7991718890c6 100644
> >> --- a/arch/arm64/include/asm/mmu_context.h
> >> +++ b/arch/arm64/include/asm/mmu_context.h
> >> @@ -63,11 +63,21 @@ static inline void cpu_set_reserved_ttbr0(void)
> >>   * physical memory, in which case it will be smaller.
> >>   */
> >>  extern u64 idmap_t0sz;
> >> +extern u64 idmap_ptrs_per_pgd;
> >>  
> >> -static inline bool __cpu_uses_extended_idmap(void)
> >> +static inline bool __cpu_uses_extended_idmap_level(void)
> >>  {
> >> -	return (!IS_ENABLED(CONFIG_ARM64_VA_BITS_48) &&
> >> -		unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)));
> >> +	return ARM64_HW_PGTABLE_LEVELS((64 - idmap_t0sz)) > CONFIG_PGTABLE_LEVELS;
> >> +}
> >> +
> >> +/*
> >> + * True if the extended ID map requires an extra level of translation table
> >> + * to be configured.
> >> + */
> >> +static inline bool __cpu_uses_extended_idmap_table(void)
> >> +{
> >> +	return __cpu_uses_extended_idmap_level() &&
> >> +		(idmap_ptrs_per_pgd == PTRS_PER_PGD);
> >>  }
> >>  
> >>  /*
> >> @@ -77,7 +87,7 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
> >>  {
> >>  	unsigned long tcr;
> >>  
> >> -	if (!__cpu_uses_extended_idmap())
> >> +	if (!__cpu_uses_extended_idmap_level())
> >>  		return;
> >>  
> >>  	tcr = read_sysreg(tcr_el1);
> >> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> >> index eeec0001e204..66f01869e97c 100644
> >> --- a/arch/arm64/kernel/head.S
> >> +++ b/arch/arm64/kernel/head.S
> >> @@ -176,7 +176,7 @@ ENDPROC(preserve_boot_args)
> >>   *	ptrs:	#imm pointers per table page
> >>   *
> >>   * Preserves:	virt
> >> - * Corrupts:	tmp1, tmp2
> >> + * Corrupts:	ptrs, tmp1, tmp2
> >>   * Returns:	tbl -> next level table page address
> >>   */
> >>  	.macro	create_table_entry, tbl, virt, shift, ptrs, tmp1, tmp2
> >> @@ -184,7 +184,8 @@ ENDPROC(preserve_boot_args)
> >>  	phys_to_pte \tmp1, \tmp2
> >>  	orr	\tmp2, \tmp2, #PMD_TYPE_TABLE	// address of next table and entry type
> >>  	lsr	\tmp1, \virt, #\shift
> >> -	and	\tmp1, \tmp1, #\ptrs - 1	// table index
> >> +	sub	\ptrs, \ptrs, #1
> >> +	and	\tmp1, \tmp1, \ptrs		// table index
> >>  	str	\tmp2, [\tbl, \tmp1, lsl #3]
> >>  	add	\tbl, \tbl, #PAGE_SIZE		// next level table page
> >>  	.endm
> >> @@ -194,15 +195,17 @@ ENDPROC(preserve_boot_args)
> >>   * block entry in the next level (tbl) for the given virtual address.
> >>   *
> >>   * Preserves:	tbl, next, virt
> >> - * Corrupts:	tmp1, tmp2
> >> + * Corrupts:	ptrs_per_pgd, tmp1, tmp2
> >>   */
> >> -	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
> >> -	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
> >> +	.macro	create_pgd_entry, tbl, virt, ptrs_per_pgd, tmp1, tmp2
> >> +	create_table_entry \tbl, \virt, PGDIR_SHIFT, \ptrs_per_pgd, \tmp1, \tmp2
> >>  #if SWAPPER_PGTABLE_LEVELS > 3
> >> -	create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2
> >> +	mov	\ptrs_per_pgd, PTRS_PER_PUD
> >> +	create_table_entry \tbl, \virt, PUD_SHIFT, \ptrs_per_pgd, \tmp1, \tmp2
> >>  #endif
> >>  #if SWAPPER_PGTABLE_LEVELS > 2
> >> -	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
> >> +	mov	\ptrs_per_pgd, PTRS_PER_PTE
> >> +	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, \ptrs_per_pgd, \tmp1, \tmp2
> >>  #endif
> >>  	.endm
> >>  
> >> @@ -266,26 +269,13 @@ __create_page_tables:
> >>  	adrp	x0, idmap_pg_dir
> >>  	adrp	x3, __idmap_text_start		// __pa(__idmap_text_start)
> >>  
> >> -#ifndef CONFIG_ARM64_VA_BITS_48
> >> -#define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
> >> -#define EXTRA_PTRS	(1 << (48 - EXTRA_SHIFT))
> >> -
> >> -	/*
> >> -	 * If VA_BITS < 48, it may be too small to allow for an ID mapping to be
> >> -	 * created that covers system RAM if that is located sufficiently high
> >> -	 * in the physical address space. So for the ID map, use an extended
> >> -	 * virtual range in that case, by configuring an additional translation
> >> -	 * level.
> >> -	 * First, we have to verify our assumption that the current value of
> >> -	 * VA_BITS was chosen such that all translation levels are fully
> >> -	 * utilised, and that lowering T0SZ will always result in an additional
> >> -	 * translation level to be configured.
> >> -	 */
> >> -#if VA_BITS != EXTRA_SHIFT
> >> -#error "Mismatch between VA_BITS and page size/number of translation levels"
> >> -#endif
> >> -
> >>  	/*
> >> +	 * VA_BITS may be too small to allow for an ID mapping to be created
> >> +	 * that covers system RAM if that is located sufficiently high in the
> >> +	 * physical address space. So for the ID map, use an extended virtual
> >> +	 * range in that case, and configure an additional translation level
> >> +	 * if needed.
> >> +	 *
> >>  	 * Calculate the maximum allowed value for TCR_EL1.T0SZ so that the
> >>  	 * entire ID map region can be mapped. As T0SZ == (64 - #bits used),
> >>  	 * this number conveniently equals the number of leading zeroes in
> >> @@ -294,18 +284,41 @@ __create_page_tables:
> >>  	adrp	x5, __idmap_text_end
> >>  	clz	x5, x5
> >>  	cmp	x5, TCR_T0SZ(VA_BITS)	// default T0SZ small enough?
> >> -	b.ge	1f			// .. then skip additional level
> >> +	b.ge	1f			// .. then skip VA range extension
> >>  
> >>  	adr_l	x6, idmap_t0sz
> >>  	str	x5, [x6]
> >>  	dmb	sy
> >>  	dc	ivac, x6		// Invalidate potentially stale cache line
> >>  
> >> -	create_table_entry x0, x3, EXTRA_SHIFT, EXTRA_PTRS, x5, x6
> >> -1:
> >> +#if (VA_BITS < 48)
> >> +#define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
> >> +#define EXTRA_PTRS	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))
> >> +
> >> +	/*
> >> +	 * If VA_BITS < 48, we have to configure an additional table level.
> >> +	 * First, we have to verify our assumption that the current value of
> >> +	 * VA_BITS was chosen such that all translation levels are fully
> >> +	 * utilised, and that lowering T0SZ will always result in an additional
> >> +	 * translation level to be configured.
> >> +	 */
> >> +#if VA_BITS != EXTRA_SHIFT
> >> +#error "Mismatch between VA_BITS and page size/number of translation levels"
> >>  #endif
> >>  
> >> -	create_pgd_entry x0, x3, x5, x6
> >> +	mov	x4, EXTRA_PTRS
> >> +	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
> >> +#else
> >> +	/*
> >> +	 * If VA_BITS == 48, we don't have to configure an additional
> >> +	 * translation level, but the top-level table has more entries.
> >> +	 */
> >> +	mov	x4, #1 << (PHYS_MASK_SHIFT - PGDIR_SHIFT)
> >> +	str_l	x4, idmap_ptrs_per_pgd, x5
> >> +#endif
> >> +1:
> >> +	ldr_l	x4, idmap_ptrs_per_pgd
> >> +	create_pgd_entry x0, x3, x4, x5, x6
> >>  	mov	x5, x3				// __pa(__idmap_text_start)
> >>  	adr_l	x6, __idmap_text_end		// __pa(__idmap_text_end)
> >>  	create_block_map x0, x7, x3, x5, x6, x4
> >> @@ -316,7 +329,8 @@ __create_page_tables:
> >>  	adrp	x0, swapper_pg_dir
> >>  	mov_q	x5, KIMAGE_VADDR + TEXT_OFFSET	// compile time __va(_text)
> >>  	add	x5, x5, x23			// add KASLR displacement
> >> -	create_pgd_entry x0, x5, x3, x6
> >> +	mov	x4, PTRS_PER_PGD
> >> +	create_pgd_entry x0, x5, x4, x3, x6
> >>  	adrp	x6, _end			// runtime __pa(_end)
> >>  	adrp	x3, _text			// runtime __pa(_text)
> >>  	sub	x6, x6, x3			// _end - _text
> >> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
> >> index f9681cc00973..33c40b3eea01 100644
> >> --- a/arch/arm64/kvm/hyp-init.S
> >> +++ b/arch/arm64/kvm/hyp-init.S
> >> @@ -72,24 +72,23 @@ __do_hyp_init:
> >>  	mov	x5, #TCR_EL2_RES1
> >>  	orr	x4, x4, x5
> >>  
> >> -#ifndef CONFIG_ARM64_VA_BITS_48
> >>  	/*
> >> -	 * If we are running with VA_BITS < 48, we may be running with an extra
> >> -	 * level of translation in the ID map. This is only the case if system
> >> -	 * RAM is out of range for the currently configured page size and number
> >> -	 * of translation levels, in which case we will also need the extra
> >> -	 * level for the HYP ID map, or we won't be able to enable the EL2 MMU.
> >> +	 * The ID map may be configured to use an extended virtual address
> >> +	 * range. This is only the case if system RAM is out of range for the
> >> +	 * currently configured page size and VA_BITS, in which case we will
> >> +	 * also need the extended virtual range for the HYP ID map, or we won't
> >> +	 * be able to enable the EL2 MMU.
> >>  	 *
> >>  	 * However, at EL2, there is only one TTBR register, and we can't switch
> >>  	 * between translation tables *and* update TCR_EL2.T0SZ at the same
> >> -	 * time. Bottom line: we need the extra level in *both* our translation
> >> -	 * tables.
> >> +	 * time. Bottom line: we need to use the extended range with *both* our
> >> +	 * translation tables.
> >>  	 *
> >>  	 * So use the same T0SZ value we use for the ID map.
> >>  	 */
> >>  	ldr_l	x5, idmap_t0sz
> >>  	bfi	x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
> >> -#endif
> >> +
> >>  	/*
> >>  	 * Set the PS bits in TCR_EL2.
> >>  	 */
> >> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> >> index 0c631a17ae1d..baa34418c3bf 100644
> >> --- a/arch/arm64/mm/mmu.c
> >> +++ b/arch/arm64/mm/mmu.c
> >> @@ -50,6 +50,7 @@
> >>  #define NO_CONT_MAPPINGS	BIT(1)
> >>  
> >>  u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
> >> +u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
> >>  
> >>  u64 kimage_voffset __ro_after_init;
> >>  EXPORT_SYMBOL(kimage_voffset);
> >> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> >> index b36945d49986..761787befd3b 100644
> >> --- a/virt/kvm/arm/mmu.c
> >> +++ b/virt/kvm/arm/mmu.c
> >> @@ -629,14 +629,20 @@ static int __create_hyp_mappings(pgd_t *pgdp,
> >>  {
> >>  	pgd_t *pgd;
> >>  	pud_t *pud;
> >> -	unsigned long addr, next;
> >> +	unsigned long addr, next, ptrs_per_pgd = PTRS_PER_PGD;
> >>  	int err = 0;
> >>  
> >> +	/*
> >> +	 * If it's not the hyp_pgd, fall back to the kvm idmap layout.
> >> +	 */
> >> +	if (pgdp != hyp_pgd)
> >> +		ptrs_per_pgd = __kvm_idmap_ptrs_per_pgd();
> > 
> > This isn't right. When VA_BITS = 48 and the idmap is in 52-bit memory,
> > we come here with hyp_pgd, but need to use __kvm_idmap_ptrs_per_pgd. (We
> > don't have an extra table level, so we take the "else" case in
> > kvm_mmu_init. But we have a larger number of entries in the top-level
> > table, so we need __kvm_idmap_ptrs_per_pgd to mask in the extra bits.)
> > 
> > Currently a kernel with the above configuration (and VHE disabled) fails
> > to boot.
> > 
> > I'm not sure how else to push the changes into __create_hyp_mappings, as
> > Marc originally requested. One option might be to get rid of the mask
> > entirely, since the top bits of all hyp addresses should be zero anyway:
> >   pgd = pgdp + (addr >> PGDIR_SHIFT);
> 
> I was wrong, this solution does not work for the case where we create an
> extra table level, because the index will incorrectly include the bits
> "above" the pgd level. Sorry about that.
> 
> I don't have any other ideas. Should I put it back as it was in v1, with
> the callers passing in the mask for the table index?

Probably. At this stage, we need to fix things, so let's go back to
what you had, and we'll see if we can do something better in the long
run.

Thanks for having investigated that, and sorry for having broken it.

Thanks,

	M.

^ permalink raw reply

* [PATCH v3] arm64: cpu_errata: Add Kryo to Falkor 1003 errata
From: Catalin Marinas @ 2018-01-13 12:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180109212212.GD21040@codeaurora.org>

On Tue, Jan 09, 2018 at 01:22:12PM -0800, Stephen Boyd wrote:
> On 12/14, Will Deacon wrote:
> > On Wed, Dec 13, 2017 at 02:19:37PM -0800, Stephen Boyd wrote:
> > > The Kryo CPUs are also affected by the Falkor 1003 errata, so
> > > we need to do the same workaround on Kryo CPUs. The MIDR is
> > > slightly more complicated here, where the PART number is not
> > > always the same when looking at all the bits from 15 to 4. Drop
> > > the lower 8 bits and just look at the top 4 to see if it's '2'
> > > and then consider those as Kryo CPUs. This covers all the
> > > combinations without having to list them all out.
> > > 
> > > Fixes: 38fd94b0275c ("arm64: Work around Falkor erratum 1003")
> > > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > > ---
> > 
> > Acked-by: Will Deacon <will.deacon@arm.com>
> > 
> > Thanks for respinning this. Catalin -- can you take this for 4.16, please?
> 
> Can this get picked up? I don't see it in linux-next yet.

I picked it up now but I'll push it tomorrow or Monday (still running
some tests on the unpushed patches).

-- 
Catalin

^ permalink raw reply

* [PATCH v6 11/16] firmware: arm_sdei: Add support for CPU and system power states
From: Catalin Marinas @ 2018-01-13 12:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180108172226.GC2530@red-moon>

On Mon, Jan 08, 2018 at 05:22:26PM +0000, Lorenzo Pieralisi wrote:
> On Mon, Jan 08, 2018 at 03:38:13PM +0000, James Morse wrote:
> 
> [...]
> 
> > +/* When entering idle, mask/unmask events for this cpu */
> 
> Just mentioning (since I know you know), this notifier is called also
> through syscore_ops so it is not just idle (CPUidle or Suspend-to-idle).
> 
> > +static int sdei_pm_notifier(struct notifier_block *nb, unsigned long action,
> > +			    void *data)
> > +{
> > +	int rv;
> > +
> > +	switch (action) {
> > +	case CPU_PM_ENTER:
> > +		rv = sdei_mask_local_cpu();
> > +		break;
> > +	case CPU_PM_EXIT:
> > +		rv = sdei_unmask_local_cpu();
> 
> You should handle CPU_PM_ENTER_FAILED here for correctness,
> in case the notifier chain fails.

So, just to confirm, the CPU_PM_ENTER_FAILED case goes together with
CPU_PM_EXIT so that we unmask the SDE again for the CPU.

-- 
Catalin

^ permalink raw reply

* [PATCH V4 0/3] Map larger kernels at early init
From: Catalin Marinas @ 2018-01-13 11:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180111101159.9748-1-steve.capper@arm.com>

On Thu, Jan 11, 2018 at 10:11:56AM +0000, Steve Capper wrote:
> Steve Capper (3):
>   arm64: Re-order reserved_ttbr0 in linker script
>   arm64: entry: Move the trampoline to be before PAN
>   arm64: Extend early page table code to allow for larger kernels

I queued the patches for 4.16. I'll push them out once my tests
complete.

Thanks.

-- 
Catalin

^ permalink raw reply

* EDAC driver for ARMv8 L1/L2 cache
From: Borislav Petkov @ 2018-01-13 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <VI1PR04MB2078FCB86150A2AABFE7AB439A170@VI1PR04MB2078.eurprd04.prod.outlook.com>

Btw,

I jus received a driver for this:

https://lkml.kernel.org/r/1515804626-21254-1-git-send-email-kyan at codeaurora.org

and I think you guys should first talk and do one version which works
for all.

Adding Kyle to CC.

@Kyle: there's also a driver here: https://patchwork.kernel.org/patch/7513231

Also, looking at it, you probably should call it arm64_edac or so, to
be clear what it is. armv8 - although known to ARM people - makes me go
look at wikipedia to refresh what v8 was again.

Also, I'd like you to figure out who's going to be maintaining it so
that get_maintainer.pl can find you on bug reports.

Thx.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply

* bcm2835: device tree regression in 4.15.0-rc7
From: Stefan Wahren @ 2018-01-13 10:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <6809C455-9989-409C-9AB8-DDA8FDD04EB3@martin.sperl.org>

Hi Martin,

> kernel at martin.sperl.org hat am 13. Januar 2018 um 11:05 geschrieben:
> 
> 
> Hi!
> ...
> 
> and network does not
> come up so ssh access is not possible?
> DHCP-Networking does not come up either!
> 
> After reapplying the patch for CM3-dt and rebuilding it boots fine.
> 
> As far as I understand older, formerly functional DTs should always continue to work.

please apply "drm/vc4: Move IRQ enable to PM path" to get the rid off this warning and
"phy: work around 'phys' references to usb-nop-xceiv devices" to fix dwc2.

Stefan


> 
> Martin
>

^ permalink raw reply

* [PATCH v2 4/4] ARM: dts: bcm2837-rpi-3-b: add GPIO expander
From: Stefan Wahren @ 2018-01-13 10:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1cb81e3d7a1b1f7ccf374952fa7e8d2147c186fb.1515698418.git.baruch@tkos.co.il>

Hi Baruch,

> Baruch Siach <baruch@tkos.co.il> hat am 11. Januar 2018 um 20:44 geschrieben:
> 
> 
> Add a description of the RPi3 GPIO expander that the VC4 firmware controls.
> 
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
> v2:
>   * Move GPIO expander node out of the soc container
>   * Rename compatible string
>   * Add gpio-line-names property
> ---
>  arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> index b44b3b5af00d..24555e8a43ec 100644
> --- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> @@ -23,6 +23,16 @@
>  			gpios = <&gpio 47 0>;
>  		};
>  	};
> +
> +	expgpio: gpio-expander {
> +		compatible = "raspberrypi,firmware-gpio";
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		firmware = <&firmware>;
> +		gpio-line-names = "BT_ON", "WL_ON", "STATUS_LED", "LAN_RUN",
> +			"HPD_N", "CAM_GPIO0", "CAM_GPIO1", "PWR_LOW_N";

please one GPIO name per line like in the other files. This makes it easier to review changes and add comments.

Stefan

> +		status = "okay";
> +	};
>  };
>  
>  /* uart0 communicates with the BT module */
> -- 
> 2.15.1
>

^ permalink raw reply

* [PATCH v2 3/4] gpio: raspberrypi-exp: Driver for RPi3 GPIO expander via mailbox service
From: Stefan Wahren @ 2018-01-13 10:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <35b07d1aae959c357d671f5530311320d0f10cc8.1515698418.git.baruch@tkos.co.il>

Hi Baruch,

> Baruch Siach <baruch@tkos.co.il> hat am 11. Januar 2018 um 20:44 geschrieben:
> 
> 
> From: Dave Stevenson <dave.stevenson@raspberrypi.org>
> 
> Pi3 and Compute Module 3 have a GPIO expander that the
> VPU communicates with.
> There is a mailbox service that now allows control of this
> expander, so add a kernel driver that can make use of it.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
> v2:
>   * Rename driver to gpio-raspberrypi-exp
>   * Populate the gpiochip parent device pointer
>   * Use macro for the mailbox base GPIO number
>   * Drop linux/gpio.h and GPIOF_DIR_*
>   * Check and print firmware error value
>   * Use devm_gpiochip_add_data(); drop .remove
>   * A few more minor tweaks
> ---
>  drivers/gpio/Kconfig                |   9 ++
>  drivers/gpio/Makefile               |   1 +
>  drivers/gpio/gpio-raspberrypi-exp.c | 258 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 268 insertions(+)
>  create mode 100644 drivers/gpio/gpio-raspberrypi-exp.c
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index d6a8e851ad13..8df901c75bef 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -128,6 +128,15 @@ config GPIO_AXP209
>  	help
>  	  Say yes to enable GPIO support for the AXP209 PMIC
>  
> +config GPIO_RASPBERRYPI_EXP
> +	bool "RaspberryPi 3 Exp GPIO"

How about "RaspberryPi 3 GPIO Expander" ?

Why not tristate? On arm64 it's preferred to have a kernel module.


> +	default RASPBERRYPI_FIRMWARE
> +	depends on OF_GPIO && RASPBERRYPI_FIRMWARE && \
> +		(ARCH_BCM2835 || COMPILE_TEST)

Since this is default on RASPBERRYPI_FIRMWARE, we could remove it from the dependencies.

> +	help
> +	  Turn on GPIO support for the expander on Raspberry Pi 3 boards, using
> +	  the firmware mailbox to communicate with VideoCore on BCM283x chips.
> +
>  config GPIO_BCM_KONA
>  	bool "Broadcom Kona GPIO"
>  	depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 4bc24febb889..71021b0e71da 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_ARIZONA)	+= gpio-arizona.o
>  obj-$(CONFIG_GPIO_ATH79)	+= gpio-ath79.o
>  obj-$(CONFIG_GPIO_ASPEED)	+= gpio-aspeed.o
>  obj-$(CONFIG_GPIO_AXP209)	+= gpio-axp209.o
> +obj-$(CONFIG_GPIO_RASPBERRYPI_EXP)	+= gpio-raspberrypi-exp.o
>  obj-$(CONFIG_GPIO_BCM_KONA)	+= gpio-bcm-kona.o
>  obj-$(CONFIG_GPIO_BD9571MWV)	+= gpio-bd9571mwv.o
>  obj-$(CONFIG_GPIO_BRCMSTB)	+= gpio-brcmstb.o
> diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
> new file mode 100644
> index 000000000000..95b1957a69fa
> --- /dev/null
> +++ b/drivers/gpio/gpio-raspberrypi-exp.c
> @@ -0,0 +1,258 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + *  Raspberry Pi 3 expander GPIO driver
> + *
> + *  Uses the firmware mailbox service to communicate with the
> + *  GPIO expander on the VPU.
> + *
> + *  Copyright (C) 2017 Raspberry Pi Trading Ltd.

2018?

> + */
> +
> +#include <linux/err.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/dma-mapping.h>

I can't see any DMA handling, so please remove it.

> +#include <soc/bcm2835/raspberrypi-firmware.h>
> +
> +#define MODULE_NAME "raspberrypi-exp-gpio"
> +#define NUM_GPIO 8
> +
> +#define RPI_EXP_GPIO_BASE	128
> +
> +#define RPI_EXP_GPIO_DIR_IN	0
> +#define RPI_EXP_GPIO_DIR_OUT	1
> +
> +struct rpi_exp_gpio {
> +	struct gpio_chip gc;
> +	struct rpi_firmware *fw;
> +};
> +
> +/* VC4 firmware mailbox interface data structures */
> +
> +struct gpio_set_config {
> +	u32 gpio;
> +	u32 direction;
> +	u32 polarity;
> +	u32 term_en;
> +	u32 term_pull_up;
> +	u32 state;
> +};
> +
> +struct gpio_get_config {
> +	u32 gpio;
> +	u32 direction;
> +	u32 polarity;
> +	u32 term_en;
> +	u32 term_pull_up;
> +};
> +
> +struct gpio_get_set_state {
> +	u32 gpio;
> +	u32 state;
> +};
> +
> +static int rpi_exp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
> +{
> +	struct rpi_exp_gpio *gpio;
> +	struct gpio_get_config get;
> +	int ret;
> +
> +	gpio = gpiochip_get_data(gc);
> +
> +	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
> +
> +	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
> +				    &get, sizeof(get));
> +	if (ret || get.gpio != 0) {
> +		dev_err(gc->parent,
> +			"Failed to get GPIO %u config (%d %x)\n", off, ret,
> +			get.gpio);

Can't we change this to fit in 2 lines?

> +		return ret ? ret : -EIO;
> +	}
> +	return get.polarity;
> +}
> +
> +static int rpi_exp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
> +{
> +	struct rpi_exp_gpio *gpio;
> +	struct gpio_set_config set_in;
> +	int ret;
> +
> +	gpio = gpiochip_get_data(gc);
> +
> +	set_in.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
> +	set_in.direction = RPI_EXP_GPIO_DIR_IN;
> +	set_in.polarity = rpi_exp_gpio_get_polarity(gc, off);

This could fail, so please check the return code.

> +					/* Retain existing setting */
> +	set_in.term_en = 0;		/* termination disabled */
> +	set_in.term_pull_up = 0;	/* n/a as termination disabled */
> +	set_in.state = 0;		/* n/a as configured as an input */
> +
> +	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
> +				    &set_in, sizeof(set_in));
> +	if (ret || set_in.gpio != 0) {
> +		dev_err(gc->parent,
> +			"Failed to set GPIO %u to input (%d %x)\n",
> +			off, ret, set_in.gpio);

see above

> +		return ret ? ret : -EIO;
> +	}
> +	return 0;
> +}
> +
> +static int rpi_exp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
> +{
> +	struct rpi_exp_gpio *gpio;
> +	struct gpio_set_config set_out;
> +	int ret;
> +
> +	gpio = gpiochip_get_data(gc);
> +
> +	set_out.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
> +	set_out.direction = RPI_EXP_GPIO_DIR_OUT;
> +	set_out.polarity = rpi_exp_gpio_get_polarity(gc, off);

This could also fail.

> +					/* Retain existing setting */
> +	set_out.term_en = 0;		/* n/a as an output */
> +	set_out.term_pull_up = 0;	/* n/a as termination disabled */
> +	set_out.state = val;		/* Output state */
> +
> +	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
> +				    &set_out, sizeof(set_out));
> +	if (ret || set_out.gpio != 0) {
> +		dev_err(gc->parent,
> +			"Failed to set GPIO %u to output (%d %x)\n", off, ret,
> +			set_out.gpio);
> +		return ret ? ret : -EIO;
> +	}
> +	return 0;
> +}
> +
> +static int rpi_exp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
> +{
> +	struct rpi_exp_gpio *gpio;
> +	struct gpio_get_config get;
> +	int ret;
> +
> +	gpio = gpiochip_get_data(gc);
> +
> +	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
> +
> +	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
> +				    &get, sizeof(get));
> +	if (ret || get.gpio != 0) {
> +		dev_err(gc->parent,
> +			"Failed to get GPIO %u config (%d %x)\n", off, ret,
> +			get.gpio);
> +		return ret ? ret : -EIO;
> +	}
> +	return !get.direction;
> +}
> +
> +static int rpi_exp_gpio_get(struct gpio_chip *gc, unsigned int off)
> +{
> +	struct rpi_exp_gpio *gpio;
> +	struct gpio_get_set_state get;
> +	int ret;
> +
> +	gpio = gpiochip_get_data(gc);
> +
> +	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
> +	get.state = 0;		/* storage for returned value */
> +
> +	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
> +					 &get, sizeof(get));
> +	if (ret || get.gpio != 0) {
> +		dev_err(gc->parent,
> +			"Failed to get GPIO %u state (%d %x)\n", off, ret,
> +			get.gpio);
> +		return ret ? ret : -EIO;
> +	}
> +	return !!get.state;
> +}
> +
> +static void rpi_exp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
> +{
> +	struct rpi_exp_gpio *gpio;
> +	struct gpio_get_set_state set;
> +	int ret;
> +
> +	gpio = gpiochip_get_data(gc);
> +
> +	set.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
> +	set.state = val;	/* Output state */
> +
> +	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
> +					 &set, sizeof(set));
> +	if (ret || set.gpio != 0)
> +		dev_err(gc->parent,
> +			"Failed to set GPIO %u state (%d %x)\n", off, ret,
> +			set.gpio);
> +}
> +
> +static int rpi_exp_gpio_probe(struct platform_device *pdev)
> +{
> +	int err = 0;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct device_node *fw_node;
> +	struct rpi_firmware *fw;
> +	struct rpi_exp_gpio *rpi_gpio;
> +
> +	fw_node = of_parse_phandle(np, "firmware", 0);
> +	if (!fw_node) {
> +		dev_err(dev, "Missing firmware node\n");
> +		return -ENOENT;
> +	}
> +
> +	fw = rpi_firmware_get(fw_node);
> +	if (!fw)
> +		return -EPROBE_DEFER;
> +
> +	rpi_gpio = devm_kzalloc(dev, sizeof(*rpi_gpio), GFP_KERNEL);
> +	if (!rpi_gpio)
> +		return -ENOMEM;
> +
> +	rpi_gpio->fw = fw;
> +	rpi_gpio->gc.parent = dev;
> +	rpi_gpio->gc.label = MODULE_NAME;
> +	rpi_gpio->gc.owner = THIS_MODULE;
> +	rpi_gpio->gc.of_node = np;
> +	rpi_gpio->gc.base = -1;
> +	rpi_gpio->gc.ngpio = NUM_GPIO;
> +
> +	rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in;
> +	rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out;
> +	rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction;
> +	rpi_gpio->gc.get = rpi_exp_gpio_get;
> +	rpi_gpio->gc.set = rpi_exp_gpio_set;
> +	rpi_gpio->gc.can_sleep = true;
> +
> +	err = devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
> +	if (err)
> +		return err;
> +
> +	platform_set_drvdata(pdev, rpi_gpio);

Since we use devm_gpiochip_add_data, we can drop this.

> +
> +	return 0;
> +}
> +
> +static const struct of_device_id rpi_exp_gpio_ids[] = {
> +	{ .compatible = "raspberrypi,firmware-gpio" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, rpi_exp_gpio_ids);
> +
> +static struct platform_driver rpi_exp_gpio_driver = {
> +	.driver	= {
> +		.name		= MODULE_NAME,
> +		.owner		= THIS_MODULE,

Please drop this, too.

Thanks
Stefan

^ permalink raw reply

* [PATCH] pinctrl/nomadik/abx500: Use seq_putc() in abx500_gpio_dbg_show()
From: SF Markus Elfring @ 2018-01-13 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 13 Jan 2018 11:04:29 +0100

A single character (line break) should be put into a sequence.
Thus use the corresponding function "seq_putc".

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/pinctrl/nomadik/pinctrl-abx500.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c
index b32c0d602024..ed47ae5b0682 100644
--- a/drivers/pinctrl/nomadik/pinctrl-abx500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c
@@ -633,7 +633,7 @@ static void abx500_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 	for (i = 0; i < chip->ngpio; i++, gpio++) {
 		/* On AB8500, there is no GPIO0, the first is the GPIO 1 */
 		abx500_gpio_dbg_show_one(s, pctldev, chip, i + 1, gpio);
-		seq_printf(s, "\n");
+		seq_putc(s, '\n');
 	}
 }
 
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2 2/4] dt-bindings: gpio: add raspberry pi GPIO expander binding
From: Stefan Wahren @ 2018-01-13 10:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a93ba9ec4d3d3ff6d1e2a79f4f813a2f86c4086b.1515698418.git.baruch@tkos.co.il>

Hi Baruch,

> Baruch Siach <baruch@tkos.co.il> hat am 11. Januar 2018 um 20:44 geschrieben:
> 
> 
> The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware over
> I2C. The firmware mailbox interface allows the ARM core to control the
> GPIO lines.
> 
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> ---
> v2:
>   * Rename compatible string to raspberrypi,firmware-gpio
> ---
>  .../bindings/gpio/raspberrypi,firmware-gpio.txt    | 24 ++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
> new file mode 100644
> index 000000000000..8faf269cf541
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
> @@ -0,0 +1,24 @@
> +Raspberry Pi GPIO expander
> +
> +The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware. The
> +firmware exposes a mailbox interface that allows the ARM core to control the
> +GPIO lines on the expander.
> +
> +Required properties:
> +
> +- compatible : Should be "raspberrypi,firmware-gpio"
> +- gpio-controller : Marks the device node as a gpio controller
> +- #gpio-cells : Should be two.  The first cell is the pin number, and
> +  the second cell is used to specify the gpio polarity:
> +  0 = active high
> +  1 = active low
> +- firmware : Reference to the RPi firmware device node
> +
> +Example:
> +
> +expgpio: expgpio {

just a nit, please change this to

expgpio: gpio-expander {

just like in patch #4


Thanks Stefan

^ permalink raw reply

* bcm2835: device tree regression in 4.15.0-rc7
From: kernel at martin.sperl.org @ 2018-01-13 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

I have to report a regression in 4.15.0-rc7 when using a device tree compiled in 4.14.0.
(from the cm3 patch that I have posted earlier, which needed brushing up).

The system fails with the following:

Jan 13 09:18:18 raspcm3 kernel: [    1.515454] vc4-drm soc:gpu: bound 3f902000.hdmi (ops vc4_hdmi_ops)
Jan 13 09:18:18 raspcm3 kernel: [    1.524755] vc4-drm soc:gpu: bound 3f806000.vec (ops vc4_vec_ops)
Jan 13 09:18:18 raspcm3 kernel: [    1.533707] vc4-drm soc:gpu: bound 3f400000.hvs (ops vc4_hvs_ops)
Jan 13 09:18:18 raspcm3 kernel: [    1.542704] vc4-drm soc:gpu: bound 3f206000.pixelvalve (ops vc4_crtc_ops)
Jan 13 09:18:18 raspcm3 kernel: [    1.552365] vc4-drm soc:gpu: bound 3f207000.pixelvalve (ops vc4_crtc_ops)
Jan 13 09:18:18 raspcm3 kernel: [    1.561928] vc4-drm soc:gpu: bound 3f807000.pixelvalve (ops vc4_crtc_ops)
Jan 13 09:18:18 raspcm3 kernel: [    1.590330] ------------[ cut here ]------------
Jan 13 09:18:18 raspcm3 kernel: [    1.597459] WARNING: CPU: 0 PID: 70 at kernel/irq/chip.c:244 __irq_startup+0x50/0xb4
Jan 13 09:18:18 raspcm3 kernel: [    1.610254] Modules linked in:
Jan 13 09:18:18 raspcm3 kernel: [    1.615823] CPU: 0 PID: 70 Comm: kworker/0:2 Not tainted 4.15.0-rc7msu7+ #175
Jan 13 09:18:18 raspcm3 kernel: [    1.625587] Hardware name: BCM2835
Jan 13 09:18:18 raspcm3 kernel: [    1.631622] Workqueue: events deferred_probe_work_func
Jan 13 09:18:18 raspcm3 kernel: [    1.639471] [<c0110a50>] (unwind_backtrace) from [<c010c750>] (show_stack+0x20/0x24)
Jan 13 09:18:18 raspcm3 kernel: [    1.652696] [<c010c750>] (show_stack) from [<c0796070>] (dump_stack+0x8c/0xb0)
Jan 13 09:18:18 raspcm3 kernel: [    1.662819] [<c0796070>] (dump_stack) from [<c0120ad4>] (__warn+0xf0/0x110)
Jan 13 09:18:18 raspcm3 kernel: [    1.672676] [<c0120ad4>] (__warn) from [<c0120be0>] (warn_slowpath_null+0x4c/0x58)
Jan 13 09:18:18 raspcm3 kernel: [    1.685978] [<c0120be0>] (warn_slowpath_null) from [<c0173a8c>] (__irq_startup+0x50/0xb4)
Jan 13 09:18:18 raspcm3 kernel: [    1.700005] [<c0173a8c>] (__irq_startup) from [<c0173bf0>] (irq_startup+0x100/0x120)
Jan 13 09:18:18 raspcm3 kernel: [    1.713701] [<c0173bf0>] (irq_startup) from [<c0171a9c>] (__enable_irq+0x70/0x80)
Jan 13 09:18:18 raspcm3 kernel: [    1.727338] [<c0171a9c>] (__enable_irq) from [<c0171b1c>] (enable_irq+0x70/0x80)
Jan 13 09:18:18 raspcm3 kernel: [    1.741030] [<c0171b1c>] (enable_irq) from [<c049ed48>] (vc4_irq_postinstall+0x20/0x44)
Jan 13 09:18:18 raspcm3 kernel: [    1.755750] [<c049ed48>] (vc4_irq_postinstall) from [<c047126c>] (drm_irq_install+0xdc/0x11c)
Jan 13 09:18:18 raspcm3 kernel: [    1.771499] [<c047126c>] (drm_irq_install) from [<c04a1b6c>] (vc4_v3d_bind+0x1c0/0x224)
Jan 13 09:18:18 raspcm3 kernel: [    1.786924] [<c04a1b6c>] (vc4_v3d_bind) from [<c04a4824>] (component_bind_all+0x110/0x224)
Jan 13 09:18:18 raspcm3 kernel: [    1.802730] [<c04a4824>] (component_bind_all) from [<c0495744>] (vc4_drm_bind+0x90/0x138)
Jan 13 09:18:18 raspcm3 kernel: [    1.818603] [<c0495744>] (vc4_drm_bind) from [<c04a41d4>] (try_to_bring_up_master+0x14c/0x254)
Jan 13 09:18:18 raspcm3 kernel: [    1.835083] [<c04a41d4>] (try_to_bring_up_master) from [<c04a4380>] (component_add+0xa4/0x11c)
Jan 13 09:18:18 raspcm3 kernel: [    1.851583] [<c04a4380>] (component_add) from [<c04a15a4>] (vc4_v3d_dev_probe+0x20/0x28)
Jan 13 09:18:18 raspcm3 kernel: [    1.867723] [<c04a15a4>] (vc4_v3d_dev_probe) from [<c04ac1ec>] (platform_drv_probe+0x60/0xac)
Jan 13 09:18:18 raspcm3 kernel: [    1.884344] [<c04ac1ec>] (platform_drv_probe) from [<c04aa608>] (driver_probe_device+0x254/0x46c)
Jan 13 09:18:18 raspcm3 kernel: [    1.901326] [<c04aa608>] (driver_probe_device) from [<c04aaa1c>] (__device_attach_driver+0xb0/0x104)
Jan 13 09:18:18 raspcm3 kernel: [    1.918572] [<c04aaa1c>] (__device_attach_driver) from [<c04a8890>] (bus_for_each_drv+0x98/0xa0)
Jan 13 09:18:18 raspcm3 kernel: [    1.935469] [<c04a8890>] (bus_for_each_drv) from [<c04aa2b4>] (__device_attach+0xac/0x134)
Jan 13 09:18:18 raspcm3 kernel: [    1.951857] [<c04aa2b4>] (__device_attach) from [<c04aaa8c>] (device_initial_probe+0x1c/0x20)
Jan 13 09:18:18 raspcm3 kernel: [    1.968516] [<c04aaa8c>] (device_initial_probe) from [<c04a9640>] (bus_probe_device+0x38/0x90)
Jan 13 09:18:18 raspcm3 kernel: [    1.985264] [<c04a9640>] (bus_probe_device) from [<c04a9c44>] (deferred_probe_work_func+0x10c/0x140)
Jan 13 09:18:18 raspcm3 kernel: [    2.002548] [<c04a9c44>] (deferred_probe_work_func) from [<c01385c0>] (process_one_work+0x1d0/0x42c)
Jan 13 09:18:18 raspcm3 kernel: [    2.036136] [<c013976c>] (worker_thread) from [<c013e404>] (kthread+0x14c/0x164)
Jan 13 09:18:18 raspcm3 kernel: [    2.051636] [<c013e404>] (kthread) from [<c0108068>] (ret_from_fork+0x14/0x2c)
Jan 13 09:18:18 raspcm3 kernel: [    2.062979] ---[ end trace 574020c6446fc7f4 ]---
Jan 13 09:18:18 raspcm3 kernel: [    2.071713] vc4-drm soc:gpu: bound 3fc00000.v3d (ops vc4_v3d_ops)
Jan 13 09:18:18 raspcm3 kernel: [    2.081863] checking generic (3db75000 85400) vs hw (0 ffffffff)
Jan 13 09:18:18 raspcm3 kernel: [    2.081869] fb: switching to vc4drmfb from simple
Jan 13 09:18:18 raspcm3 kernel: [    2.090677] Console: switching to colour dummy device 80x30
Jan 13 09:18:18 raspcm3 kernel: [    2.097454] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 0
Jan 13 09:18:18 raspcm3 kernel: [    2.104083] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
Jan 13 09:18:18 raspcm3 kernel: [    2.110732] [drm] Driver supports precise vblank timestamp query.
Jan 13 09:18:18 raspcm3 kernel: [    2.159872] Console: switching to colour frame buffer device 90x30

And then later on systemd fails:
[  OK  ] Started Raise network interfaces.
[FAILED] Failed to start Login Service.
See 'systemctl status systemd-logind.service' for details. and network does not
come up so ssh access is not possible?
DHCP-Networking does not come up either!

After reapplying the patch for CM3-dt and rebuilding it boots fine.

As far as I understand older, formerly functional DTs should always continue to work.

Martin

^ permalink raw reply

* [PATCH v2 1/4] ARM: bcm2835: sync firmware properties with downstream
From: Stefan Wahren @ 2018-01-13  9:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e68675d54955c754ebe8ffc2491585fde5b396bc.1515698418.git.baruch@tkos.co.il>


> Baruch Siach <baruch@tkos.co.il> hat am 11. Januar 2018 um 20:44 geschrieben:
> 
> 
> Add latest firmware property tags from the latest Raspberry Pi downstream
> kernel. This is needed for the GPIO tags, so we can control the GPIO
> multiplexor lines.
> 
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>

Acked-by: Stefan Wahren <stefan.wahren@i2se.com>

Maybe this is obvious, but patch #3 depends on this change so no cherry-picking allowed.

^ permalink raw reply

* [alsa-devel] [RESEND PATCH v2 12/15] ASoC: qcom: qdsp6: Add support to q6asm dai driver
From: Rohit Kumar @ 2018-01-13  8:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171214173402.19074-13-srinivas.kandagatla@linaro.org>



On 12/14/2017 11:03 PM, srinivas.kandagatla at linaro.org wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>
> This patch adds support to q6asm dai driver which configures Q6ASM streams
> to pass pcm data.
> Currently the driver only exposes 2 playback streams for hdmi playback
> support, it can be easily extended to add all 8 streams.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
>   sound/soc/qcom/Kconfig           |   6 +
>   sound/soc/qcom/qdsp6/Makefile    |   1 +
>   sound/soc/qcom/qdsp6/q6asm-dai.c | 534 +++++++++++++++++++++++++++++++++++++++
>   3 files changed, 541 insertions(+)
>   create mode 100644 sound/soc/qcom/qdsp6/q6asm-dai.c
>
> diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
> index 003ce182691c..ecd1e4ba834d 100644
> --- a/sound/soc/qcom/Kconfig
[..]
> +static void event_handler(uint32_t opcode, uint32_t token,
> +			  uint32_t *payload, void *priv)
> +{
> +	struct q6asm_dai_rtd *prtd = priv;
> +	struct snd_pcm_substream *substream = prtd->substream;
> +
> +	switch (opcode) {
> +	case ASM_CLIENT_EVENT_CMD_RUN_DONE:
> +		q6asm_write_nolock(prtd->audio_client,
> +				   prtd->pcm_count, 0, 0, NO_TIMESTAMP);
> +		break;
> +	case ASM_CLIENT_EVENT_CMD_EOS_DONE:
> +		prtd->state = STOPPED;
> +		break;
Add support for V2 version of opcode to support latest adsp
> +	case ASM_CLIENT_EVENT_DATA_WRITE_DONE: {
> +		prtd->pcm_irq_pos += prtd->pcm_count;
> +		snd_pcm_period_elapsed(substream);
> +		if (prtd->state == RUNNING)
> +			q6asm_write_nolock(prtd->audio_client,
> +					   prtd->pcm_count, 0, 0, NO_TIMESTAMP);
> +
> +		break;
> +		}
> +	default:
> +		break;
> +	}
> +}
> +
> +static int q6asm_dai_prepare(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
> +	struct q6asm_dai_rtd *prtd = runtime->private_data;
> +	struct q6asm_dai_data *pdata;
> +	int ret;
> +
> +	pdata = dev_get_drvdata(soc_prtd->platform->dev);
> +	if (!pdata)
> +		return -EINVAL;
> +
> +	if (!prtd || !prtd->audio_client) {
> +		pr_err("%s: private data null or audio client freed\n",
> +			__func__);
> +		return -EINVAL;
> +	}
> +
> +	prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
> +	prtd->pcm_irq_pos = 0;
> +	/* rate and channels are sent to audio driver */
> +	if (prtd->state) {
> +		/* clear the previous setup if any  */
> +		q6asm_cmd(prtd->audio_client, CMD_CLOSE);
> +		q6asm_unmap_memory_regions(substream->stream,
> +					   prtd->audio_client);
> +		q6routing_dereg_phy_stream(soc_prtd->dai_link->id,
> +					 SNDRV_PCM_STREAM_PLAYBACK);
> +	}
> +
> +	ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client,
> +				       prtd->phys,
> +				       (prtd->pcm_size / prtd->periods),
> +				       prtd->periods);
> +
> +	if (ret < 0) {
> +		pr_err("Audio Start: Buffer Allocation failed rc = %d\n",
> +							ret);
> +		return -ENOMEM;
> +	}
> +
> +	ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM,
> +			       prtd->bits_per_sample);
> +	if (ret < 0) {
> +		pr_err("%s: q6asm_open_write failed\n", __func__);
> +		q6asm_audio_client_free(prtd->audio_client);
> +		prtd->audio_client = NULL;
> +		return -ENOMEM;
> +	}
> +
> +	prtd->session_id = q6asm_get_session_id(prtd->audio_client);
> +	ret = q6routing_reg_phy_stream(soc_prtd->dai_link->id, LEGACY_PCM_MODE,
> +				      prtd->session_id, substream->stream);
> +	if (ret) {
> +		pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	ret = q6asm_media_format_block_multi_ch_pcm(
> +			prtd->audio_client, runtime->rate,
> +			runtime->channels, !prtd->set_channel_map,
> +			prtd->channel_map, prtd->bits_per_sample);
> +	if (ret < 0)
> +		pr_info("%s: CMD Format block failed\n", __func__);
> +
> +	prtd->state = RUNNING;
> +
> +	return 0;
> +}
> +
> +static int q6asm_dai_trigger(struct snd_pcm_substream *substream, int cmd)
> +{
> +	int ret = 0;
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct q6asm_dai_rtd *prtd = runtime->private_data;
> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +		ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
> +		break;
> +	case SNDRV_PCM_TRIGGER_RESUME:
> +	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> +		ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
> +		break;
> +	case SNDRV_PCM_TRIGGER_STOP:
> +		prtd->state = STOPPED;
> +		ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
> +		break;
> +	case SNDRV_PCM_TRIGGER_SUSPEND:
> +	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> +		ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static int q6asm_dai_open(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
> +	struct q6asm_dai_rtd *prtd;
> +	struct q6asm_dai_data *pdata;
> +	struct device *dev = soc_prtd->platform->dev;
> +	int ret = 0;
> +
> +	pdata = dev_get_drvdata(dev);
> +	if (!pdata) {
> +		pr_err("Platform data not found ..\n");
> +		return -EINVAL;
> +	}
> +
> +	prtd = kzalloc(sizeof(struct q6asm_dai_rtd), GFP_KERNEL);
> +	if (prtd == NULL)
> +		return -ENOMEM;
> +
> +	prtd->substream = substream;
> +	prtd->audio_client = q6asm_audio_client_alloc(dev,
> +				(app_cb)event_handler, prtd);
> +	if (!prtd->audio_client) {
> +		pr_info("%s: Could not allocate memory\n", __func__);
> +		kfree(prtd);
> +		return -ENOMEM;
> +	}
> +
> +//	prtd->audio_client->dev = dev;
> +
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> +		runtime->hw = q6asm_dai_hardware_playback;
> +
> +	ret = snd_pcm_hw_constraint_list(runtime, 0,
> +				SNDRV_PCM_HW_PARAM_RATE,
> +				&constraints_sample_rates);
> +	if (ret < 0)
> +		pr_info("snd_pcm_hw_constraint_list failed\n");
> +	/* Ensure that buffer size is a multiple of period size */
> +	ret = snd_pcm_hw_constraint_integer(runtime,
> +					    SNDRV_PCM_HW_PARAM_PERIODS);
> +	if (ret < 0)
> +		pr_info("snd_pcm_hw_constraint_integer failed\n");
> +
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> +		ret = snd_pcm_hw_constraint_minmax(runtime,
> +			SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
> +			PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE,
> +			PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE);
> +		if (ret < 0) {
> +			pr_err("constraint for buffer bytes min max ret = %d\n",
> +									ret);
> +		}
> +	}
> +
> +	ret = snd_pcm_hw_constraint_step(runtime, 0,
> +		SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
> +	if (ret < 0) {
> +		pr_err("constraint for period bytes step ret = %d\n",
> +								ret);
> +	}
> +	ret = snd_pcm_hw_constraint_step(runtime, 0,
> +		SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
> +	if (ret < 0) {
> +		pr_err("constraint for buffer bytes step ret = %d\n",
> +								ret);
> +	}
> +
> +	prtd->set_channel_map = false;
> +	runtime->private_data = prtd;
> +
> +	snd_soc_set_runtime_hwparams(substream, &q6asm_dai_hardware_playback);
> +
> +	runtime->dma_bytes = q6asm_dai_hardware_playback.buffer_bytes_max;
> +
> +
> +	if (pdata->sid < 0)
> +		prtd->phys = substream->dma_buffer.addr;
> +	else
> +		prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32);
> +
> +	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
> +
> +	return 0;
> +}
> +
> +static int q6asm_dai_close(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
> +	struct q6asm_dai_rtd *prtd = runtime->private_data;
> +
> +	if (prtd->audio_client) {
> +		q6asm_cmd(prtd->audio_client, CMD_CLOSE);
> +		q6asm_unmap_memory_regions(substream->stream,
> +					   prtd->audio_client);
> +		q6asm_audio_client_free(prtd->audio_client);
> +	}
> +	q6routing_dereg_phy_stream(soc_prtd->dai_link->id,
> +						SNDRV_PCM_STREAM_PLAYBACK);
> +	kfree(prtd);
> +	return 0;
> +}
> +
> +static snd_pcm_uframes_t q6asm_dai_pointer(struct snd_pcm_substream *substream)
> +{
> +
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct q6asm_dai_rtd *prtd = runtime->private_data;
> +
> +	if (prtd->pcm_irq_pos >= prtd->pcm_size)
> +		prtd->pcm_irq_pos = 0;
> +
> +	return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
> +}
> +
> +static int q6asm_dai_mmap(struct snd_pcm_substream *substream,
> +				struct vm_area_struct *vma)
> +{
> +
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
> +	struct snd_card *card = soc_prtd->card->snd_card;
> +
> +	return dma_mmap_coherent(card->dev, vma,
> +			runtime->dma_area, runtime->dma_addr,
> +			runtime->dma_bytes);
> +}
> +
> +static int q6asm_dai_hw_params(struct snd_pcm_substream *substream,
> +				struct snd_pcm_hw_params *params)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct q6asm_dai_rtd *prtd = runtime->private_data;
> +
> +	prtd->pcm_size = params_buffer_bytes(params);
> +	prtd->periods = params_periods(params);
> +
> +	switch (params_format(params)) {
> +	case SNDRV_PCM_FORMAT_S16_LE:
> +		prtd->bits_per_sample = 16;
> +		break;
> +	case SNDRV_PCM_FORMAT_S24_LE:
> +		prtd->bits_per_sample = 24;
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct snd_pcm_ops q6asm_dai_ops = {
> +	.open           = q6asm_dai_open,
> +	.hw_params	= q6asm_dai_hw_params,
> +	.close          = q6asm_dai_close,
> +	.ioctl          = snd_pcm_lib_ioctl,
> +	.prepare        = q6asm_dai_prepare,
> +	.trigger        = q6asm_dai_trigger,
> +	.pointer        = q6asm_dai_pointer,
> +	.mmap		= q6asm_dai_mmap,
> +};
> +
> +static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd)
> +{
> +	struct snd_pcm *pcm = rtd->pcm;
> +	struct snd_pcm_substream *substream;
> +	struct snd_card *card = rtd->card->snd_card;
> +	struct device *dev = card->dev;
> +	struct device_node *node = dev->of_node;
> +	struct q6asm_dai_data *pdata = dev_get_drvdata(rtd->platform->dev);
> +	struct of_phandle_args args;
> +
> +	int size, ret = 0;
> +
> +	ret = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args);
> +	if (ret < 0)
> +		pdata->sid = -1;
> +	else
> +		pdata->sid = args.args[0];
> +
> +
> +
> +	substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
> +	size = q6asm_dai_hardware_playback.buffer_bytes_max;
> +	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size,
> +				  &substream->dma_buffer);
> +	if (ret) {
> +		dev_err(dev, "Cannot allocate buffer(s)\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static void q6asm_dai_pcm_free(struct snd_pcm *pcm)
> +{
> +	struct snd_pcm_substream *substream;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
> +		substream = pcm->streams[i].substream;
> +		if (substream) {
> +			snd_dma_free_pages(&substream->dma_buffer);
> +			substream->dma_buffer.area = NULL;
> +			substream->dma_buffer.addr = 0;
> +		}
> +	}
> +}
> +
> +static struct snd_soc_platform_driver q6asm_soc_platform = {
> +	.ops		= &q6asm_dai_ops,
> +	.pcm_new	= q6asm_dai_pcm_new,
> +	.pcm_free	= q6asm_dai_pcm_free,
> +
> +};
> +
> +static const struct snd_soc_dapm_route afe_pcm_routes[] = {
> +	{"MM_DL1",  NULL, "MultiMedia1 Playback" },
> +	{"MM_DL2",  NULL, "MultiMedia2 Playback" },
> +
> +};
> +
> +static int fe_dai_probe(struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_dapm_context *dapm;
> +
> +	dapm = snd_soc_component_get_dapm(dai->component);
> +	snd_soc_dapm_add_routes(dapm, afe_pcm_routes,
> +				ARRAY_SIZE(afe_pcm_routes));
> +
> +	return 0;
> +}
> +
> +static const struct snd_soc_component_driver q6asm_fe_dai_component = {
> +	.name		= "q6asm-fe-dai",
> +};
> +
> +static struct snd_soc_dai_driver q6asm_fe_dais[] = {
> +	{
> +		.playback = {
> +			.stream_name = "MultiMedia1 Playback",
> +			.rates = (SNDRV_PCM_RATE_8000_192000|
> +					SNDRV_PCM_RATE_KNOT),
> +			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
> +						SNDRV_PCM_FMTBIT_S24_LE),
> +			.channels_min = 1,
> +			.channels_max = 8,
> +			.rate_min =     8000,
> +			.rate_max =	192000,
> +		},
> +		.name = "MM_DL1",
> +		.probe = fe_dai_probe,
> +		.id = MSM_FRONTEND_DAI_MULTIMEDIA1,
> +	},
> +	{
> +		.playback = {
> +			.stream_name = "MultiMedia2 Playback",
> +			.rates = (SNDRV_PCM_RATE_8000_192000|
> +					SNDRV_PCM_RATE_KNOT),
> +			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
> +						SNDRV_PCM_FMTBIT_S24_LE),
> +			.channels_min = 1,
> +			.channels_max = 8,
> +			.rate_min =     8000,
> +			.rate_max =	192000,
> +		},
> +		.name = "MM_DL2",
> +		.probe = fe_dai_probe,
> +		.id = MSM_FRONTEND_DAI_MULTIMEDIA2,
> +	},
> +};
> +
> +static int q6asm_dai_probe(struct platform_device *pdev)
> +{
> +	struct q6asm_dai_data *pdata;
> +	struct device *dev = &pdev->dev;
> +	int rc;
> +
> +	pdata = devm_kzalloc(dev, sizeof(struct q6asm_dai_data), GFP_KERNEL);
> +	if (!pdata)
> +		return -ENOMEM;
> +
> +
> +	dev_set_drvdata(dev, pdata);
> +
> +	rc = snd_soc_register_platform(dev,  &q6asm_soc_platform);
> +	if (rc) {
> +		dev_err(&pdev->dev, "err_dai_platform\n");
> +		return rc;
> +	}
> +
> +	rc = snd_soc_register_component(dev, &q6asm_fe_dai_component,
> +					q6asm_fe_dais,
> +					ARRAY_SIZE(q6asm_fe_dais));
> +	if (rc)
> +		dev_err(dev, "err_dai_component\n");
> +
> +	return rc;
> +
> +}
> +
> +static int q6asm_dai_remove(struct platform_device *pdev)
> +{
> +	snd_soc_unregister_platform(&pdev->dev);
> +	return 0;
> +}
> +
> +static struct platform_driver q6asm_dai_driver = {
> +	.driver = {
> +		.name = "q6asm_dai",
> +		.owner = THIS_MODULE,
> +	},
> +	.probe = q6asm_dai_probe,
> +	.remove = q6asm_dai_remove,
> +};
> +
> +module_platform_driver(q6asm_dai_driver);
> +
> +MODULE_DESCRIPTION("PCM module platform driver");
> +MODULE_LICENSE("GPL v2");

^ permalink raw reply

* [alsa-devel] [RESEND PATCH v2 08/15] ASoC: qcom: q6asm: add support to audio stream apis
From: Rohit Kumar @ 2018-01-13  8:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171214173402.19074-9-srinivas.kandagatla@linaro.org>



On 12/14/2017 11:03 PM, srinivas.kandagatla at linaro.org wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>
> This patch adds support to open, write and media format commands
> in the q6asm module.
[..]
> +static int32_t q6asm_callback(struct apr_device *adev,
> +			      struct apr_client_data *data, int session_id)
> +{
> +	struct audio_client *ac;// = (struct audio_client *)priv;
> +	uint32_t token;
> +	uint32_t *payload;
> +	uint32_t wakeup_flag = 1;
> +	uint32_t client_event = 0;
> +	struct q6asm *q6asm = dev_get_drvdata(&adev->dev);
> +
> +	if (data == NULL)
> +		return -EINVAL;
> +
> +	ac = q6asm_get_audio_client(q6asm, session_id);
> +	if (!q6asm_is_valid_audio_client(ac))
> +		return -EINVAL;
> +
ac could get freed by q6asm_audio_client_free during the execution of 
q6asm_callback as they are running in different thread.
Add synchronization.
> +	payload = data->payload;
> +
> +	if (data->opcode == APR_BASIC_RSP_RESULT) {
> +		token = data->token;
> +		switch (payload[0]) {
> +		case ASM_SESSION_CMD_PAUSE:
> +			client_event = ASM_CLIENT_EVENT_CMD_PAUSE_DONE;
> +			break;
> +		case ASM_SESSION_CMD_SUSPEND:
> +			client_event = ASM_CLIENT_EVENT_CMD_SUSPEND_DONE;
> +			break;
> +		case ASM_DATA_CMD_EOS:
> +			client_event = ASM_CLIENT_EVENT_CMD_EOS_DONE;
> +			break;
> +			break;
> +		case ASM_STREAM_CMD_FLUSH:
> +			client_event = ASM_CLIENT_EVENT_CMD_FLUSH_DONE;
> +			break;
> +		case ASM_SESSION_CMD_RUN_V2:
> +			client_event = ASM_CLIENT_EVENT_CMD_RUN_DONE;
> +			break;
> +
> +		case ASM_STREAM_CMD_FLUSH_READBUFS:
> +			if (token != ac->session) {
> +				dev_err(ac->dev, "session invalid\n");
> +				return -EINVAL;
> +			}
> +		case ASM_STREAM_CMD_CLOSE:
> +			client_event = ASM_CLIENT_EVENT_CMD_CLOSE_DONE;
> +			break;
> +		case ASM_STREAM_CMD_OPEN_WRITE_V3:
> +		case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
> +			if (payload[1] != 0) {
> +				dev_err(ac->dev,
> +					"cmd = 0x%x returned error = 0x%x\n",
> +					payload[0], payload[1]);
> +				if (wakeup_flag) {
> +					ac->cmd_state = payload[1];
> +					wake_up(&ac->cmd_wait);
> +				}
> +				return 0;
> +			}
> +			break;
> +		default:
> +			dev_err(ac->dev, "command[0x%x] not expecting rsp\n",
> +				payload[0]);
> +			break;
> +		}
> +
> +		if (ac->cmd_state && wakeup_flag) {
> +			ac->cmd_state = 0;
> +			wake_up(&ac->cmd_wait);
> +		}
> +		if (ac->cb)
> +			ac->cb(client_event, data->token,
> +			       data->payload, ac->priv);
> +
> +		return 0;
> +	}
> +
> +	switch (data->opcode) {
> +	case ASM_DATA_EVENT_WRITE_DONE_V2:{
> +			struct audio_port_data *port =
> +			    &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
> +
> +			client_event = ASM_CLIENT_EVENT_DATA_WRITE_DONE;
> +
> +			if (ac->io_mode & SYNC_IO_MODE) {
> +				dma_addr_t phys = port->buf[data->token].phys;
> +
> +				if (lower_32_bits(phys) != payload[0] ||
> +				    upper_32_bits(phys) != payload[1]) {
> +					dev_err(ac->dev, "Expected addr %pa\n",
> +						&port->buf[data->token].phys);
> +					return -EINVAL;
> +				}
> +				token = data->token;
> +				port->buf[token].used = 1;
> +			}
> +			break;
> +		}
> +	}
> +	if (ac->cb)
> +		ac->cb(client_event, data->token, data->payload, ac->priv);
> +
> +	return 0;
> +}
> +
[..]
> +/**
> + * q6asm_media_format_block_multi_ch_pcm() - setup pcm configuration
> + *
> + * @ac: audio client pointer
> + * @rate: audio sample rate
> + * @channels: number of audio channels.
> + * @use_default_chmap: flag to use default ch map.
> + * @channel_map: channel map pointer
> + * @bits_per_sample: bits per sample
> + *
> + * Return: Will be an negative value on error or zero on success
> + */
> +int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
> +					  uint32_t rate, uint32_t channels,
> +					  bool use_default_chmap,
> +					  char *channel_map,
> +					  uint16_t bits_per_sample)
> +{
> +	struct asm_multi_channel_pcm_fmt_blk_v2 fmt;
asm_multi_channel_pcm_fmt_blk_v4 is now being used in latest adsp. 
Better to add adsp version based support to handle different struct
> +	u8 *channel_mapping;
> +	int rc = 0;
> +
> +	q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), true, ac->stream_id);
> +	ac->cmd_state = -1;
> +
> +	fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
> +	fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
> +	    sizeof(fmt.fmt_blk);
> +	fmt.num_channels = channels;
> +	fmt.bits_per_sample = bits_per_sample;
> +	fmt.sample_rate = rate;
> +	fmt.is_signed = 1;
> +
> +	channel_mapping = fmt.channel_mapping;
> +
> +	if (use_default_chmap) {
> +		if (q6dsp_map_channels(channel_mapping, channels)) {
> +			dev_err(ac->dev, " map channels failed %d\n", channels);
> +			return -EINVAL;
> +		}
> +	} else {
> +		memcpy(channel_mapping, channel_map,
> +		       PCM_FORMAT_MAX_NUM_CHANNEL);
> +	}
> +
> +	rc = apr_send_pkt(ac->adev, (uint32_t *) &fmt);
> +	if (rc < 0)
> +		goto fail_cmd;
> +
> +	rc = wait_event_timeout(ac->cmd_wait, (ac->cmd_state >= 0), 5 * HZ);
> +	if (!rc) {
> +		dev_err(ac->dev, "timeout on format update\n");
> +		return -ETIMEDOUT;
> +	}
> +	if (ac->cmd_state > 0)
> +		return adsp_err_get_lnx_err_code(ac->cmd_state);
> +
> +	return 0;
> +fail_cmd:
> +	return rc;
> +}
> +EXPORT_SYMBOL_GPL(q6asm_media_format_block_multi_ch_pcm);
> +
> +/**
> + * q6asm_write_nolock() - non blocking write
> + *
> + * @ac: audio client pointer
> + * @len: lenght in bytes
> + * @msw_ts: timestamp msw
> + * @lsw_ts: timestamp lsw
> + * @flags: flags associated with write
> + *
> + * Return: Will be an negative value on error or zero on success
> + */
> +int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
> +		       uint32_t lsw_ts, uint32_t flags)
> +{
> +	struct asm_data_cmd_write_v2 write;
> +	struct audio_port_data *port;
> +	struct audio_buffer *ab;
> +	int dsp_buf = 0;
> +	int rc = 0;
> +
> +	if (ac->io_mode & SYNC_IO_MODE) {
> +		port = &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
> +		q6asm_add_hdr(ac, &write.hdr, sizeof(write), false,
> +			      ac->stream_id);
> +
> +		dsp_buf = port->dsp_buf;
> +		ab = &port->buf[dsp_buf];
> +
> +		write.hdr.token = port->dsp_buf;
> +		write.hdr.opcode = ASM_DATA_CMD_WRITE_V2;
> +		write.buf_addr_lsw = lower_32_bits(ab->phys);
> +		write.buf_addr_msw = upper_32_bits(ab->phys);
> +		write.buf_size = len;
> +		write.seq_id = port->dsp_buf;
> +		write.timestamp_lsw = lsw_ts;
> +		write.timestamp_msw = msw_ts;
> +		write.mem_map_handle =
> +		    ac->port[SNDRV_PCM_STREAM_PLAYBACK].mem_map_handle;
> +
> +		if (flags == NO_TIMESTAMP)
> +			write.flags = (flags & 0x800000FF);
> +		else
> +			write.flags = (0x80000000 | flags);
> +
> +		port->dsp_buf++;
> +
> +		if (port->dsp_buf >= port->max_buf_cnt)
> +			port->dsp_buf = 0;
> +
> +		rc = apr_send_pkt(ac->adev, (uint32_t *) &write);
> +		if (rc < 0)
> +			return rc;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(q6asm_write_nolock);
> +
> +static void q6asm_reset_buf_state(struct audio_client *ac)
> +{
> +	int cnt = 0;
> +	int loopcnt = 0;
> +	int used;
> +	struct audio_port_data *port = NULL;
> +
> +	if (ac->io_mode & SYNC_IO_MODE) {
> +		used = (ac->io_mode & TUN_WRITE_IO_MODE ? 1 : 0);
> +		mutex_lock(&ac->cmd_lock);
> +		for (loopcnt = 0; loopcnt <= SNDRV_PCM_STREAM_CAPTURE;
> +		     loopcnt++) {
> +			port = &ac->port[loopcnt];
> +			cnt = port->max_buf_cnt - 1;
> +			port->dsp_buf = 0;
> +			while (cnt >= 0) {
> +				if (!port->buf)
> +					continue;
> +				port->buf[cnt].used = used;
> +				cnt--;
> +			}
> +		}
> +		mutex_unlock(&ac->cmd_lock);
> +	}
> +}
> +
> +static int __q6asm_cmd(struct audio_client *ac, int cmd, bool wait)
> +{
> +	int stream_id = ac->stream_id;
> +	struct apr_hdr hdr;
> +	int rc;
> +
> +	q6asm_add_hdr(ac, &hdr, sizeof(hdr), true, stream_id);
> +	ac->cmd_state = -1;
> +	switch (cmd) {
> +	case CMD_PAUSE:
> +		hdr.opcode = ASM_SESSION_CMD_PAUSE;
> +		break;
> +	case CMD_SUSPEND:
> +		hdr.opcode = ASM_SESSION_CMD_SUSPEND;
> +		break;
> +	case CMD_FLUSH:
> +		hdr.opcode = ASM_STREAM_CMD_FLUSH;
> +		break;
> +	case CMD_OUT_FLUSH:
> +		hdr.opcode = ASM_STREAM_CMD_FLUSH_READBUFS;
> +		break;
> +	case CMD_EOS:
> +		hdr.opcode = ASM_DATA_CMD_EOS;
> +		ac->cmd_state = 0;
> +		break;
> +	case CMD_CLOSE:
> +		hdr.opcode = ASM_STREAM_CMD_CLOSE;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	rc = apr_send_pkt(ac->adev, (uint32_t *) &hdr);
> +	if (rc < 0)
> +		return rc;
> +
> +	if (!wait)
> +		return 0;
> +
> +	rc = wait_event_timeout(ac->cmd_wait, (ac->cmd_state >= 0), 5 * HZ);
> +	if (!rc) {
> +		dev_err(ac->dev, "timeout response for opcode[0x%x]\n",
> +			hdr.opcode);
> +		return -ETIMEDOUT;
> +	}
> +	if (ac->cmd_state > 0)
> +		return adsp_err_get_lnx_err_code(ac->cmd_state);
> +
> +	if (cmd == CMD_FLUSH)
> +		q6asm_reset_buf_state(ac);
> +
> +	return 0;
> +}
> +
> +/**
> + * q6asm_cmd() - run cmd on audio client
> + *
> + * @ac: audio client pointer
> + * @cmd: command to run on audio client.
> + *
> + * Return: Will be an negative value on error or zero on success
> + */
> +int q6asm_cmd(struct audio_client *ac, int cmd)
> +{
> +	return __q6asm_cmd(ac, cmd, true);
> +}
> +EXPORT_SYMBOL_GPL(q6asm_cmd);
> +
> +/**
> + * q6asm_cmd_nowait() - non blocking, run cmd on audio client
> + *
> + * @ac: audio client pointer
> + * @cmd: command to run on audio client.
> + *
> + * Return: Will be an negative value on error or zero on success
> + */
> +int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
> +{
> +	return __q6asm_cmd(ac, cmd, false);
> +}
> +EXPORT_SYMBOL_GPL(q6asm_cmd_nowait);
>   
>   static int q6asm_probe(struct apr_device *adev)
>   {
> diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h
> index e1409c368600..b4896059da79 100644
> --- a/sound/soc/qcom/qdsp6/q6asm.h
> +++ b/sound/soc/qcom/qdsp6/q6asm.h
> @@ -2,7 +2,34 @@
>   #ifndef __Q6_ASM_H__
>   #define __Q6_ASM_H__
>   
> +/* ASM client callback events */
> +#define CMD_PAUSE			0x0001
> +#define ASM_CLIENT_EVENT_CMD_PAUSE_DONE		0x1001
> +#define CMD_FLUSH				0x0002
> +#define ASM_CLIENT_EVENT_CMD_FLUSH_DONE		0x1002
> +#define CMD_EOS				0x0003
> +#define ASM_CLIENT_EVENT_CMD_EOS_DONE		0x1003
> +#define CMD_CLOSE				0x0004
> +#define ASM_CLIENT_EVENT_CMD_CLOSE_DONE		0x1004
> +#define CMD_OUT_FLUSH				0x0005
> +#define ASM_CLIENT_EVENT_CMD_OUT_FLUSH_DONE	0x1005
> +#define CMD_SUSPEND				0x0006
> +#define ASM_CLIENT_EVENT_CMD_SUSPEND_DONE	0x1006
> +#define ASM_CLIENT_EVENT_CMD_RUN_DONE		0x1008
> +#define ASM_CLIENT_EVENT_DATA_WRITE_DONE	0x1009
> +
> +#define MSM_FRONTEND_DAI_MULTIMEDIA1	0
> +#define MSM_FRONTEND_DAI_MULTIMEDIA2	1
> +#define	MSM_FRONTEND_DAI_MULTIMEDIA3	2
> +#define MSM_FRONTEND_DAI_MULTIMEDIA4	3
> +#define MSM_FRONTEND_DAI_MULTIMEDIA5	4
> +#define MSM_FRONTEND_DAI_MULTIMEDIA6	5
> +#define	MSM_FRONTEND_DAI_MULTIMEDIA7	6
> +#define	MSM_FRONTEND_DAI_MULTIMEDIA8	7
> +
>   #define MAX_SESSIONS	16
> +#define NO_TIMESTAMP    0xFF00
> +#define FORMAT_LINEAR_PCM   0x0000
>   
>   typedef void (*app_cb) (uint32_t opcode, uint32_t token,
>   			uint32_t *payload, void *priv);
> @@ -10,6 +37,21 @@ struct audio_client;
>   struct audio_client *q6asm_audio_client_alloc(struct device *dev,
>   					      app_cb cb, void *priv);
>   void q6asm_audio_client_free(struct audio_client *ac);
> +int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
> +		       uint32_t lsw_ts, uint32_t flags);
> +int q6asm_open_write(struct audio_client *ac, uint32_t format,
> +		     uint16_t bits_per_sample);
> +int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
> +					  uint32_t rate, uint32_t channels,
> +					  bool use_default_chmap,
> +					  char *channel_map,
> +					  uint16_t bits_per_sample);
> +int q6asm_run(struct audio_client *ac, uint32_t flags, uint32_t msw_ts,
> +	      uint32_t lsw_ts);
> +int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts,
> +		     uint32_t lsw_ts);
> +int q6asm_cmd(struct audio_client *ac, int cmd);
> +int q6asm_cmd_nowait(struct audio_client *ac, int cmd);
>   int q6asm_get_session_id(struct audio_client *ac);
>   int q6asm_map_memory_regions(unsigned int dir,
>   			     struct audio_client *ac,

^ permalink raw reply

* [PATCH] usb: xhci-mtk: fix semicolon.cocci warnings
From: Chunfeng Yun @ 2018-01-13  6:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180112174649.GA116473@ivb43>

On Sat, 2018-01-13 at 01:46 +0800, kbuild test robot wrote:
> From: Fengguang Wu <fengguang.wu@intel.com>
> 
> drivers/usb/host/xhci-mtk.c:311:2-3: Unneeded semicolon
> 
> 
>  Remove unneeded semicolon.
> 
> Generated by: scripts/coccinelle/misc/semicolon.cocci
> 
> Fixes: a2ecc4df9f84 ("usb: xhci-mtk: supports remote wakeup for mt2712 with two xHCI IPs")
> CC: Chunfeng Yun <chunfeng.yun@mediatek.com>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> ---
> 
>  xhci-mtk.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -308,7 +308,7 @@ static void usb_wakeup_ip_sleep_set(stru
>  		break;
>  	default:
>  		return;
> -	};
> +	}
>  	regmap_update_bits(mtk->uwk, reg, msk, val);
>  }
>  
Thanks

Acked-by: Chunfeng Yun <chunfeng.yun@mediatek.com>

^ permalink raw reply

* [PATCH] usb: mtu3: fix semicolon.cocci warnings
From: Chunfeng Yun @ 2018-01-13  6:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180112171853.GA54422@ivb43>

On Sat, 2018-01-13 at 01:18 +0800, kbuild test robot wrote:
> From: Fengguang Wu <fengguang.wu@intel.com>
> 
> drivers/usb/mtu3/mtu3_host.c:58:2-3: Unneeded semicolon
> 
> 
>  Remove unneeded semicolon.
> 
> Generated by: scripts/coccinelle/misc/semicolon.cocci
> 
> Fixes: f0ede2c6282b ("usb: mtu3: supports remote wakeup for mt2712 with two SSUSB IPs")
> CC: Chunfeng Yun <chunfeng.yun@mediatek.com>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> ---
> 
>  mtu3_host.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- a/drivers/usb/mtu3/mtu3_host.c
> +++ b/drivers/usb/mtu3/mtu3_host.c
> @@ -55,7 +55,7 @@ static void ssusb_wakeup_ip_sleep_set(st
>  		break;
>  	default:
>  		return;
> -	};
> +	}
>  	regmap_update_bits(ssusb->uwk, reg, msk, val);
>  }
>  
Thanks a lot.

Acked-by: Chunfeng Yun <chunfeng.yun@mediatek.com>

^ permalink raw reply

* [PATCH][v2] arm64: Allocate elfcorehdr & crashkernel mem before any reservation
From: Poonam Aggrwal @ 2018-01-13  3:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5A58F75E.8030106@arm.com>

Hi James

Regards
Poonam

> -----Original Message-----
> From: James Morse [mailto:james.morse at arm.com]
> Sent: Friday, January 12, 2018 11:29 PM
> To: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> Cc: linux-arm-kernel at lists.infradead.org; takahiro.akashi at linaro.org;
> will.deacon at arm.com; G.h. Gao <guanhua.gao@nxp.com>; Abhimanyu Saini
> <abhimanyu.saini@nxp.com>; kexec at lists.infradead.org
> Subject: Re: [PATCH][v2] arm64: Allocate elfcorehdr & crashkernel mem before
> any reservation
> 
> Hi Poonam,
> 
> On 08/01/18 04:31, Poonam Aggrwal wrote:
> > James Morse wrote:
> >> On 04/01/18 15:34, Poonam Aggrwal wrote:
> >>> Address for both crashkernel memory and elfcorehdr can be assigned
> >>> statically. For crashkernel memory it is via
> >>> crashkernel=SIZE at ADDRESS and elfcorehdr_addr via by kexec-utils in dump
> kernel device tree.
> >>
> >> There are some crashkernel=SIZE at ADDRESS values that the user can
> >> supply that we must reject. The obvious one is if it overlaps with
> >> the kernel text. (this patch won't spot this). We need to read the
> >> hardware's reserved regions from the DT before we allocate the
> >> crashkernel region, for example if the bootloader reserved a chunk of
> >> memory for a frame-buffer, I shouldn't be able to use that as crashkernel
> memory.
> >>
> >> (you shouldn't need to specify an address, doing so prevents the
> >> kernel from picking memory it can use)
> >>
> >>
> >>> So memory should be reserved for both the above areas before any
> >>> other memory reservations are done. Otherwise overlaps may happen
> >>> and memory allocations will fail leading to failure in booting the
> >>> dump capture kernel.
> 
> >>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index
> >>> 00e7b90..24ce15d 100644
> >>> --- a/arch/arm64/mm/init.c
> >>> +++ b/arch/arm64/mm/init.c
> >>> @@ -453,6 +453,14 @@ void __init arm64_memblock_init(void)
> 
> >>> +	reserve_elfcorehdr();
> >>
> >> (Moving reserve_elfcorehdr() makes sense, but..)
> >>
> >>
> >>> +	reserve_crashkernel();
> >>
> >> reserve_crashkernel() does the allocation for the crashkernels reserved
> memory.
> >> I expect this to always fail in the kdump kernel because there isn't
> >> enough memory. (fdt_enforce_memory_region() at the top of this
> >> function calls memblock_cap_memory_range()).
> >>
> >> Moving this allocation above the early_init_fdt_scan_reserved_mem()
> >> below means we may allocate memory for the crashdump that is in use
> >> by firmware/hardware and described as reserved in the DT.
> 
> > Yeah, this is a good point. So ideally the address of the crash kernel
> > should be diligently provided by the user based on the system.
> 
> Even better: the region to store the crash kernel in should be chosen by the
> kernel.
> When using kdump I boot with 'crashkernel=1G', the kernel chooses where to
> place the reserved region.
Right. This is a commonly used.
 Even if I specified a reasonable physical address, the
> efistub may relocate the kernel over the top during boot as part of its KASLR
> work.
Agree
> 
> (Why does anyone ever need to specify an offset here?)
offset is normally an optional argument. Request Takahiro to provide his inputs.  Does this imply any updates in kexec design/implementation/documentation?

> 
> 
> Thanks,
> 
> James

^ permalink raw reply

* [nomadik:gemini-ethernet 9/9] gemini.c:undefined reference to `devm_ioremap_resource'
From: kbuild test robot @ 2018-01-13  2:53 UTC (permalink / raw)
  To: linux-arm-kernel

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git gemini-ethernet
head:   c5fab9815a7a1857155a7911fbce85d1af11ab8f
commit: c5fab9815a7a1857155a7911fbce85d1af11ab8f [9/9] net: ethernet: Add a driver for Gemini gigabit ethernet
config: um-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        git checkout c5fab9815a7a1857155a7911fbce85d1af11ab8f
        # save the attached .config to linux build tree
        make ARCH=um 

All errors (new ones prefixed by >>):

   arch/um/drivers/vde.o: In function `vde_open_real':
   (.text+0x951): warning: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
   (.text+0x79c): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
   (.text+0xab5): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
   arch/um/drivers/pcap.o: In function `pcap_nametoaddr':
   (.text+0xdee5): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
   arch/um/drivers/pcap.o: In function `pcap_nametonetaddr':
   (.text+0xdf85): warning: Using 'getnetbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
   arch/um/drivers/pcap.o: In function `pcap_nametoproto':
   (.text+0xe1a5): warning: Using 'getprotobyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
   arch/um/drivers/pcap.o: In function `pcap_nametoport':
   (.text+0xdfd7): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
   drivers/net/ethernet/cortina/gemini.o: In function `geth_cleanup_freeq':
>> gemini.c:(.text+0x97d): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0xad5): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0xb85): undefined reference to `bad_dma_ops'
   drivers/net/ethernet/cortina/gemini.o: In function `gemini_ethernet_probe':
>> gemini.c:(.text+0xd2b): undefined reference to `devm_ioremap_resource'
   drivers/net/ethernet/cortina/gemini.o: In function `geth_freeq_alloc_map_page':
   gemini.c:(.text+0x11c4): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0x11d0): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0x13dc): undefined reference to `bad_dma_ops'
   drivers/net/ethernet/cortina/gemini.o: In function `geth_resize_freeq':
   gemini.c:(.text+0x1ead): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0x20a4): undefined reference to `bad_dma_ops'
   drivers/net/ethernet/cortina/gemini.o:gemini.c:(.text+0x2247): more undefined references to `bad_dma_ops' follow
   drivers/net/ethernet/cortina/gemini.o: In function `gemini_ethernet_port_probe':
   gemini.c:(.text+0x2dec): undefined reference to `devm_ioremap_resource'
   gemini.c:(.text+0x2e4c): undefined reference to `devm_ioremap_resource'
   drivers/net/ethernet/cortina/gemini.o: In function `gmac_map_tx_bufs.isra.0':
   gemini.c:(.text+0x37fb): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0x3813): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0x393a): undefined reference to `bad_dma_ops'
   drivers/net/ethernet/cortina/gemini.o: In function `gmac_cleanup_rxq':
   gemini.c:(.text+0x3ffa): undefined reference to `bad_dma_ops'
   gemini.c:(.text+0x409d): undefined reference to `bad_dma_ops'
   drivers/net/ethernet/cortina/gemini.o:gemini.c:(.text+0x4245): more undefined references to `bad_dma_ops' follow
   collect2: error: ld returned 1 exit status

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 19820 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180113/798eda0e/attachment-0001.gz>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox