Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Tearing down DMA transfer setup after DMA client has finished
From: Mason @ 2016-12-06 12:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206051222.GQ6408@localhost>

On 06/12/2016 06:12, Vinod Koul wrote:

> On Tue, Nov 29, 2016 at 07:25:02PM +0100, Mason wrote:
> 
>> Is there a way to write a driver within the existing framework?
> 
> I think so, looking back at comments from Russell, I do tend to agree with
> that. Is there a specific reason why sbox can't be tied to alloc and free
> channels?

Here's a recap of the situation.

The "SBOX+MBUS" HW is used in several iterations of the tango SoC:

tango3
  2 memory channels available
  6 devices ("clients"?) may request an MBUS channel

tango4 (one more channel)
  3 memory channels available
  7 devices may request an MBUS channel :
    NFC0, NFC1, SATA0, SATA1, memcpy, (IDE0, IDE1)

Notes:
The current NFC driver supports only one controller.
IDE is mostly obsolete at this point.

tango5 (SATA gets own dedicated MBUS channel pair)
  3 memory channels available
  5 devices may request an MBUS channel :
    NFC0, NFC1, memcpy, (IDE0, IDE1)


If I understand the current DMA driver (written by Mans), client
drivers are instructed to use a specific channel in the DT, and
the DMA driver muxes access to that channel. The DMA driver
manages a per-channel queue of outstanding DMA transfer requests,
and a new transfer is started friom within the DMA ISR
(modulo the fact that the interrupt does not signal completion
of the transfer, as explained else-thread).

What you're proposing, Vinod, is to make a channel exclusive
to a driver, as long as the driver has not explicitly released
the channel, via dma_release_channel(), right?

Regards.

^ permalink raw reply

* [STLinux Kernel] [PATCH 2/3] serial: st-asc: Provide RTS functionality
From: Lee Jones @ 2016-12-06 12:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206123131.GA15382@griffinp-ThinkPad-X1-Carbon-2nd>

On Tue, 06 Dec 2016, Peter Griffin wrote:
> On Mon, 05 Dec 2016, Patrice Chotard wrote:
> > On 12/02/2016 03:11 PM, Lee Jones wrote:
> > > Until this point, it has not been possible for serial applications
> > > to toggle the UART RTS line.  This can be useful with certain
> > > configurations. For example, when using a Mezzanine on a Linaro
> > > 96board, RTS line is used to take the the on-board microcontroller
> > 
> > typo "the the on"
> > 
> > > in and out of reset.
> > > 
> > > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > > ---
> > >  drivers/tty/serial/st-asc.c | 14 ++++++++++++++
> > >  1 file changed, 14 insertions(+)
> > > 
> > > diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
> > > index 379e5bd..ce46898 100644
> > > --- a/drivers/tty/serial/st-asc.c
> > > +++ b/drivers/tty/serial/st-asc.c
> > > @@ -30,6 +30,7 @@
> > >  #include <linux/of_platform.h>
> > >  #include <linux/serial_core.h>
> > >  #include <linux/clk.h>
> > > +#include <linux/gpio/consumer.h>
> > >  
> > >  #define DRIVER_NAME "st-asc"
> > >  #define ASC_SERIAL_NAME "ttyAS"
> > > @@ -38,6 +39,7 @@
> > >  
> > >  struct asc_port {
> > >  	struct uart_port port;
> > > +	struct gpio_desc *rts;
> > >  	struct clk *clk;
> > >  	unsigned int hw_flow_control:1;
> > >  	unsigned int force_m1:1;
> > > @@ -381,12 +383,16 @@ static unsigned int asc_tx_empty(struct uart_port *port)
> > >  
> > >  static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl)
> > >  {
> > > +	struct asc_port *ascport = to_asc_port(port);
> > > +
> > >  	/*
> > >  	 * This routine is used for seting signals of: DTR, DCD, CTS/RTS
> > >  	 * We use ASC's hardware for CTS/RTS, so don't need any for that.
> > >  	 * Some boards have DTR and DCD implemented using PIO pins,
> > >  	 * code to do this should be hooked in here.
> > >  	 */
> > > +
> > > +	gpiod_set_value(ascport->rts, mctrl & TIOCM_RTS);
> 
> This now puts the code and the comment above out of sync with each
> other.
> 
> However just checking the stih410 datasheet and I don't think this patch
> to control RTS via a GPIO is required anyway.
> 
> The correct way of handling this is to add UART10_RTS and UART10_CTS pins
> to the pinctrl_serial0 group so they are properly configured for their cts/rts
> alternate function. Once the pins are correctly configured, the IP block should
> control the signals correctly like the comment says.

That was the first thing I tried.  It didn't work.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [GIT PULL] ARM: Xilinx Zynq SOC changes for v4.10
From: Michal Simek @ 2016-12-06 12:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

please pull this fix to your tree.

Thanks,
Michal


The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

  Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)

are available in the git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynq-soc-for-4.10

for you to fetch changes up to 7a3cc2a7b2c723aa552028f4e66841cec183756d:

  ARM: zynq: Reserve correct amount of non-DMA RAM (2016-11-14 16:07:58
+0100)

----------------------------------------------------------------
arm: Xilinx Zynq patches for v4.10

- Fix dma issue

----------------------------------------------------------------
Kyle Roeschley (1):
      ARM: zynq: Reserve correct amount of non-DMA RAM

 arch/arm/mach-zynq/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP SoCs


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161206/773ac815/attachment-0001.sig>

^ permalink raw reply

* [STLinux Kernel] [PATCH 2/3] serial: st-asc: Provide RTS functionality
From: Lee Jones @ 2016-12-06 12:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206124543.GC25385@dell.home>

On Tue, 06 Dec 2016, Lee Jones wrote:

> On Tue, 06 Dec 2016, Peter Griffin wrote:
> > On Mon, 05 Dec 2016, Patrice Chotard wrote:
> > > On 12/02/2016 03:11 PM, Lee Jones wrote:
> > > > Until this point, it has not been possible for serial applications
> > > > to toggle the UART RTS line.  This can be useful with certain
> > > > configurations. For example, when using a Mezzanine on a Linaro
> > > > 96board, RTS line is used to take the the on-board microcontroller
> > > 
> > > typo "the the on"
> > > 
> > > > in and out of reset.
> > > > 
> > > > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > > > ---
> > > >  drivers/tty/serial/st-asc.c | 14 ++++++++++++++
> > > >  1 file changed, 14 insertions(+)
> > > > 
> > > > diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
> > > > index 379e5bd..ce46898 100644
> > > > --- a/drivers/tty/serial/st-asc.c
> > > > +++ b/drivers/tty/serial/st-asc.c
> > > > @@ -30,6 +30,7 @@
> > > >  #include <linux/of_platform.h>
> > > >  #include <linux/serial_core.h>
> > > >  #include <linux/clk.h>
> > > > +#include <linux/gpio/consumer.h>
> > > >  
> > > >  #define DRIVER_NAME "st-asc"
> > > >  #define ASC_SERIAL_NAME "ttyAS"
> > > > @@ -38,6 +39,7 @@
> > > >  
> > > >  struct asc_port {
> > > >  	struct uart_port port;
> > > > +	struct gpio_desc *rts;
> > > >  	struct clk *clk;
> > > >  	unsigned int hw_flow_control:1;
> > > >  	unsigned int force_m1:1;
> > > > @@ -381,12 +383,16 @@ static unsigned int asc_tx_empty(struct uart_port *port)
> > > >  
> > > >  static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl)
> > > >  {
> > > > +	struct asc_port *ascport = to_asc_port(port);
> > > > +
> > > >  	/*
> > > >  	 * This routine is used for seting signals of: DTR, DCD, CTS/RTS
> > > >  	 * We use ASC's hardware for CTS/RTS, so don't need any for that.
> > > >  	 * Some boards have DTR and DCD implemented using PIO pins,
> > > >  	 * code to do this should be hooked in here.
> > > >  	 */
> > > > +
> > > > +	gpiod_set_value(ascport->rts, mctrl & TIOCM_RTS);
> > 
> > This now puts the code and the comment above out of sync with each
> > other.
> > 
> > However just checking the stih410 datasheet and I don't think this patch
> > to control RTS via a GPIO is required anyway.
> > 
> > The correct way of handling this is to add UART10_RTS and UART10_CTS pins
> > to the pinctrl_serial0 group so they are properly configured for their cts/rts
> > alternate function. Once the pins are correctly configured, the IP block should
> > control the signals correctly like the comment says.
> 
> That was the first thing I tried.  It didn't work.

       cts = <&pio17 2 ALT1 IN>;
       rts = <&pio17 3 ALT1 OUT>;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [GIT PULL] ARM: Xilinx Zynq DT changes for v4.10
From: Michal Simek @ 2016-12-06 12:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0eeda910-d585-d532-96c6-5c0cc634627c@monstr.eu>

Hi,

On 6.12.2016 13:40, Michal Simek wrote:
> Hi,
> 
> please add these changes to your arm-soc repo.
> It fixes dtc warnings, small coding style changes and add support for
> Microzed.
> 
> Thanks,
> Michal
> 
> The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
> 
>   Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
> 
> are available in the git repository at:
> 
>   https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-dt-for-4.10


please ignore this one - patches are good but I used incorrect tag name
here because this is for zynq not for zynqmp.
Sorry for that will send v2.

Thanks,
Michal
-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP SoCs


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161206/bc941f7b/attachment.sig>

^ permalink raw reply

* [GIT PULL v2] ARM: Xilinx Zynq DT changes for v4.10
From: Michal Simek @ 2016-12-06 12:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

please add these changes to your arm-soc repo.
It fixes dtc warnings, small coding style changes and add support for
Microzed.

Thanks,
Michal

---
v2: Use correct zynq-dt-for-4.10 tag instead of zynqmp-dt-for-4.10.


The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

  Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)

are available in the git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynq-dt-for-4.10

for you to fetch changes up to df2f3c48b9cd51e2612a1598342769d09d849f39:

  arm: dts: zynq: Add MicroZed board support (2016-12-06 13:17:39 +0100)

----------------------------------------------------------------
arm: Xilinx Zynq dt patches for v4.10

- Remove skeleton.dtsi
- Fix DTC warnings
- Coding style changes
- Microzed support

----------------------------------------------------------------
Jagan Teki (1):
      arm: dts: zynq: Add MicroZed board support

Michal Simek (3):
      ARM: zynq: Remove skeleton.dtsi
      ARM: zynq: Fix W=1 dtc 1.4 warnings
      ARM: zynq: Fix pmu register description coding style

 arch/arm/boot/dts/Makefile            |  1 +
 arch/arm/boot/dts/zynq-7000.dtsi      | 10 +++++---
 arch/arm/boot/dts/zynq-microzed.dts   | 96
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/zynq-parallella.dts |  2 +-
 arch/arm/boot/dts/zynq-zc702.dts      |  2 +-
 arch/arm/boot/dts/zynq-zc706.dts      |  2 +-
 arch/arm/boot/dts/zynq-zed.dts        |  2 +-
 arch/arm/boot/dts/zynq-zybo.dts       |  2 +-
 8 files changed, 108 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm/boot/dts/zynq-microzed.dts


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP SoCs


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161206/76407ade/attachment.sig>

^ permalink raw reply

* [PATCH v3 7/7] ARM: dts: stm32: add stm32 general purpose timer driver in DT
From: Lee Jones @ 2016-12-06 12:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8f881cf7-ba63-315f-b852-71869ad480f3@st.com>

On Tue, 06 Dec 2016, Alexandre Torgue wrote:
> On 12/06/2016 10:48 AM, Lee Jones wrote:
> > On Mon, 05 Dec 2016, Alexandre Torgue wrote:
> > > On 12/02/2016 02:22 PM, Lee Jones wrote:
> > > > On Fri, 02 Dec 2016, Benjamin Gaignard wrote:
> > > > 
> > > > > Add general purpose timers and it sub-nodes into DT for stm32f4.
> > > > > Define and enable pwm1 and pwm3 for stm32f469 discovery board
> > > > > 
> > > > > version 3:
> > > > > - use "st,stm32-timer-trigger" in DT
> > > > > 
> > > > > version 2:
> > > > > - use parameters to describe hardware capabilities
> > > > > - do not use references for pwm and iio timer subnodes
> > > > > 
> > > > > Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> > > > > ---
> > > > >  arch/arm/boot/dts/stm32f429.dtsi      | 333 +++++++++++++++++++++++++++++++++-
> > > > >  arch/arm/boot/dts/stm32f469-disco.dts |  28 +++
> > > > >  2 files changed, 360 insertions(+), 1 deletion(-)
> > 
> > [...]
> > 
> > If you're only commenting on a little piece of the patch, it's always
> > a good idea to trim the rest.
> > 
> > > > > diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
> > > > > index 8a163d7..df4ca7e 100644
> > > > > --- a/arch/arm/boot/dts/stm32f469-disco.dts
> > > > > +++ b/arch/arm/boot/dts/stm32f469-disco.dts
> > > > > @@ -81,3 +81,31 @@
> > > > >  &usart3 {
> > > > >  	status = "okay";
> > > > >  };
> > > > > +
> > > > > +&gptimer1 {
> > > > > +	status = "okay";
> > > > > +
> > > > > +	pwm1 at 0 {
> > > > > +		pinctrl-0	= <&pwm1_pins>;
> > > > > +		pinctrl-names	= "default";
> > > > > +		status = "okay";
> > > > > +	};
> > > > > +
> > > > > +	timer1 at 0 {
> > > > > +		status = "okay";
> > > > > +	};
> > > > > +};
> > > > 
> > > > This is a much *better* format than before.
> > > > 
> > > > I still don't like the '&' syntax though.
> > > 
> > > Please keep "&" format to match with existing nodes.
> > 
> > Right.  I wasn't suggesting that he differs from the current format in
> > *this* set.  I am suggesting that we change the format in a subsequent
> > set though.
> 
> Why change? Looking at Linux ARM kernel patchwork, new DT board file
> contains this format. Did you already discuss with Arnd or Olof about it ?

Because the syntax is horrible.  It removes any indication of
hierarchy and insists all nodes include labels that would otherwise be
unnecessary.

The syntax is approved, so there is no issue with Arnd/Olof, nor the
DT Maintainers.  The decision is left to the sub-arch maintainer to
choose to use it or not.  My vote (which doesn't really count for
anything in this scenario) is to not use it for the aforementioned
reasons.

> > > > > +&gptimer3 {
> > > > > +	status = "okay";
> > > > > +
> > > > > +	pwm3 at 0 {
> > > > > +		pinctrl-0	= <&pwm3_pins>;
> > > > > +		pinctrl-names	= "default";
> > > > > +		status = "okay";
> > > > > +	};
> > > > > +
> > > > > +	timer3 at 0 {
> > > > > +		status = "okay";
> > > > > +	};
> > > > > +};
> > > > 
> > 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v4 7/7] ARM: dts: stm32: add STM32 General Purpose Timer driver in DT
From: Lee Jones @ 2016-12-06 12:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481027929-13704-8-git-send-email-benjamin.gaignard@st.com>

On Tue, 06 Dec 2016, Benjamin Gaignard wrote:

> Add General Purpose Timers and it sub-nodes into DT for stm32f4.
> Define and enable pwm1 and pwm3 for stm32f469 discovery board
> 
> version 4:
> - remove unwanted indexing in pwm@ and timer@ node name
> - use "reg" instead of additional parameters to set timer
>   configuration
> 
> version 3:
> - use "st,stm32-timer-trigger" in DT
> 
> version 2:
> - use parameters to describe hardware capabilities
> - do not use references for pwm and iio timer subnodes
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> ---
>  arch/arm/boot/dts/stm32f429.dtsi      | 276 +++++++++++++++++++++++++++++++++-
>  arch/arm/boot/dts/stm32f469-disco.dts |  28 ++++
>  2 files changed, 303 insertions(+), 1 deletion(-)

This now looks really neat.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v4 1/7] MFD: add bindings for STM32 General Purpose Timer driver
From: Lee Jones @ 2016-12-06 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481027929-13704-2-git-send-email-benjamin.gaignard@st.com>

On Tue, 06 Dec 2016, Benjamin Gaignard wrote:

> Add bindings information for STM32 General Purpose Timer
> 
> version 2:
> - rename stm32-mfd-timer to stm32-gptimer
> - only keep one compatible string
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> ---
>  .../bindings/mfd/stm32-general-purpose-timer.txt   | 39 ++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt b/Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt
> new file mode 100644
> index 0000000..e92c8be
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt
> @@ -0,0 +1,39 @@
> +STM32 General Purpose Timer driver bindings
> +
> +Required parameters:
> +- compatible: must be "st,stm32-gptimer"
> +
> +- reg:			Physical base address and length of the controller's
> +			registers.
> +- clock-names: 		Set to "clk_int".
> +- clocks: 		Phandle to the clock used by the timer module.
> +			For Clk properties, please refer to ../clock/clock-bindings.txt
> +
> +Optional parameters:
> +- resets:		Phandle to the parent reset controller.
> +			See ../reset/st,stm32-rcc.txt
> +
> +Optional subnodes:
> +- pwm:			See ../pwm/pwm-stm32.txt
> +- timer:		See ../iio/timer/stm32-timer-trigger.txt
> +
> +Example:
> +	gptimer at 40010000 {

I'm not going to push too hard, but I still thing "advanced-control"
would suit better, since this is not *just* a timer.  In fact, the
parent device (the MFD) doesn't have any timer functionality.  That's
what "timer at 0" does.

The IP is called "Advanced Control" in the datasheet, no?

> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		compatible = "st,stm32-gptimer";
> +		reg = <0x40010000 0x400>;
> +		clocks = <&rcc 0 160>;
> +		clock-names = "clk_int";
> +
> +		pwm at 0 {
> +			compatible = "st,stm32-pwm";
> +			pinctrl-0	= <&pwm1_pins>;
> +			pinctrl-names	= "default";
> +		};
> +
> +		timer at 0 {
> +			compatible = "st,stm32-timer-trigger";
> +			reg = <0>;
> +		};
> +	};

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v3 1/2] ARM: dts: da850-lcdk: add the dumb-vga-dac node
From: Bartosz Golaszewski @ 2016-12-06 13:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a2159347-1cd7-18b1-626a-fe6a272ba85c@ti.com>

2016-12-05 13:49 GMT+01:00 Tomi Valkeinen <tomi.valkeinen@ti.com>:
> On 29/11/16 13:57, Bartosz Golaszewski wrote:
>> Add the dumb-vga-dac node to the board DT together with corresponding
>> ports and vga connector. This allows to retrieve the edid info from
>> the display automatically.
>>
>
> It's a bit difficult to follow this as there's been so many patches
> going around. But I take the above is the LCDC node in the base da850
> dtsi file? In that case, what is the display_in supposed to present?
> It's the first node in the "display chain", so it has no input.
>
> Also, don't touch da850.dtsi here, just add the "ports" node in the
> da850-lcdk.dts file.
>
> If the da850.dtsi has not been merged yet, I'd change the name of the
> lcdc node to something else than "display". It's rather vague. If it's
> named "lcdc", reading da850-lcdk.dts becomes much easier, as you'll
> refer to "lcdc".
>

The node is already in Sekhar's branch.

Thanks,
Bartosz

^ permalink raw reply

* [STLinux Kernel] [PATCH 2/3] serial: st-asc: Provide RTS functionality
From: Peter Griffin @ 2016-12-06 13:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206124808.GD25385@dell.home>

Hi Lee,

On Tue, 06 Dec 2016, Lee Jones wrote:

> On Tue, 06 Dec 2016, Lee Jones wrote:
> 
> > On Tue, 06 Dec 2016, Peter Griffin wrote:
> > > On Mon, 05 Dec 2016, Patrice Chotard wrote:
> > > > On 12/02/2016 03:11 PM, Lee Jones wrote:
> > > > > Until this point, it has not been possible for serial applications
> > > > > to toggle the UART RTS line.  This can be useful with certain
> > > > > configurations. For example, when using a Mezzanine on a Linaro
> > > > > 96board, RTS line is used to take the the on-board microcontroller
> > > > 
> > > > typo "the the on"
> > > > 
> > > > > in and out of reset.
> > > > > 
> > > > > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > > > > ---
> > > > >  drivers/tty/serial/st-asc.c | 14 ++++++++++++++
> > > > >  1 file changed, 14 insertions(+)
> > > > > 
> > > > > diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
> > > > > index 379e5bd..ce46898 100644
> > > > > --- a/drivers/tty/serial/st-asc.c
> > > > > +++ b/drivers/tty/serial/st-asc.c
> > > > > @@ -30,6 +30,7 @@
> > > > >  #include <linux/of_platform.h>
> > > > >  #include <linux/serial_core.h>
> > > > >  #include <linux/clk.h>
> > > > > +#include <linux/gpio/consumer.h>
> > > > >  
> > > > >  #define DRIVER_NAME "st-asc"
> > > > >  #define ASC_SERIAL_NAME "ttyAS"
> > > > > @@ -38,6 +39,7 @@
> > > > >  
> > > > >  struct asc_port {
> > > > >  	struct uart_port port;
> > > > > +	struct gpio_desc *rts;
> > > > >  	struct clk *clk;
> > > > >  	unsigned int hw_flow_control:1;
> > > > >  	unsigned int force_m1:1;
> > > > > @@ -381,12 +383,16 @@ static unsigned int asc_tx_empty(struct uart_port *port)
> > > > >  
> > > > >  static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl)
> > > > >  {
> > > > > +	struct asc_port *ascport = to_asc_port(port);
> > > > > +
> > > > >  	/*
> > > > >  	 * This routine is used for seting signals of: DTR, DCD, CTS/RTS
> > > > >  	 * We use ASC's hardware for CTS/RTS, so don't need any for that.
> > > > >  	 * Some boards have DTR and DCD implemented using PIO pins,
> > > > >  	 * code to do this should be hooked in here.
> > > > >  	 */
> > > > > +
> > > > > +	gpiod_set_value(ascport->rts, mctrl & TIOCM_RTS);
> > > 
> > > This now puts the code and the comment above out of sync with each
> > > other.
> > > 
> > > However just checking the stih410 datasheet and I don't think this patch
> > > to control RTS via a GPIO is required anyway.
> > > 
> > > The correct way of handling this is to add UART10_RTS and UART10_CTS pins
> > > to the pinctrl_serial0 group so they are properly configured for their cts/rts
> > > alternate function. Once the pins are correctly configured, the IP block should
> > > control the signals correctly like the comment says.
> > 
> > That was the first thing I tried.  It didn't work.
> 
>        cts = <&pio17 2 ALT1 IN>;
>        rts = <&pio17 3 ALT1 OUT>;
>

That implies that either some additional configuration of the IP is required in
st-asc to get the IP to control those signals or that there is a bug in the
ST pinctrl driver and the correct settings aren't being applied.

regards,

Peter.

^ permalink raw reply

* [PATCH v4 2/7] MFD: add STM32 General Purpose Timer driver
From: Lee Jones @ 2016-12-06 13:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481027929-13704-3-git-send-email-benjamin.gaignard@st.com>

This is really starting to come together.

Couple of nits to tend to and you'll be all set.

> This hardware block could at used at same time for PWM generation
> and IIO timers.
> PWM and IIO timer configuration are mixed in the same registers
> so we need a multi fonction driver to be able to share those registers.
> 
> version 4:
> - add a function to detect Auto Reload Register (ARR) size
> - rename the structure shared with other drivers
> 
> version 2:
> - rename driver "stm32-gptimer" to be align with SoC documentation
> - only keep one compatible
> - use of_platform_populate() instead of devm_mfd_add_devices()
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> ---
>  drivers/mfd/Kconfig               | 11 ++++++
>  drivers/mfd/Makefile              |  2 +
>  drivers/mfd/stm32-gptimer.c       | 82 +++++++++++++++++++++++++++++++++++++++

This is not a timer.

>  include/linux/mfd/stm32-gptimer.h | 63 ++++++++++++++++++++++++++++++
>  4 files changed, 158 insertions(+)
>  create mode 100644 drivers/mfd/stm32-gptimer.c
>  create mode 100644 include/linux/mfd/stm32-gptimer.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index c6df644..a00f6b3 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1607,6 +1607,17 @@ config MFD_STW481X
>  	  in various ST Microelectronics and ST-Ericsson embedded
>  	  Nomadik series.
>  
> +config MFD_STM32_GP_TIMER
> +	tristate "Support for STM32 General Purpose Timer"

... but it's not though is it.  This is the parent device whose
children are a PWM and a Timer.

> +	select MFD_CORE
> +	select REGMAP
> +	depends on ARCH_STM32 || COMPILE_TEST
> +	depends on OF

Shouldn't this be:

	depends on (ARCH_STM32 && OF) || COMPILE_TEST
	
> +	help
> +	  Select this option to enable STM32 general purpose timer
> +	  driver used for PWM and IIO Timer. This driver allow to
> +	  share the registers between the others drivers.
> +
>  menu "Multimedia Capabilities Port drivers"
>  	depends on ARCH_SA1100
>  
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 9834e66..86353b9 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -211,3 +211,5 @@ obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
>  obj-$(CONFIG_MFD_MT6397)	+= mt6397-core.o
>  
>  obj-$(CONFIG_MFD_ALTERA_A10SR)	+= altera-a10sr.o
> +
> +obj-$(CONFIG_MFD_STM32_GP_TIMER) 	+= stm32-gptimer.o
> diff --git a/drivers/mfd/stm32-gptimer.c b/drivers/mfd/stm32-gptimer.c
> new file mode 100644
> index 0000000..6747fcb
> --- /dev/null
> +++ b/drivers/mfd/stm32-gptimer.c
> @@ -0,0 +1,82 @@
> +/*
> + * Copyright (C) STMicroelectronics 2016
> + *
> + * Author: Benjamin Gaignard <benjamin.gaignard@st.com>

Nit: '\n' here.

> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/reset.h>
> +
> +#include <linux/mfd/stm32-gptimer.h>

Nit: Why does this need to be separate?

> +static const struct regmap_config stm32_gptimer_regmap_cfg = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = sizeof(u32),
> +	.max_register = 0x400,
> +};
> +
> +static u32 stm32_gptimer_get_arr_size(struct regmap *regmap)
> +{
> +	u32 max_arr;
> +
> +	/* Only the available bits will be written so when readback
> +	 * we get the maximum value of auto reload register
> +	 */

Incorrect format for a multi-line comment in Linux.

> +	regmap_write(regmap, TIM_ARR, ~0L);
> +	regmap_read(regmap, TIM_ARR, &max_arr);
> +	regmap_write(regmap, TIM_ARR, 0x0);
> +
> +	return max_arr;
> +}
> +
> +static int stm32_gptimer_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct stm32_gptimer *ddata;
> +	struct resource *res;
> +	void __iomem *mmio;
> +
> +	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
> +	if (!ddata)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	mmio = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(mmio))
> +		return PTR_ERR(mmio);
> +
> +	ddata->regmap = devm_regmap_init_mmio_clk(dev, "clk_int", mmio,
> +						  &stm32_gptimer_regmap_cfg);
> +	if (IS_ERR(ddata->regmap))
> +		return PTR_ERR(ddata->regmap);
> +
> +	ddata->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(ddata->clk))
> +		return PTR_ERR(ddata->clk);
> +
> +	ddata->max_arr = stm32_gptimer_get_arr_size(ddata->regmap);

Why don't you pass in ddata, then use regmap and populate max_arr
inside the function.  Then make stm32_gptimer_get_arr_size() void.

> +	platform_set_drvdata(pdev, ddata);
> +
> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
> +}
> +
> +static const struct of_device_id stm32_gptimer_of_match[] = {
> +	{ .compatible = "st,stm32-gptimer" },
> +};
> +MODULE_DEVICE_TABLE(of, stm32_gptimer_of_match);
> +
> +static struct platform_driver stm32_gptimer_driver = {
> +	.probe = stm32_gptimer_probe,
> +	.driver	= {
> +		.name = "stm32-gptimer",
> +		.of_match_table = stm32_gptimer_of_match,
> +	},
> +};
> +module_platform_driver(stm32_gptimer_driver);
> +
> +MODULE_DESCRIPTION("STMicroelectronics STM32 General Purpose Timer");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/mfd/stm32-gptimer.h b/include/linux/mfd/stm32-gptimer.h
> new file mode 100644
> index 0000000..bf0a595
> --- /dev/null
> +++ b/include/linux/mfd/stm32-gptimer.h
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright (C) STMicroelectronics 2016
> + *
> + * Author: Benjamin Gaignard <benjamin.gaignard@st.com>

Nit: '\n'

> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#ifndef _LINUX_STM32_GPTIMER_H_
> +#define _LINUX_STM32_GPTIMER_H_
> +
> +#include <linux/clk.h>
> +#include <linux/regmap.h>
> +
> +#define TIM_CR1		0x00	/* Control Register 1      */
> +#define TIM_CR2		0x04	/* Control Register 2      */
> +#define TIM_SMCR	0x08	/* Slave mode control reg  */
> +#define TIM_DIER	0x0C	/* DMA/interrupt register  */
> +#define TIM_SR		0x10	/* Status register	   */
> +#define TIM_EGR		0x14	/* Event Generation Reg    */
> +#define TIM_CCMR1	0x18	/* Capt/Comp 1 Mode Reg    */
> +#define TIM_CCMR2	0x1C	/* Capt/Comp 2 Mode Reg    */
> +#define TIM_CCER	0x20	/* Capt/Comp Enable Reg    */
> +#define TIM_PSC		0x28	/* Prescaler               */
> +#define TIM_ARR		0x2c	/* Auto-Reload Register    */
> +#define TIM_CCR1	0x34	/* Capt/Comp Register 1    */
> +#define TIM_CCR2	0x38	/* Capt/Comp Register 2    */
> +#define TIM_CCR3	0x3C	/* Capt/Comp Register 3    */
> +#define TIM_CCR4	0x40	/* Capt/Comp Register 4    */
> +#define TIM_BDTR	0x44	/* Break and Dead-Time Reg */
> +
> +#define TIM_CR1_CEN	BIT(0)	/* Counter Enable	   */
> +#define TIM_CR1_ARPE	BIT(7)	/* Auto-reload Preload Ena */
> +#define TIM_CR2_MMS	(BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */
> +#define TIM_SMCR_SMS	(BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
> +#define TIM_SMCR_TS	(BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
> +#define TIM_DIER_UIE	BIT(0)	/* Update interrupt	   */
> +#define TIM_SR_UIF	BIT(0)	/* Update interrupt flag   */
> +#define TIM_EGR_UG	BIT(0)	/* Update Generation       */
> +#define TIM_CCMR_PE	BIT(3)	/* Channel Preload Enable  */
> +#define TIM_CCMR_M1	(BIT(6) | BIT(5))  /* Channel PWM Mode 1 */
> +#define TIM_CCER_CC1E	BIT(0)	/* Capt/Comp 1  out Ena    */
> +#define TIM_CCER_CC1P	BIT(1)	/* Capt/Comp 1  Polarity   */
> +#define TIM_CCER_CC1NE	BIT(2)	/* Capt/Comp 1N out Ena    */
> +#define TIM_CCER_CC1NP	BIT(3)	/* Capt/Comp 1N Polarity   */
> +#define TIM_CCER_CC2E	BIT(4)	/* Capt/Comp 2  out Ena    */
> +#define TIM_CCER_CC3E	BIT(8)	/* Capt/Comp 3  out Ena    */
> +#define TIM_CCER_CC4E	BIT(12)	/* Capt/Comp 4  out Ena    */
> +#define TIM_CCER_CCXE	(BIT(0) | BIT(4) | BIT(8) | BIT(12))
> +#define TIM_BDTR_BKE	BIT(12) /* Break input enable	   */
> +#define TIM_BDTR_BKP	BIT(13) /* Break input polarity	   */
> +#define TIM_BDTR_AOE	BIT(14)	/* Automatic Output Enable */
> +#define TIM_BDTR_MOE	BIT(15)	/* Main Output Enable      */
> +
> +#define MAX_TIM_PSC		0xFFFF
> +#define TIM_CR2_MMS_SHIFT	4
> +#define TIM_SMCR_TS_SHIFT	4
> +
> +struct stm32_gptimer {
> +	struct clk *clk;
> +	struct regmap *regmap;
> +	u32 max_arr;
> +};
> +#endif

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v3] KVM: arm/arm64: Access CNTHCTL_EL2 bit fields correctly
From: Marc Zyngier @ 2016-12-06 13:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206121617.GB3681@cbox>

On 06/12/16 12:16, Christoffer Dall wrote:
> On Tue, Dec 06, 2016 at 01:12:21PM +0100, Christoffer Dall wrote:
>> On Tue, Dec 06, 2016 at 11:17:40AM +0000, Marc Zyngier wrote:
>>> On 01/12/16 19:32, Jintack Lim wrote:
>>>> Current KVM world switch code is unintentionally setting wrong bits to
>>>> CNTHCTL_EL2 when E2H == 1, which may allow guest OS to access physical
>>>> timer.  Bit positions of CNTHCTL_EL2 are changing depending on
>>>> HCR_EL2.E2H bit.  EL1PCEN and EL1PCTEN are 1st and 0th bits when E2H is
>>>> not set, but they are 11th and 10th bits respectively when E2H is set.
>>>>
>>>> In fact, on VHE we only need to set those bits once, not for every world
>>>> switch. This is because the host kernel runs in EL2 with HCR_EL2.TGE ==
>>>> 1, which makes those bits have no effect for the host kernel execution.
>>>> So we just set those bits once for guests, and that's it.
>>>>
>>>> Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
>>>> ---
>>>> v2->v3: 
>>>> - Perform the initialization including CPU hotplug case.
>>>> - Move has_vhe() to asm/virt.h
>>>>
>>>> v1->v2: 
>>>> - Skip configuring cnthctl_el2 in world switch path on VHE system.
>>>> - Write patch based on linux-next.
>>>> ---
>>>>  arch/arm/include/asm/virt.h   |  5 +++++
>>>>  arch/arm/kvm/arm.c            |  3 +++
>>>>  arch/arm64/include/asm/virt.h | 10 ++++++++++
>>>>  include/kvm/arm_arch_timer.h  |  1 +
>>>>  virt/kvm/arm/arch_timer.c     | 23 +++++++++++++++++++++++
>>>>  virt/kvm/arm/hyp/timer-sr.c   | 33 +++++++++++++++++++++------------
>>>>  6 files changed, 63 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
>>>> index a2e75b8..6dae195 100644
>>>> --- a/arch/arm/include/asm/virt.h
>>>> +++ b/arch/arm/include/asm/virt.h
>>>> @@ -80,6 +80,11 @@ static inline bool is_kernel_in_hyp_mode(void)
>>>>  	return false;
>>>>  }
>>>>  
>>>> +static inline bool has_vhe(void)
>>>> +{
>>>> +	return false;
>>>> +}
>>>> +
>>>>  /* The section containing the hypervisor idmap text */
>>>>  extern char __hyp_idmap_text_start[];
>>>>  extern char __hyp_idmap_text_end[];
>>>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>>>> index 8f92efa..13e54e8 100644
>>>> --- a/arch/arm/kvm/arm.c
>>>> +++ b/arch/arm/kvm/arm.c
>>>> @@ -1099,6 +1099,9 @@ static void cpu_init_hyp_mode(void *dummy)
>>>>  	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
>>>>  	__cpu_init_stage2();
>>>>  
>>>> +	if (is_kernel_in_hyp_mode())
>>>> +		kvm_timer_init_vhe();
>>>> +
>>>>  	kvm_arm_init_debug();
>>>>  }
>>>>  
>>>> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
>>>> index fea1073..b043cfd 100644
>>>> --- a/arch/arm64/include/asm/virt.h
>>>> +++ b/arch/arm64/include/asm/virt.h
>>>> @@ -47,6 +47,7 @@
>>>>  #include <asm/ptrace.h>
>>>>  #include <asm/sections.h>
>>>>  #include <asm/sysreg.h>
>>>> +#include <asm/cpufeature.h>
>>>>  
>>>>  /*
>>>>   * __boot_cpu_mode records what mode CPUs were booted in.
>>>> @@ -80,6 +81,15 @@ static inline bool is_kernel_in_hyp_mode(void)
>>>>  	return read_sysreg(CurrentEL) == CurrentEL_EL2;
>>>>  }
>>>>  
>>>> +static inline bool has_vhe(void)
>>>> +{
>>>> +#ifdef CONFIG_ARM64_VHE
>>>
>>> Is there a particular reason why this should be guarded by a #ifdef? All
>>> the symbols should always be available, and since this is a static key,
>>> the overhead should be really insignificant (provided that you use a
>>> non-prehistoric compiler...).
>>>
>>
>> Isn't this code called from a file shared between 32-bit arm and arm64?
>> Does the cpus_have_const_cap work on ARM64?
> 
> Duh, I meant on 32-bit arm of course.

Well, this is a pure 64bit file - 32bit has the canonical implementation
that always returns false. So I can't really see how this can ever break
32bit. Unless my lack of sleep is really showing, and I'm missing
something terribly obvious?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH v4 0/2] ARM: dts: da850: tilcdc related DT changes
From: Bartosz Golaszewski @ 2016-12-06 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

This series contains the last DT changes required for LCDC support
on da850-lcdk. The first one adds the dumb-vga-dac nodes, the second
limits the maximum pixel clock rate.

v1 -> v2:
- drop patch 3/3 (already merged)
- use max-pixelclock instead of max-bandwidth for display mode limiting

v2 -> v3:
- make the commit message in patch [2/2] more detailed
- move the max-pixelclock property to da850.dtsi as the limit
  affects all da850-based boards

v3 -> v4:
- remove the input port from the display node
- move the display ports node to da850-lcdk.dts
- rename the vga_bridge node to vga-bridge
- move the LCDC pins to the LCDC node (from the vga bridge node)

Bartosz Golaszewski (2):
  ARM: dts: da850-lcdk: add the dumb-vga-dac node
  ARM: dts: da850: specify the maximum pixel clock rate for tilcdc

 arch/arm/boot/dts/da850-lcdk.dts | 69 ++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/da850.dtsi     |  1 +
 2 files changed, 70 insertions(+)

-- 
2.9.3

^ permalink raw reply

* [PATCH v4 1/2] ARM: dts: da850-lcdk: add the dumb-vga-dac node
From: Bartosz Golaszewski @ 2016-12-06 13:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481030026-7329-1-git-send-email-bgolaszewski@baylibre.com>

Add the dumb-vga-dac node to the board DT together with corresponding
ports and vga connector. This allows to retrieve the edid info from
the display automatically.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/boot/dts/da850-lcdk.dts | 69 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index afcb482..ca437c1 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -51,6 +51,51 @@
 			system-clock-frequency = <24576000>;
 		};
 	};
+
+	vga-bridge {
+		compatible = "dumb-vga-dac";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+
+				vga_bridge_in: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&display_out_vga>;
+				};
+			};
+
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+
+				vga_bridge_out: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		ddc-i2c-bus = <&i2c0>;
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
 };
 
 &pmx_core {
@@ -236,3 +281,27 @@
 &memctrl {
 	status = "okay";
 };
+
+&display {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd_pins>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		display_out: port at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+	};
+};
+
+&display_out {
+	display_out_vga: endpoint at 0 {
+		reg = <0>;
+		remote-endpoint = <&vga_bridge_in>;
+	};
+};
-- 
2.9.3

^ permalink raw reply related

* [PATCH v4 2/2] ARM: dts: da850: specify the maximum pixel clock rate for tilcdc
From: Bartosz Golaszewski @ 2016-12-06 13:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481030026-7329-1-git-send-email-bgolaszewski@baylibre.com>

At maximum CPU frequency of 300 MHz the maximum pixel clock frequency
is 37.5 MHz[1]. We must filter out any mode for which the calculated
pixel clock rate would exceed this value.

Specify the max-pixelclock property for the display node for
da850-lcdk.

[1] http://processors.wiki.ti.com/index.php/OMAP-L1x/C674x/AM1x_LCD_Controller_(LCDC)_Throughput_and_Optimization_Techniques

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/boot/dts/da850.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index ffc6e1a..da86d80 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -452,6 +452,7 @@
 			compatible = "ti,da850-tilcdc";
 			reg = <0x213000 0x1000>;
 			interrupts = <52>;
+			max-pixelclock = <37500>;
 			status = "disabled";
 		};
 	};
-- 
2.9.3

^ permalink raw reply related

* Tearing down DMA transfer setup after DMA client has finished
From: Måns Rullgård @ 2016-12-06 13:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5846B237.8060409@free.fr>

Mason <slash.tmp@free.fr> writes:

> On 06/12/2016 06:12, Vinod Koul wrote:
>
>> On Tue, Nov 29, 2016 at 07:25:02PM +0100, Mason wrote:
>> 
>>> Is there a way to write a driver within the existing framework?
>> 
>> I think so, looking back at comments from Russell, I do tend to agree with
>> that. Is there a specific reason why sbox can't be tied to alloc and free
>> channels?
>
> Here's a recap of the situation.
>
> The "SBOX+MBUS" HW is used in several iterations of the tango SoC:
>
> tango3
>   2 memory channels available
>   6 devices ("clients"?) may request an MBUS channel
>
> tango4 (one more channel)
>   3 memory channels available
>   7 devices may request an MBUS channel :
>     NFC0, NFC1, SATA0, SATA1, memcpy, (IDE0, IDE1)
>
> Notes:
> The current NFC driver supports only one controller.

I consider that a bug.

> IDE is mostly obsolete at this point.
>
> tango5 (SATA gets own dedicated MBUS channel pair)
>   3 memory channels available
>   5 devices may request an MBUS channel :
>     NFC0, NFC1, memcpy, (IDE0, IDE1)

Some of the chip variants can also use this DMA engine for PCI devices.

> If I understand the current DMA driver (written by Mans), client
> drivers are instructed to use a specific channel in the DT, and
> the DMA driver muxes access to that channel.

Almost.  The DT indicates the sbox ID of each device.  The driver
multiplexes requests from all devices across all channels.

> The DMA driver manages a per-channel queue of outstanding DMA transfer
> requests, and a new transfer is started friom within the DMA ISR
> (modulo the fact that the interrupt does not signal completion of the
> transfer, as explained else-thread).

We need to somehow let the device driver signal the dma driver when a
transfer has been fully completed.  Currently the only post-transfer
interaction between the dma engine and the device driver is through the
descriptor callback, which is not suitable for this purpose.

This is starting to look like one of those situations where someone just
needs to implement a solution, or we'll be forever bickering about
hypotheticals.

> What you're proposing, Vinod, is to make a channel exclusive
> to a driver, as long as the driver has not explicitly released
> the channel, via dma_release_channel(), right?

That's not going to work very well.  Device drivers typically request
dma channels in their probe functions or when the device is opened.
This means that reserving one of the few channels there will inevitably
make some other device fail to operate.

Doing a request/release per transfer really doesn't fit with the
intended usage of the dmaengine api.  For starters, what should a driver
do if all the channels are currently busy?

Since the hardware actually does support multiplexing the dma channels,
I think it would be misguided to deliberately cripple the software
support in order to shoehorn it into an incomplete model of how hardware
ought to work.  While I agree it would be nicer if all hardware actually
did work that way, this isn't the reality we're living in.

-- 
M?ns Rullg?rd

^ permalink raw reply

* [PATCH v4 6/7] IIO: add STM32 timer trigger driver
From: Lee Jones @ 2016-12-06 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481027929-13704-7-git-send-email-benjamin.gaignard@st.com>

On Tue, 06 Dec 2016, Benjamin Gaignard wrote:

> Timers IPs can be used to generate triggers for other IPs like
> DAC, ADC or other timers.
> Each trigger may result of timer internals signals like counter enable,
> reset or edge, this configuration could be done through "master_mode"
> device attribute.
> 
> A timer device could be triggered by other timers, we use the trigger
> name and is_stm32_iio_timer_trigger() function to distinguish them
> and configure IP input switch.
> 
> Timer may also decide on which event (edge, level) they could
> be activated by a trigger, this configuration is done by writing in
> "slave_mode" device attribute.
> 
> Since triggers could also be used by DAC or ADC their names are defined
> in include/ nux/iio/timer/stm32-timer-trigger.h so those IPs will be able
> to configure themselves in valid_trigger function
> 
> Trigger have a "sampling_frequency" attribute which allow to configure
> timer sampling frequency without using PWM interface
> 
> version 4:
> - get triggers configuration from "reg" in DT
> - add tables of triggers
> - sampling frequency is enable/disable when writing in trigger
>   sampling_frequency attribute
> - no more use of interruptions
> 
> version 3:
> - change compatible to "st,stm32-timer-trigger"
> - fix attributes access right
> - use string instead of int for master_mode and slave_mode
> - document device attributes in sysfs-bus-iio-timer-stm32
> 
> version 2:
> - keep only one compatible
> - use st,input-triggers-names and st,output-triggers-names
>   to know which triggers are accepted and/or create by the device
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> ---
>  .../ABI/testing/sysfs-bus-iio-timer-stm32          |  55 +++
>  drivers/iio/Kconfig                                |   2 +-
>  drivers/iio/Makefile                               |   1 +
>  drivers/iio/timer/Kconfig                          |  15 +
>  drivers/iio/timer/Makefile                         |   1 +
>  drivers/iio/timer/stm32-timer-trigger.c            | 526 +++++++++++++++++++++
>  drivers/iio/trigger/Kconfig                        |   1 -
>  include/linux/iio/timer/stm32-timer-trigger.h      |  61 +++
>  8 files changed, 660 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
>  create mode 100644 drivers/iio/timer/Kconfig
>  create mode 100644 drivers/iio/timer/Makefile
>  create mode 100644 drivers/iio/timer/stm32-timer-trigger.c
>  create mode 100644 include/linux/iio/timer/stm32-timer-trigger.h
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
> new file mode 100644
> index 0000000..26583dd
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
> @@ -0,0 +1,55 @@
> +What:		/sys/bus/iio/devices/iio:deviceX/master_mode_available
> +KernelVersion:	4.10
> +Contact:	benjamin.gaignard at st.com
> +Description:
> +		Reading returns the list possible master modes which are:
> +		- "reset"     :	The UG bit from the TIMx_EGR register is used as trigger output (TRGO).
> +		- "enable"    : The Counter Enable signal CNT_EN is used as trigger output.
> +		- "update"    : The update event is selected as trigger output.
> +				For instance a master timer can then be used as a prescaler for a slave timer.
> +		- "compare_pulse" : The trigger output send a positive pulse when the CC1IF flag is to be set.
> +		- "OC1REF"    : OC1REF signal is used as trigger output.
> +		- "OC2REF"    : OC2REF signal is used as trigger output.
> +		- "OC3REF"    : OC3REF signal is used as trigger output.
> +		- "OC4REF"    : OC4REF signal is used as trigger output.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/master_mode
> +KernelVersion:	4.10
> +Contact:	benjamin.gaignard at st.com
> +Description:
> +		Reading returns the current master modes.
> +		Writing set the master mode
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/slave_mode_available
> +KernelVersion:	4.10
> +Contact:	benjamin.gaignard at st.com
> +Description:
> +		Reading returns the list possible slave modes which are:
> +		- "disabled"  : The prescaler is clocked directly by the internal clock.
> +		- "encoder_1" : Counter counts up/down on TI2FP1 edge depending on TI1FP2 level.
> +		- "encoder_2" : Counter counts up/down on TI1FP2 edge depending on TI2FP1 level.
> +		- "encoder_3" : Counter counts up/down on both TI1FP1 and TI2FP2 edges depending
> +				on the level of the other input.
> +		- "reset"     : Rising edge of the selected trigger input reinitializes the counter
> +				and generates an update of the registers.
> +		- "gated"     : The counter clock is enabled when the trigger input is high.
> +				The counter stops (but is not reset) as soon as the trigger becomes low.
> +				Both start and stop of the counter are controlled.
> +		- "trigger"   : The counter starts at a rising edge of the trigger TRGI (but it is not
> +				reset). Only the start of the counter is controlled.
> +		- "external_clock": Rising edges of the selected trigger (TRGI) clock the counter.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/slave_mode
> +KernelVersion:	4.10
> +Contact:	benjamin.gaignard at st.com
> +Description:
> +		Reading returns the current slave mode.
> +		Writing set the slave mode
> +
> +What:		/sys/bus/iio/devices/triggerX/sampling_frequency
> +KernelVersion:	4.10
> +Contact:	benjamin.gaignard at st.com
> +Description:
> +		Reading returns the current sampling frequency.
> +		Writing an value different of 0 set and start sampling.
> +		Writing 0 stop sampling.
> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
> index 6743b18..2de2a80 100644
> --- a/drivers/iio/Kconfig
> +++ b/drivers/iio/Kconfig
> @@ -90,5 +90,5 @@ source "drivers/iio/potentiometer/Kconfig"
>  source "drivers/iio/pressure/Kconfig"
>  source "drivers/iio/proximity/Kconfig"
>  source "drivers/iio/temperature/Kconfig"
> -
> +source "drivers/iio/timer/Kconfig"
>  endif # IIO
> diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
> index 87e4c43..b797c08 100644
> --- a/drivers/iio/Makefile
> +++ b/drivers/iio/Makefile
> @@ -32,4 +32,5 @@ obj-y += potentiometer/
>  obj-y += pressure/
>  obj-y += proximity/
>  obj-y += temperature/
> +obj-y += timer/
>  obj-y += trigger/
> diff --git a/drivers/iio/timer/Kconfig b/drivers/iio/timer/Kconfig
> new file mode 100644
> index 0000000..3033869
> --- /dev/null
> +++ b/drivers/iio/timer/Kconfig
> @@ -0,0 +1,15 @@
> +#
> +# Timers drivers
> +
> +menu "Timers"
> +
> +config IIO_STM32_TIMER_TRIGGER
> +	tristate "STM32 Timer Trigger"
> +	depends on ARCH_STM32 || COMPILE_TEST
> +	depends on OF
> +	depends on MFD_STM32_GP_TIMER
> +	select IIO_TRIGGERED_EVENT
> +	help
> +	  Select this option to enable STM32 Timer Trigger
> +
> +endmenu
> diff --git a/drivers/iio/timer/Makefile b/drivers/iio/timer/Makefile
> new file mode 100644
> index 0000000..4ad95ec9
> --- /dev/null
> +++ b/drivers/iio/timer/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_IIO_STM32_TIMER_TRIGGER) += stm32-timer-trigger.o
> diff --git a/drivers/iio/timer/stm32-timer-trigger.c b/drivers/iio/timer/stm32-timer-trigger.c
> new file mode 100644
> index 0000000..58fba33
> --- /dev/null
> +++ b/drivers/iio/timer/stm32-timer-trigger.c
> @@ -0,0 +1,526 @@
> +/*
> + * Copyright (C) STMicroelectronics 2016
> + *
> + * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/iio/timer/stm32-timer-trigger.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/triggered_event.h>
> +#include <linux/interrupt.h>
> +#include <linux/mfd/stm32-gptimer.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +
> +static const char * const triggers0[] = {
> +	TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4, NULL,
> +};
> +
> +static const char * const triggers1[] = {
> +	TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4, NULL,
> +};
> +
> +static const char * const triggers2[] = {
> +	TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4, NULL,
> +};
> +
> +static const char * const triggers3[] = {
> +	TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4, NULL,
> +};
> +
> +static const char * const triggers4[] = {
> +	TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4, NULL,
> +};
> +
> +static const char * const triggers5[] = {
> +	TIM6_TRGO, NULL,
> +};
> +
> +static const char * const triggers6[] = {
> +	TIM7_TRGO, NULL,
> +};
> +
> +static const char * const triggers7[] = {
> +	TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4, NULL,
> +};
> +
> +static const char * const triggers8[] = {
> +	TIM9_TRGO, TIM9_CH1, TIM9_CH2, NULL,
> +};
> +
> +static const char * const triggers9[] = {
> +	TIM12_TRGO, TIM12_CH1, TIM12_CH2, NULL,
> +};
> +
> +static const void *triggers_table[] = {
> +	triggers0,
> +	triggers1,
> +	triggers2,
> +	triggers3,
> +	triggers4,
> +	triggers5,
> +	triggers6,
> +	triggers7,
> +	triggers8,
> +	triggers9,
> +};

What about:

static const char * const triggers[][] = {
	{ TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4, NULL },
	{ TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4, NULL },
	{ TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4, NULL },
	{ TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4, NULL },
	{ TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4, NULL },
	{ TIM6_TRGO, NULL },
	{ TIM7_TRGO, NULL },
	{ TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4, NULL },
	{ TIM9_TRGO, TIM9_CH1, TIM9_CH2, NULL },
	{ TIM12_TRGO, TIM12_CH1, TIM12_CH2, NULL }
};

> +static const char * const valids0[] = {
> +	TIM5_TRGO, TIM2_TRGO, TIM4_TRGO, TIM3_TRGO, NULL,
> +};
> +
> +static const char * const valids1[] = {
> +	TIM1_TRGO, TIM8_TRGO, TIM3_TRGO, TIM4_TRGO, NULL,
> +};
> +
> +static const char * const valids2[] = {
> +	TIM1_TRGO, TIM8_TRGO, TIM5_TRGO, TIM4_TRGO, NULL,
> +};
> +
> +static const char * const valids3[] = {
> +	TIM1_TRGO, TIM2_TRGO, TIM3_TRGO, TIM8_TRGO, NULL,
> +};
> +
> +static const char *const valids4[] = {
> +	TIM2_TRGO, TIM3_TRGO, TIM4_TRGO, TIM8_TRGO, NULL,
> +};
> +
> +static const char * const valids7[] = {
> +	TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO, NULL,
> +};
> +
> +static const char * const valids8[] = {
> +	TIM2_TRGO, TIM3_TRGO, NULL,
> +};
> +
> +static const char * const valids9[] = {
> +	TIM4_TRGO, TIM5_TRGO, NULL,
> +};
> +
> +static const void *valids_table[] = {
> +	valids0,
> +	valids1,
> +	valids2,
> +	valids3,
> +	valids4,
> +	NULL,
> +	NULL,
> +	valids7,
> +	valids8,
> +	valids9,
> +};

Same here.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v9 02/11] arm/arm64: vgic: Add distributor and redistributor access
From: Auger Eric @ 2016-12-06 13:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161128130825.GD18170@cbox>

Hi,

On 28/11/2016 14:08, Christoffer Dall wrote:
> On Wed, Nov 23, 2016 at 06:31:49PM +0530, vijay.kilari at gmail.com wrote:
>> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
>>
>> VGICv3 Distributor and Redistributor registers are accessed using
>> KVM_DEV_ARM_VGIC_GRP_DIST_REGS and KVM_DEV_ARM_VGIC_GRP_REDIST_REGS
>> with KVM_SET_DEVICE_ATTR and KVM_GET_DEVICE_ATTR ioctls.
>> These registers are accessed as 32-bit and cpu mpidr
>> value passed along with register offset is used to identify the
>> cpu for redistributor registers access.
>>
>> The version of VGIC v3 specification is define here
s/define/defined
>> Documentation/virtual/kvm/devices/arm-vgic-v3.txt
>>
>> Also update arch/arm/include/uapi/asm/kvm.h to compile for
>> AArch32 mode.
>>
>> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
>> ---
>>  arch/arm/include/uapi/asm/kvm.h     |   4 +
>>  arch/arm64/include/uapi/asm/kvm.h   |   4 +
>>  virt/kvm/arm/vgic/vgic-kvm-device.c | 144 ++++++++++++++++++++++++++++++++++--
>>  virt/kvm/arm/vgic/vgic-mmio-v2.c    |  16 +---
>>  virt/kvm/arm/vgic/vgic-mmio-v3.c    |  72 ++++++++++++++++++
>>  virt/kvm/arm/vgic/vgic-mmio.c       |  22 ++++++
>>  virt/kvm/arm/vgic/vgic-mmio.h       |   4 +
>>  virt/kvm/arm/vgic/vgic.h            |  49 +++++++++++-
>>  8 files changed, 292 insertions(+), 23 deletions(-)
>>
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
>> index af05f8e..0ae6035 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -181,10 +181,14 @@ struct kvm_arch_memory_slot {
>>  #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS	2
>>  #define   KVM_DEV_ARM_VGIC_CPUID_SHIFT	32
>>  #define   KVM_DEV_ARM_VGIC_CPUID_MASK	(0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
>> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
>> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
>> +			(0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
>>  #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT	0
>>  #define   KVM_DEV_ARM_VGIC_OFFSET_MASK	(0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
>>  #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS	3
>>  #define KVM_DEV_ARM_VGIC_GRP_CTRL       4
>> +#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
>>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT    0
>>  
>>  /* KVM_IRQ_LINE irq field index values */
>> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
>> index 3051f86..56dc08d 100644
>> --- a/arch/arm64/include/uapi/asm/kvm.h
>> +++ b/arch/arm64/include/uapi/asm/kvm.h
>> @@ -201,10 +201,14 @@ struct kvm_arch_memory_slot {
>>  #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS	2
>>  #define   KVM_DEV_ARM_VGIC_CPUID_SHIFT	32
>>  #define   KVM_DEV_ARM_VGIC_CPUID_MASK	(0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
>> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
>> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
>> +			(0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
>>  #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT	0
>>  #define   KVM_DEV_ARM_VGIC_OFFSET_MASK	(0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
>>  #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS	3
>>  #define KVM_DEV_ARM_VGIC_GRP_CTRL	4
>> +#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
>>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT	0
>>  
>>  /* Device Control API on vcpu fd */
>> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> index fbe87a6..bc7de95 100644
>> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
>> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> @@ -235,7 +235,7 @@ struct vgic_reg_attr {
>>  	gpa_t addr;
>>  };
>>  
>> -static int parse_vgic_v2_attr(struct kvm_device *dev,
>> +static int vgic_v2_parse_attr(struct kvm_device *dev,
>>  			      struct kvm_device_attr *attr,
>>  			      struct vgic_reg_attr *reg_attr)
>>  {
>> @@ -292,14 +292,14 @@ static bool lock_all_vcpus(struct kvm *kvm)
>>  }
>>  
>>  /**
>> - * vgic_attr_regs_access_v2 - allows user space to access VGIC v2 state
>> + * vgic_v2_attr_regs_access - allows user space to access VGIC v2 state
>>   *
>>   * @dev:      kvm device handle
>>   * @attr:     kvm device attribute
>>   * @reg:      address the value is read or written
>>   * @is_write: true if userspace is writing a register
>>   */
>> -static int vgic_attr_regs_access_v2(struct kvm_device *dev,
>> +static int vgic_v2_attr_regs_access(struct kvm_device *dev,
>>  				    struct kvm_device_attr *attr,
>>  				    u32 *reg, bool is_write)
>>  {
>> @@ -308,7 +308,7 @@ static int vgic_attr_regs_access_v2(struct kvm_device *dev,
>>  	struct kvm_vcpu *vcpu;
>>  	int ret;
>>  
>> -	ret = parse_vgic_v2_attr(dev, attr, &reg_attr);
>> +	ret = vgic_v2_parse_attr(dev, attr, &reg_attr);
>>  	if (ret)
>>  		return ret;
>>  
>> @@ -362,7 +362,7 @@ static int vgic_v2_set_attr(struct kvm_device *dev,
>>  		if (get_user(reg, uaddr))
>>  			return -EFAULT;
>>  
>> -		return vgic_attr_regs_access_v2(dev, attr, &reg, true);
>> +		return vgic_v2_attr_regs_access(dev, attr, &reg, true);
>>  	}
>>  	}
>>  
>> @@ -384,7 +384,7 @@ static int vgic_v2_get_attr(struct kvm_device *dev,
>>  		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
>>  		u32 reg = 0;
>>  
>> -		ret = vgic_attr_regs_access_v2(dev, attr, &reg, false);
>> +		ret = vgic_v2_attr_regs_access(dev, attr, &reg, false);
>>  		if (ret)
>>  			return ret;
>>  		return put_user(reg, uaddr);
>> @@ -428,16 +428,141 @@ struct kvm_device_ops kvm_arm_vgic_v2_ops = {
>>  	.has_attr = vgic_v2_has_attr,
>>  };
>>  
>> +static int vgic_v3_parse_attr(struct kvm_device *dev,
>> +			      struct kvm_device_attr *attr,
>> +			      struct vgic_reg_attr *reg_attr)
>> +{
>> +	unsigned long vgic_mpidr, mpidr_reg;
>> +
>> +	vgic_mpidr = (attr->attr & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) >>
>> +		      KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT;
>> +
>> +	mpidr_reg = VGIC_TO_MPIDR(vgic_mpidr);
>> +	reg_attr->vcpu = kvm_mpidr_to_vcpu(dev->kvm, mpidr_reg);
>> +	if (!reg_attr->vcpu)
>> +		return -EINVAL;
>> +
>> +	reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * vgic_v3_attr_regs_access - allows user space to access VGIC v3 state
>> + *
>> + * @dev:      kvm device handle
>> + * @attr:     kvm device attribute
>> + * @reg:      address the value is read or written
>> + * @is_write: true if userspace is writing a register
>> + */
>> +static int vgic_v3_attr_regs_access(struct kvm_device *dev,
>> +				    struct kvm_device_attr *attr,
>> +				    u64 *reg, bool is_write)
>> +{
>> +	struct vgic_reg_attr reg_attr;
>> +	gpa_t addr;
>> +	struct kvm_vcpu *vcpu;
>> +	int ret;
>> +	u32 tmp32;
>> +
>> +	ret = vgic_v3_parse_attr(dev, attr, &reg_attr);
>> +	if (ret)
>> +		return ret;
>> +
>> +	vcpu = reg_attr.vcpu;
>> +	addr = reg_attr.addr;
>> +
>> +	mutex_lock(&dev->kvm->lock);
>> +
>> +	if (unlikely(!vgic_initialized(dev->kvm))) {
>> +		ret = -EBUSY;
>> +		goto out;
>> +	}
>> +
>> +	if (!lock_all_vcpus(dev->kvm)) {
>> +		ret = -EBUSY;
>> +		goto out;
>> +	}
>> +
>> +	switch (attr->group) {
>> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>> +		if (is_write)
>> +			tmp32 = *reg;
>> +
>> +		ret = vgic_v3_dist_uaccess(vcpu, is_write, addr, &tmp32);
>> +		if (!is_write)
>> +			*reg = tmp32;
>> +		break;
>> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
>> +		if (is_write)
>> +			tmp32 = *reg;
>> +
>> +		ret = vgic_v3_redist_uaccess(vcpu, is_write, addr, &tmp32);
>> +		if (!is_write)
>> +			*reg = tmp32;
>> +		break;
>> +	default:
>> +		ret = -EINVAL;
>> +		break;
>> +	}
>> +
>> +	unlock_all_vcpus(dev->kvm);
>> +out:
>> +	mutex_unlock(&dev->kvm->lock);
>> +	return ret;
>> +}
>> +
>>  static int vgic_v3_set_attr(struct kvm_device *dev,
>>  			    struct kvm_device_attr *attr)
>>  {
>> -	return vgic_set_common_attr(dev, attr);
>> +	int ret;
>> +
>> +	ret = vgic_set_common_attr(dev, attr);
>> +	if (ret != -ENXIO)
>> +		return ret;
>> +
>> +	switch (attr->group) {
>> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: {
>> +		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
>> +		u32 tmp32;
>> +		u64 reg;
>> +
>> +		if (get_user(tmp32, uaddr))
>> +			return -EFAULT;
>> +
>> +		reg = tmp32;
>> +		return vgic_v3_attr_regs_access(dev, attr, &reg, true);
>> +	}
>> +	}
>> +	return -ENXIO;
>>  }
>>  
>>  static int vgic_v3_get_attr(struct kvm_device *dev,
>>  			    struct kvm_device_attr *attr)
>>  {
>> -	return vgic_get_common_attr(dev, attr);
>> +	int ret;
>> +
>> +	ret = vgic_get_common_attr(dev, attr);
>> +	if (ret != -ENXIO)
>> +		return ret;
>> +
>> +	switch (attr->group) {
>> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: {
>> +		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
>> +		u64 reg;
>> +		u32 tmp32;
>> +
>> +		ret = vgic_v3_attr_regs_access(dev, attr, &reg, false);
>> +		if (ret)
>> +			return ret;
>> +		tmp32 = reg;
>> +		return put_user(tmp32, uaddr);
>> +	}
>> +	}
>> +
>> +	return -ENXIO;
>>  }
>>  
>>  static int vgic_v3_has_attr(struct kvm_device *dev,
>> @@ -451,6 +576,9 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
>>  			return 0;
>>  		}
>>  		break;
>> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
>> +		return vgic_v3_has_attr_regs(dev, attr);
>>  	case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
>>  		return 0;
>>  	case KVM_DEV_ARM_VGIC_GRP_CTRL:
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
>> index 0b32f40..2cb04b7 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
>> +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
>> @@ -368,10 +368,9 @@ unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev)
>>  
>>  int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>>  {
>> -	int nr_irqs = dev->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
>>  	const struct vgic_register_region *regions;
>>  	gpa_t addr;
>> -	int nr_regions, i, len;
>> +	int nr_regions;
>>  
>>  	addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
>>  
>> @@ -392,18 +391,7 @@ int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>>  	if (addr & 3)
>>  		return -ENXIO;
>>  
>> -	for (i = 0; i < nr_regions; i++) {
>> -		if (regions[i].bits_per_irq)
>> -			len = (regions[i].bits_per_irq * nr_irqs) / 8;
>> -		else
>> -			len = regions[i].len;
>> -
>> -		if (regions[i].reg_offset <= addr &&
>> -		    regions[i].reg_offset + len > addr)
>> -			return 0;
>> -	}
>> -
>> -	return -ENXIO;
>> +	return vgic_validate_mmio_region_addr(dev, regions, nr_regions, addr);
>>  }
>>  
>>  int vgic_v2_cpuif_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> index 8e76d04..2a7cd62 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> @@ -18,6 +18,8 @@
>>  #include <kvm/arm_vgic.h>
>>  
>>  #include <asm/kvm_emulate.h>
>> +#include <asm/kvm_arm.h>
>> +#include <asm/kvm_mmu.h>
>>  
>>  #include "vgic.h"
>>  #include "vgic-mmio.h"
>> @@ -439,6 +441,9 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>>  	REGISTER_DESC_WITH_LENGTH(GICD_CTLR,
>>  		vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc, 16,
>>  		VGIC_ACCESS_32bit),
>> +	REGISTER_DESC_WITH_LENGTH(GICD_STATUSR,
>> +		vgic_mmio_read_rao, vgic_mmio_write_wi, 4,
>> +		VGIC_ACCESS_32bit),
>>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IGROUPR,
>>  		vgic_mmio_read_rao, vgic_mmio_write_wi, NULL, NULL, 1,
>>  		VGIC_ACCESS_32bit),
>> @@ -486,12 +491,18 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>>  	REGISTER_DESC_WITH_LENGTH(GICR_CTLR,
>>  		vgic_mmio_read_v3r_ctlr, vgic_mmio_write_v3r_ctlr, 4,
>>  		VGIC_ACCESS_32bit),
>> +	REGISTER_DESC_WITH_LENGTH(GICR_STATUSR,
>> +		vgic_mmio_read_raz, vgic_mmio_write_wi, 4,
>> +		VGIC_ACCESS_32bit),
>>  	REGISTER_DESC_WITH_LENGTH(GICR_IIDR,
>>  		vgic_mmio_read_v3r_iidr, vgic_mmio_write_wi, 4,
>>  		VGIC_ACCESS_32bit),
>>  	REGISTER_DESC_WITH_LENGTH(GICR_TYPER,
>>  		vgic_mmio_read_v3r_typer, vgic_mmio_write_wi, 8,
>>  		VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
>> +	REGISTER_DESC_WITH_LENGTH(GICR_WAKER,
>> +		vgic_mmio_read_raz, vgic_mmio_write_wi, 8,
4 ? WAKER is a 32b reg
>> +		VGIC_ACCESS_32bit),
>>  	REGISTER_DESC_WITH_LENGTH(GICR_PROPBASER,
>>  		vgic_mmio_read_propbase, vgic_mmio_write_propbase, 8,
>>  		VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
>> @@ -612,6 +623,34 @@ int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t redist_base_address)
>>  	return ret;
>>  }
>>  
>> +int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>> +{
>> +	const struct vgic_register_region *regions;
>> +	gpa_t addr;
>> +	int nr_regions;
>> +
>> +	addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
>> +
>> +	switch (attr->group) {
>> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>> +		regions = vgic_v3_dist_registers;
>> +		nr_regions = ARRAY_SIZE(vgic_v3_dist_registers);
Couldn't you set
	struct vgic_io_device dev = {
		.regions = vgic_v3_dist_registers,
		.nr_regions = ARRAY_SIZE(vgic_v3_dist_registers),
	};

and reuse:
vgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device
*iodev, gpa_t addr, int len)?

In such a case is vgic_validate_mmio_region_addr() still mandated?
>> +		break;
>> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:{
>> +		regions = vgic_v3_rdbase_registers;
>> +		nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers);
>> +		break;
>> +	}
>> +	default:
>> +		return -ENXIO;
>> +	}
>> +
>> +	/* We only support aligned 32-bit accesses. */
>> +	if (addr & 3)
>> +		return -ENXIO;
>> +
>> +	return vgic_validate_mmio_region_addr(dev, regions, nr_regions, addr);
>> +}
>>  /*
>>   * Compare a given affinity (level 1-3 and a level 0 mask, from the SGI
>>   * generation register ICC_SGI1R_EL1) with a given VCPU.
>> @@ -718,3 +757,36 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
>>  		vgic_put_irq(vcpu->kvm, irq);
>>  	}
>>  }
>> +
>> +int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> +			 int offset, u32 *val)
>> +{
>> +	struct vgic_io_device dev = {
>> +		.regions = vgic_v3_dist_registers,
>> +		.nr_regions = ARRAY_SIZE(vgic_v3_dist_registers),
>> +	};
>> +
>> +	return vgic_uaccess(vcpu, &dev, is_write, offset, val);
>> +}
>> +
>> +int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> +			   int offset, u32 *val)
>> +{
>> +	struct vgic_io_device rd_dev = {
>> +		.regions = vgic_v3_rdbase_registers,
>> +		.nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers),
>> +	};
>> +
>> +	struct vgic_io_device sgi_dev = {
>> +		.regions = vgic_v3_sgibase_registers,
>> +		.nr_regions = ARRAY_SIZE(vgic_v3_sgibase_registers),
>> +	};
>> +
>> +	/* SGI_base is the next 64K frame after RD_base */
>> +	if (offset >= SZ_64K)
>> +		return vgic_uaccess(vcpu, &sgi_dev, is_write,
>> +				    offset - SZ_64K, val);
>> +	else
>> +		return vgic_uaccess(vcpu, &rd_dev, is_write,
>> +				    offset, val);
>> +}
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
>> index d5f3ee2..0d1bc98 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio.c
>> +++ b/virt/kvm/arm/vgic/vgic-mmio.c
>> @@ -394,6 +394,28 @@ static int match_region(const void *key, const void *elt)
>>  		       sizeof(region[0]), match_region);
>>  }
>>  
>> +/* Check if address falls within the region */
>> +int vgic_validate_mmio_region_addr(struct kvm_device *dev,
>> +				   const struct vgic_register_region *regions,
>> +				   int nr_regions, gpa_t addr)
>> +{
>> +	int i, len;
>> +	int nr_irqs = dev->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
>> +
>> +	for (i = 0; i < nr_regions; i++) {
>> +		if (regions[i].bits_per_irq)
>> +			len = (regions[i].bits_per_irq * nr_irqs) / 8;
>> +		else
>> +			len = regions[i].len;
>> +
>> +		if (regions[i].reg_offset <= addr &&
>> +		    regions[i].reg_offset + len > addr)
>> +			return 0;
>> +	}
>> +
>> +	return -ENXIO;
>> +}
>> +
>>  /*
>>   * kvm_mmio_read_buf() returns a value in a format where it can be converted
>>   * to a byte array and be directly observed as the guest wanted it to appear
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
>> index 7b30296..1cc7faf 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio.h
>> +++ b/virt/kvm/arm/vgic/vgic-mmio.h
>> @@ -177,6 +177,10 @@ void vgic_mmio_write_config(struct kvm_vcpu *vcpu,
>>  int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev,
>>  		 bool is_write, int offset, u32 *val);
>>  
>> +int vgic_validate_mmio_region_addr(struct kvm_device *dev,
>> +				   const struct vgic_register_region *regions,
>> +				   int nr_regions, gpa_t addr);
>> +
>>  unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
>>  
>>  unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev);
>> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
>> index 859f65c..91f58b2 100644
>> --- a/virt/kvm/arm/vgic/vgic.h
>> +++ b/virt/kvm/arm/vgic/vgic.h
>> @@ -30,6 +30,49 @@
>>  
>>  #define vgic_irq_is_sgi(intid) ((intid) < VGIC_NR_SGIS)
>>  
>> +#define VGIC_AFFINITY_0_SHIFT 0
>> +#define VGIC_AFFINITY_0_MASK (0xffUL << VGIC_AFFINITY_0_SHIFT)
>> +#define VGIC_AFFINITY_1_SHIFT 8
>> +#define VGIC_AFFINITY_1_MASK (0xffUL << VGIC_AFFINITY_1_SHIFT)
>> +#define VGIC_AFFINITY_2_SHIFT 16
>> +#define VGIC_AFFINITY_2_MASK (0xffUL << VGIC_AFFINITY_2_SHIFT)
>> +#define VGIC_AFFINITY_3_SHIFT 24
>> +#define VGIC_AFFINITY_3_MASK (0xffUL << VGIC_AFFINITY_3_SHIFT)
>> +
>> +#define VGIC_AFFINITY_LEVEL(reg, level) \
>> +	((((reg) & VGIC_AFFINITY_## level ##_MASK) \
>> +	>> VGIC_AFFINITY_## level ##_SHIFT) << MPIDR_LEVEL_SHIFT(level))
>> +
>> +/*
>> + * The Userspace encodes the affinity differently from the MPIDR,
>> + * Below macro converts vgic userspace format to MPIDR reg format.
>> + */
>> +#define VGIC_TO_MPIDR(val) (VGIC_AFFINITY_LEVEL(val, 0) | \
>> +			    VGIC_AFFINITY_LEVEL(val, 1) | \
>> +			    VGIC_AFFINITY_LEVEL(val, 2) | \
>> +			    VGIC_AFFINITY_LEVEL(val, 3))
>> +
>> +/*
>> + * As per Documentation/virtual/kvm/devices/arm-vgic-v3.txt,
>> + * below macros are defined for CPUREG encoding.
>> + */
>> +#define KVM_REG_ARM_VGIC_SYSREG_OP0_MASK   0x000000000000c000
>> +#define KVM_REG_ARM_VGIC_SYSREG_OP0_SHIFT  14
>> +#define KVM_REG_ARM_VGIC_SYSREG_OP1_MASK   0x0000000000003800
>> +#define KVM_REG_ARM_VGIC_SYSREG_OP1_SHIFT  11
>> +#define KVM_REG_ARM_VGIC_SYSREG_CRN_MASK   0x0000000000000780
>> +#define KVM_REG_ARM_VGIC_SYSREG_CRN_SHIFT  7
>> +#define KVM_REG_ARM_VGIC_SYSREG_CRM_MASK   0x0000000000000078
>> +#define KVM_REG_ARM_VGIC_SYSREG_CRM_SHIFT  3
>> +#define KVM_REG_ARM_VGIC_SYSREG_OP2_MASK   0x0000000000000007
>> +#define KVM_REG_ARM_VGIC_SYSREG_OP2_SHIFT  0
>> +
>> +#define KVM_DEV_ARM_VGIC_SYSREG_MASK (KVM_REG_ARM_VGIC_SYSREG_OP0_MASK | \
>> +				      KVM_REG_ARM_VGIC_SYSREG_OP1_MASK | \
>> +				      KVM_REG_ARM_VGIC_SYSREG_CRN_MASK | \
>> +				      KVM_REG_ARM_VGIC_SYSREG_CRM_MASK | \
>> +				      KVM_REG_ARM_VGIC_SYSREG_OP2_MASK)
nit: do those SYSREG defines relate to this patch?

Thanks

Eric
>> +
>>  struct vgic_vmcr {
>>  	u32	ctlr;
>>  	u32	abpr;
>> @@ -89,7 +132,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>>  int kvm_vgic_register_its_device(void);
>>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>>  int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
>> -
>> +int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr);
>> +int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> +			 int offset, u32 *val);
>> +int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> +			 int offset, u32 *val);
>>  int kvm_register_vgic_device(unsigned long type);
>>  int vgic_lazy_init(struct kvm *kvm);
>>  int vgic_init(struct kvm *kvm);
>> -- 
>> 1.9.1
>>
> 
> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* [RFC PATCH 04/23] arm: use kconfig fragments for ARCH_ASPEED defconfigs
From: Baruch Siach @ 2016-12-06 13:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481027938-31831-5-git-send-email-b.zolnierkie@samsung.com>

Hi Bartlomiej,

On Tue, Dec 06, 2016 at 01:38:39PM +0100, Bartlomiej Zolnierkiewicz wrote:
> Replace [acs5k,acs5k_tiny,ks8695]_defconfig-s with a Makefile target
> using merge_config.
> 
> The patch was verified with doing:
> 
>     $ make [acs5k,acs5k_tiny,ks8695]_defconfig
>     $ make savedefconfig
> 
> and comparing resulting defconfig files (before/after the patch).

The subject is wrong. Ditto for the mmp/pxa patch.

> Cc: Greg Ungerer <gerg@uclinux.org>
> Cc: Cyril Bur <cyrilbur@gmail.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

baruch

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

^ permalink raw reply

* [PATCH v3] KVM: arm/arm64: Access CNTHCTL_EL2 bit fields correctly
From: Jintack Lim @ 2016-12-06 13:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <49451f06-10a6-4921-eae6-c37a5510197a@arm.com>

On Tue, Dec 6, 2016 at 6:17 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On 01/12/16 19:32, Jintack Lim wrote:
>> Current KVM world switch code is unintentionally setting wrong bits to
>> CNTHCTL_EL2 when E2H == 1, which may allow guest OS to access physical
>> timer.  Bit positions of CNTHCTL_EL2 are changing depending on
>> HCR_EL2.E2H bit.  EL1PCEN and EL1PCTEN are 1st and 0th bits when E2H is
>> not set, but they are 11th and 10th bits respectively when E2H is set.
>>
>> In fact, on VHE we only need to set those bits once, not for every world
>> switch. This is because the host kernel runs in EL2 with HCR_EL2.TGE ==
>> 1, which makes those bits have no effect for the host kernel execution.
>> So we just set those bits once for guests, and that's it.
>>
>> Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
>> ---
>> v2->v3:
>> - Perform the initialization including CPU hotplug case.
>> - Move has_vhe() to asm/virt.h
>>
>> v1->v2:
>> - Skip configuring cnthctl_el2 in world switch path on VHE system.
>> - Write patch based on linux-next.
>> ---
>>  arch/arm/include/asm/virt.h   |  5 +++++
>>  arch/arm/kvm/arm.c            |  3 +++
>>  arch/arm64/include/asm/virt.h | 10 ++++++++++
>>  include/kvm/arm_arch_timer.h  |  1 +
>>  virt/kvm/arm/arch_timer.c     | 23 +++++++++++++++++++++++
>>  virt/kvm/arm/hyp/timer-sr.c   | 33 +++++++++++++++++++++------------
>>  6 files changed, 63 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
>> index a2e75b8..6dae195 100644
>> --- a/arch/arm/include/asm/virt.h
>> +++ b/arch/arm/include/asm/virt.h
>> @@ -80,6 +80,11 @@ static inline bool is_kernel_in_hyp_mode(void)
>>       return false;
>>  }
>>
>> +static inline bool has_vhe(void)
>> +{
>> +     return false;
>> +}
>> +
>>  /* The section containing the hypervisor idmap text */
>>  extern char __hyp_idmap_text_start[];
>>  extern char __hyp_idmap_text_end[];
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 8f92efa..13e54e8 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -1099,6 +1099,9 @@ static void cpu_init_hyp_mode(void *dummy)
>>       __cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
>>       __cpu_init_stage2();
>>
>> +     if (is_kernel_in_hyp_mode())
>> +             kvm_timer_init_vhe();
>> +
>>       kvm_arm_init_debug();
>>  }
>>
>> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
>> index fea1073..b043cfd 100644
>> --- a/arch/arm64/include/asm/virt.h
>> +++ b/arch/arm64/include/asm/virt.h
>> @@ -47,6 +47,7 @@
>>  #include <asm/ptrace.h>
>>  #include <asm/sections.h>
>>  #include <asm/sysreg.h>
>> +#include <asm/cpufeature.h>
>>
>>  /*
>>   * __boot_cpu_mode records what mode CPUs were booted in.
>> @@ -80,6 +81,15 @@ static inline bool is_kernel_in_hyp_mode(void)
>>       return read_sysreg(CurrentEL) == CurrentEL_EL2;
>>  }
>>
>> +static inline bool has_vhe(void)
>> +{
>> +#ifdef CONFIG_ARM64_VHE
>
> Is there a particular reason why this should be guarded by a #ifdef? All
> the symbols should always be available, and since this is a static key,
> the overhead should be really insignificant (provided that you use a
> non-prehistoric compiler...).

It was only for reducing overhead on non-VHE system.

>
>> +     if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
>> +             return true;
>> +#endif
>> +     return false;
>> +}
>> +
>>  #ifdef CONFIG_ARM64_VHE
>>  extern void verify_cpu_run_el(void);
>>  #else
>> diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
>> index dda39d8..2d54903 100644
>> --- a/include/kvm/arm_arch_timer.h
>> +++ b/include/kvm/arm_arch_timer.h
>> @@ -76,4 +76,5 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>>
>>  void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
>>
>> +void kvm_timer_init_vhe(void);
>>  #endif
>> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
>> index 17b8fa5..c7c3bfd 100644
>> --- a/virt/kvm/arm/arch_timer.c
>> +++ b/virt/kvm/arm/arch_timer.c
>> @@ -24,6 +24,7 @@
>>
>>  #include <clocksource/arm_arch_timer.h>
>>  #include <asm/arch_timer.h>
>> +#include <asm/kvm_hyp.h>
>>
>>  #include <kvm/arm_vgic.h>
>>  #include <kvm/arm_arch_timer.h>
>> @@ -507,3 +508,25 @@ void kvm_timer_init(struct kvm *kvm)
>>  {
>>       kvm->arch.timer.cntvoff = kvm_phys_timer_read();
>>  }
>> +
>> +/*
>> + * On VHE system, we only need to configure trap on physical timer and counter
>> + * accesses in EL0 and EL1 once, not for every world switch.
>> + * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
>> + * and this makes those bits have no effect for the host kernel execution.
>> + */
>> +void kvm_timer_init_vhe(void)
>> +{
>> +     /* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
>> +     u32 cnthctl_shift = 10;
>> +     u64 val;
>> +
>> +     /*
>> +      * Disallow physical timer access for the guest.
>> +      * Physical counter access is allowed.
>> +      */
>> +     val = read_sysreg(cnthctl_el2);
>> +     val &= ~(CNTHCTL_EL1PCEN << cnthctl_shift);
>> +     val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
>> +     write_sysreg(val, cnthctl_el2);
>> +}
>> diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c
>> index 798866a..63e28dd 100644
>> --- a/virt/kvm/arm/hyp/timer-sr.c
>> +++ b/virt/kvm/arm/hyp/timer-sr.c
>> @@ -35,10 +35,16 @@ void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu)
>>       /* Disable the virtual timer */
>>       write_sysreg_el0(0, cntv_ctl);
>>
>> -     /* Allow physical timer/counter access for the host */
>> -     val = read_sysreg(cnthctl_el2);
>> -     val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
>> -     write_sysreg(val, cnthctl_el2);
>> +     /*
>> +      * We don't need to do this for VHE since the host kernel runs in EL2
>> +      * with HCR_EL2.TGE ==1, which makes those bits have no impact.
>> +      */
>> +     if (!has_vhe()) {
>> +             /* Allow physical timer/counter access for the host */
>> +             val = read_sysreg(cnthctl_el2);
>> +             val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
>> +             write_sysreg(val, cnthctl_el2);
>> +     }
>>
>>       /* Clear cntvoff for the host */
>>       write_sysreg(0, cntvoff_el2);
>> @@ -50,14 +56,17 @@ void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
>>       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
>>       u64 val;
>>
>> -     /*
>> -      * Disallow physical timer access for the guest
>> -      * Physical counter access is allowed
>> -      */
>> -     val = read_sysreg(cnthctl_el2);
>> -     val &= ~CNTHCTL_EL1PCEN;
>> -     val |= CNTHCTL_EL1PCTEN;
>> -     write_sysreg(val, cnthctl_el2);
>> +     /* Those bits are already configured at boot on VHE-system */
>> +     if (!has_vhe()) {
>> +             /*
>> +              * Disallow physical timer access for the guest
>> +              * Physical counter access is allowed
>> +              */
>> +             val = read_sysreg(cnthctl_el2);
>> +             val &= ~CNTHCTL_EL1PCEN;
>> +             val |= CNTHCTL_EL1PCTEN;
>> +             write_sysreg(val, cnthctl_el2);
>> +     }
>>
>>       if (timer->enabled) {
>>               write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2);
>>
>
> Otherwise, and assuming you're OK with me fixing the above nit (no need
> to resend):

I'm ok with it. Thanks!

>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
>
> Thanks,
>
>         M.
> --
> Jazz is not dead. It just smells funny...
>

^ permalink raw reply

* [PATCH] ACPI/IORT: Make dma masks set-up IORT specific
From: Joerg Roedel @ 2016-12-06 13:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206093710.GA4432@red-moon>

Hi Lorenzo,

On Tue, Dec 06, 2016 at 09:37:10AM +0000, Lorenzo Pieralisi wrote:
> I can apply Rafael and Hanjun's tags and resend a v2 to you if you
> prefer, it would be great if you could apply this patch to your arm/smmu
> branch for v4.10 as per description above, please let me know.

Yes, please collect all the tags and send me a v2 please. I'll apply it
the right away.


Thanks,

	Joerg

^ permalink raw reply

* [PATCH v9 03/11] arm/arm64: vgic: Introduce find_reg_by_id()
From: Auger Eric @ 2016-12-06 13:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479906118-15832-4-git-send-email-vijay.kilari@gmail.com>

Hi Vijay,
On 23/11/2016 14:01, vijay.kilari at gmail.com wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> 
> In order to implement vGICv3 CPU interface access, we will need to perform
> table lookup of system registers. We would need both index_to_params() and
> find_reg() exported for that purpose, but instead we export a single
> function which combines them both.
> 
> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  arch/arm64/kvm/sys_regs.c | 22 +++++++++++++++-------
>  arch/arm64/kvm/sys_regs.h |  4 ++++
>  2 files changed, 19 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index f302fdb..1330d4c 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1789,6 +1789,17 @@ static bool index_to_params(u64 id, struct sys_reg_params *params)
>  	}
>  }
>  
> +const struct sys_reg_desc *find_reg_by_id(u64 id,
> +					  struct sys_reg_params *params,
> +					  const struct sys_reg_desc table[],
> +					  unsigned int num)
> +{
> +	if (!index_to_params(id, params))
> +		return NULL;
> +
> +	return find_reg(params, table, num);
> +}
> +
Can't you use find_reg_by_id in index_to_sys_reg_desc too?

Besides Reviewed-by: Eric Auger <eric.auger@redhat.com>

Thanks

Eric
>  /* Decode an index value, and find the sys_reg_desc entry. */
>  static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,
>  						    u64 id)
> @@ -1912,10 +1923,8 @@ static int get_invariant_sys_reg(u64 id, void __user *uaddr)
>  	struct sys_reg_params params;
>  	const struct sys_reg_desc *r;
>  
> -	if (!index_to_params(id, &params))
> -		return -ENOENT;
> -
> -	r = find_reg(&params, invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs));
> +	r = find_reg_by_id(id, &params, invariant_sys_regs,
> +			   ARRAY_SIZE(invariant_sys_regs));
>  	if (!r)
>  		return -ENOENT;
>  
> @@ -1929,9 +1938,8 @@ static int set_invariant_sys_reg(u64 id, void __user *uaddr)
>  	int err;
>  	u64 val = 0; /* Make sure high bits are 0 for 32-bit regs */
>  
> -	if (!index_to_params(id, &params))
> -		return -ENOENT;
> -	r = find_reg(&params, invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs));
> +	r = find_reg_by_id(id, &params, invariant_sys_regs,
> +			   ARRAY_SIZE(invariant_sys_regs));
>  	if (!r)
>  		return -ENOENT;
>  
> diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
> index dbbb01c..9c6ffd0 100644
> --- a/arch/arm64/kvm/sys_regs.h
> +++ b/arch/arm64/kvm/sys_regs.h
> @@ -136,6 +136,10 @@ static inline int cmp_sys_reg(const struct sys_reg_desc *i1,
>  	return i1->Op2 - i2->Op2;
>  }
>  
> +const struct sys_reg_desc *find_reg_by_id(u64 id,
> +					  struct sys_reg_params *params,
> +					  const struct sys_reg_desc table[],
> +					  unsigned int num);
>  
>  #define Op0(_x) 	.Op0 = _x
>  #define Op1(_x) 	.Op1 = _x
> 

^ permalink raw reply

* [PATCH v3] KVM: arm/arm64: Access CNTHCTL_EL2 bit fields correctly
From: Jintack Lim @ 2016-12-06 13:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206121221.GA3681@cbox>

Hi Christoffer,
Thanks for the review.

On Tue, Dec 6, 2016 at 7:12 AM, Christoffer Dall
<christoffer.dall@linaro.org> wrote:
> On Tue, Dec 06, 2016 at 11:17:40AM +0000, Marc Zyngier wrote:
>> On 01/12/16 19:32, Jintack Lim wrote:
>> > Current KVM world switch code is unintentionally setting wrong bits to
>> > CNTHCTL_EL2 when E2H == 1, which may allow guest OS to access physical
>> > timer.  Bit positions of CNTHCTL_EL2 are changing depending on
>> > HCR_EL2.E2H bit.  EL1PCEN and EL1PCTEN are 1st and 0th bits when E2H is
>> > not set, but they are 11th and 10th bits respectively when E2H is set.
>> >
>> > In fact, on VHE we only need to set those bits once, not for every world
>> > switch. This is because the host kernel runs in EL2 with HCR_EL2.TGE ==
>> > 1, which makes those bits have no effect for the host kernel execution.
>> > So we just set those bits once for guests, and that's it.
>> >
>> > Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
>> > ---
>> > v2->v3:
>> > - Perform the initialization including CPU hotplug case.
>> > - Move has_vhe() to asm/virt.h
>> >
>> > v1->v2:
>> > - Skip configuring cnthctl_el2 in world switch path on VHE system.
>> > - Write patch based on linux-next.
>> > ---
>> >  arch/arm/include/asm/virt.h   |  5 +++++
>> >  arch/arm/kvm/arm.c            |  3 +++
>> >  arch/arm64/include/asm/virt.h | 10 ++++++++++
>> >  include/kvm/arm_arch_timer.h  |  1 +
>> >  virt/kvm/arm/arch_timer.c     | 23 +++++++++++++++++++++++
>> >  virt/kvm/arm/hyp/timer-sr.c   | 33 +++++++++++++++++++++------------
>> >  6 files changed, 63 insertions(+), 12 deletions(-)
>> >
>> > diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
>> > index a2e75b8..6dae195 100644
>> > --- a/arch/arm/include/asm/virt.h
>> > +++ b/arch/arm/include/asm/virt.h
>> > @@ -80,6 +80,11 @@ static inline bool is_kernel_in_hyp_mode(void)
>> >     return false;
>> >  }
>> >
>> > +static inline bool has_vhe(void)
>> > +{
>> > +   return false;
>> > +}

This is the one called on 32-bit arm.

>> > +
>> >  /* The section containing the hypervisor idmap text */
>> >  extern char __hyp_idmap_text_start[];
>> >  extern char __hyp_idmap_text_end[];
>> > diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> > index 8f92efa..13e54e8 100644
>> > --- a/arch/arm/kvm/arm.c
>> > +++ b/arch/arm/kvm/arm.c
>> > @@ -1099,6 +1099,9 @@ static void cpu_init_hyp_mode(void *dummy)
>> >     __cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
>> >     __cpu_init_stage2();
>> >
>> > +   if (is_kernel_in_hyp_mode())
>> > +           kvm_timer_init_vhe();
>> > +
>> >     kvm_arm_init_debug();
>> >  }
>> >
>> > diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
>> > index fea1073..b043cfd 100644
>> > --- a/arch/arm64/include/asm/virt.h
>> > +++ b/arch/arm64/include/asm/virt.h
>> > @@ -47,6 +47,7 @@
>> >  #include <asm/ptrace.h>
>> >  #include <asm/sections.h>
>> >  #include <asm/sysreg.h>
>> > +#include <asm/cpufeature.h>
>> >
>> >  /*
>> >   * __boot_cpu_mode records what mode CPUs were booted in.
>> > @@ -80,6 +81,15 @@ static inline bool is_kernel_in_hyp_mode(void)
>> >     return read_sysreg(CurrentEL) == CurrentEL_EL2;
>> >  }
>> >
>> > +static inline bool has_vhe(void)
>> > +{
>> > +#ifdef CONFIG_ARM64_VHE
>>
>> Is there a particular reason why this should be guarded by a #ifdef? All
>> the symbols should always be available, and since this is a static key,
>> the overhead should be really insignificant (provided that you use a
>> non-prehistoric compiler...).
>>
>
> Isn't this code called from a file shared between 32-bit arm and arm64?

This code is only for ARM64. See above for 32-bit arm.

> Does the cpus_have_const_cap work on ARM64?
>
> -Christoffer
>

^ permalink raw reply

* [PATCH renesas/devel 0/2]  ARM: Enable r8a774[35] SoCs in defconfigs
From: Simon Horman @ 2016-12-06 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

this short series enables recently added r8a7743 (RZ/G1M) and r8a7745
(RZ/G1E) SoCs in relevant defconfigs.

Based on renesas-devel-20161206-v4.9-rc8

Simon Horman (2):
  ARM: shmobile: defconfig: Enable r8a774[35] SoCs
  ARM: multi_v7_defconfig: Enable r8a774[35] SoCs

 arch/arm/configs/multi_v7_defconfig | 2 ++
 arch/arm/configs/shmobile_defconfig | 2 ++
 2 files changed, 4 insertions(+)

-- 
2.7.0.rc3.207.g0ac5344

^ 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