Devicetree
 help / color / mirror / Atom feed
* [PATCH v5 1/2] iio: adc: hx711: Add DT binding for avia,hx711
From: Andreas Klinger @ 2017-01-05 17:51 UTC (permalink / raw)
  To: devicetree, linux-iio
  Cc: linux-kernel, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, jic23, knaack.h, lars, pmeerw, ak

Add DT bindings for avia,hx711
Add vendor avia to vendor list

Signed-off-by: Andreas Klinger <ak@it-klinger.de>
Acked-by: Rob Herring <robh@kernel.org>
---
[PATCH v3 1/2] of this patch was Acked-by: Rob Herring <robh@kernel.org>
In v4 the regulator (avdd-supply) was added

 .../devicetree/bindings/iio/adc/avia-hx711.txt         | 18 ++++++++++++++++++
 Documentation/devicetree/bindings/vendor-prefixes.txt  |  1 +
 2 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/avia-hx711.txt

diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
new file mode 100644
index 000000000000..b3629405f568
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
@@ -0,0 +1,18 @@
+* AVIA HX711 ADC chip for weight cells
+  Bit-banging driver
+
+Required properties:
+ - compatible:	Should be "avia,hx711"
+ - sck-gpios:	Definition of the GPIO for the clock
+ - dout-gpios:	Definition of the GPIO for data-out
+		See Documentation/devicetree/bindings/gpio/gpio.txt
+ - avdd-supply:	Definition of the regulator used as analog supply
+
+Example:
+weight@0 {
+	compatible = "avia,hx711";
+	sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
+	dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+	avdd-suppy = <&avdd>;
+};
+
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 44ddc980b085..4696bb5c2198 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -32,6 +32,7 @@ atlas	Atlas Scientific LLC
 atmel	Atmel Corporation
 auo	AU Optronics Corporation
 avago	Avago Technologies
+avia	avia semiconductor
 avic	Shanghai AVIC Optoelectronics Co., Ltd.
 axis	Axis Communications AB
 boe	BOE Technology Group Co., Ltd.
-- 
2.1.4

^ permalink raw reply related

* [PATCH v5 0/2] iio: adc: hx711: Add IIO driver for AVIA HX711 ADC
From: Andreas Klinger @ 2017-01-05 17:51 UTC (permalink / raw)
  To: devicetree, linux-iio
  Cc: linux-kernel, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, jic23, knaack.h, lars, pmeerw, ak

This series adds IIO driver support for the AVIA HX711 ADC which is 
mostly used in weighting cells.

The first patch adds the new DT binding for which a new vendor avia
was also added.

The second patch is the simple IIO driver implemented as ADC.
The protocol is specific to this device and implemented using GPIOs.

Documentation of the chip can be found here:

https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf

Changes in v5:
The reviews of Peter and Jonathan induced some improvements and lined out
at least one bug

* Patch 1: "iio: adc: hx711: Add DT binding for avia,hx711"
  - put Acked-By once again on the patch

* Patch 2: "iio: adc: hx711: Add IIO driver for AVIA HX711"
  - improved ugly locking
  - replace devm_iio_device_register() by iio_device_register() because of
    regulator_disable() in remove()
  - added ...scale_available() functions for both channels
  - name channels directly 0 and 1 instead of #define HX711_CHAN_A...
  - added hx711_wait_for_ready() function which is called after every dummy
    read to get sure the DOUT line signals that the device is ready
  - without this check there are cases in which the clock cycle of the next
    read gets interpreted by the device as gain pulses!

Changes in v4:
Thanks to the thorough reviews and suggestions of Jonathan and Lars-Peter
the driver was reworked to better meet the standard ABI of IIO. 

* Patch 1: "iio: adc: hx711: Add DT binding for avia,hx711"
  - added attribute for regulator

* Patch 2: "iio: adc: hx711: Add IIO driver for AVIA HX711"
  - two read channels for physical channels A and B
  - remove gain attribute and use scale as read raw
  - offer scale_available attribute
  - introduced regulator as analog supply; mainly needed for calculating
    the scale
  - simplyfied use of GPIOs
  - measuring input and output with oszilloscope and revised timing behavior
  - many minor changes

Changes in v3:
moved gain from devicetree to sysfs, according to comment of Lars-Peter
Thanks for reviewing and giving suggestions

* Patch 1: "iio: adc: hx711: Add DT binding for avia,hx711"
  - removed property gain

* Patch 2: "iio: adc: hx711: Add IIO driver for AVIA HX711"
  - removed property gain from devicetree
  - added device attribute (rw) for gain
  - support reading from both channels now

Changes in v2:
Lots of updates thanks to Peters review.

* Patch 1: "iio: adc: hx711: Add DT binding for avia,hx711"
  - typo
  - removed unneded section

* Patch 2: "iio: adc: hx711: Add IIO driver for AVIA HX711"
  - updated help text in Kconfig
  - removed dead code
  - removed unused power management
  - reduced channel spec to what is actually used
  - added error handling in case reset of chip not possible

Andreas Klinger (2):
  iio: adc: hx711: Add DT binding for avia,hx711
  iio: adc: hx711: Add IIO driver for AVIA HX711

 .../devicetree/bindings/iio/adc/avia-hx711.txt     |  18 +
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 drivers/iio/adc/Kconfig                            |  19 +
 drivers/iio/adc/Makefile                           |   1 +
 drivers/iio/adc/hx711.c                            | 531 +++++++++++++++++++++
 5 files changed, 570 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
 create mode 100644 drivers/iio/adc/hx711.c

-- 
2.1.4

^ permalink raw reply

* Re: [PATCH 3/5] arm64: dts: sun50i: add MMC nodes
From: Maxime Ripard @ 2017-01-05 17:50 UTC (permalink / raw)
  To: Andre Przywara
  Cc: Ulf Hansson, Chen-Yu Tsai, Hans De Goede, Icenowy Zheng,
	Mark Rutland, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1483398226-29321-4-git-send-email-andre.przywara-5wv7dgnIgG8@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1909 bytes --]

On Mon, Jan 02, 2017 at 11:03:44PM +0000, Andre Przywara wrote:
> Signed-off-by: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 67 +++++++++++++++++++++++++++
>  1 file changed, 67 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index e0dcab8..c680566 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -150,6 +150,32 @@
>  				pins = "PB8", "PB9";
>  				function = "uart0";
>  			};
> +
> +			mmc0_pins: mmc0@0 {
> +				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
> +				function = "mmc0";
> +				drive-strength = <30>;
> +			};
> +
> +			mmc0_default_cd_pin: mmc0_cd_pin@0 {
> +				pins = "PF6";
> +				function = "gpio_in";
> +				bias-pull-up;
> +			};
> +
> +			mmc1_pins: mmc1@0 {
> +				pins = "PG0", "PG1", "PG2", "PG3", "PG4", "PG5";
> +				function = "mmc1";
> +				drive-strength = <30>;
> +			};
> +
> +			mmc2_pins: mmc2@0 {
> +				pins = "PC1", "PC5", "PC6", "PC8", "PC9",
> +				       "PC10", "PC11", "PC12", "PC13", "PC14",
> +				       "PC15", "PC16";
> +				function = "mmc2";
> +				drive-strength = <30>;
> +			};
>  		};
>  
>  		uart0: serial@1c28000 {
> @@ -240,6 +266,47 @@
>  			#size-cells = <0>;
>  		};
>  
> +		mmc0: mmc@1c0f000 {
> +			compatible = "allwinner,sun50i-a64-mmc",
> +				     "allwinner,sun5i-a13-mmc";

That's not correct. There's a bunch of features that are broken
without A64-specific (or at least not present on the A13)
quirks. Those features include for example the SDIO aggregation that
are currently broken for all modes supported so far.

I was in holidays and send those patches tomorrow, but you were a bit
too quick :)

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH 1/5] drivers: mmc: sunxi: fix A64 calibration routine
From: Maxime Ripard @ 2017-01-05 17:47 UTC (permalink / raw)
  To: Andre Przywara
  Cc: Ulf Hansson, Chen-Yu Tsai, Hans De Goede, Icenowy Zheng,
	Mark Rutland, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1483398226-29321-2-git-send-email-andre.przywara-5wv7dgnIgG8@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1258 bytes --]

Hi,

On Mon, Jan 02, 2017 at 11:03:42PM +0000, Andre Przywara wrote:
> The calibration facility in the A64 MMC block seems to have been
> misunderstood: the result value is not the value to program into the
> delay bits, but is the number of delay cells that result in a full clock
> cycle delay. So this value has to be scaled by the desired phase, which
> we still have to know and program.
> Change the calibration routine to take a phase parameter and scale the
> calibration value accordingly.
> Also introduce sun50i-a64 delay parameters to store the required phase.
> Looking at the BSP kernel the sample delay for anything below HS200 is
> 0, so we go with that value.
> Once the driver supports HS200 and faster modes, we can enter confirmed
> working values in there.
> 
> Signed-off-by: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>

Exactly how that works hasn't been confirmed, and the only thing that
this patch actually do is... nothing, since the delay is always 0. If
and when we get HS400 to work and we know for a fact how the
calibration works, then we'll be able to use it. Until then, we can
just clear those bits.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* Re: [RFC 1/1] Changes to support the driver for platform device registration
From: Florian Fainelli @ 2017-01-05 17:43 UTC (permalink / raw)
  To: Raviteja Garimella, Rob Herring, Mark Rutland, Greg Kroah-Hartman,
	Felipe Balbi
  Cc: devicetree, linux-kernel, bcm-kernel-feedback-list, linux-usb
In-Reply-To: <1483604597-26160-2-git-send-email-raviteja.garimella@broadcom.com>

On 01/05/2017 12:23 AM, Raviteja Garimella wrote:
> -- Add OF based platform device registration
> -- Modify debug prints to be compatible with both pci and platform devices
> -- Add members to 'struct udc' for extcon and phy support
> -- Add checks to not process repeated calls to udc connect and
>    disconnect routines
> -- Kconfig changes

What you are doing in this patch is all well and good, but since you are
listing these changes, that means we should see 4/5 patches submitted to
this driver each one doing what you have as a bullet point.

Since you are adding Device Tree probing support to the driver, you also
need to create a proper binding document which describes the properties
and nodes.

Thank you
-- 
Florian

^ permalink raw reply

* Re: [PATCH] ARM: dts: sunxi: Enable spi1 and spi2 for Olimex A20 SOM EVB
From: Emmanuel Vadot @ 2017-01-05 17:37 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: mark.rutland, devicetree, linux, linux-kernel, wens, robh+dt,
	linux-arm-kernel
In-Reply-To: <20170105171601.us4wffupptilvvqp@lukather>


 Hi,

On Thu, 5 Jan 2017 18:16:01 +0100
Maxime Ripard <maxime.ripard@free-electrons.com> wrote:

> Hi,
> 
> On Mon, Dec 26, 2016 at 06:53:49PM +0100, Emmanuel Vadot wrote:
> > Enable the spi1 and spi2 node since the pins are exposed on the UEXT
> > connectors.
> > 
> > Signed-off-by: Emmanuel Vadot <manu@bidouilliste.com>
> > ---
> >  arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
> > index 669a1c338c76..fa8c6f60552b 100644
> > --- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
> > +++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
> > @@ -300,12 +300,14 @@
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&spi1_pins_a>,
> >  		    <&spi1_cs0_pins_a>;
> > +	status = "okay";
> >  };
> >  
> >  &spi2 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&spi2_pins_a>,
> >  		    <&spi2_cs0_pins_a>;
> > +	status = "okay";
> >  };
> 
> Those nodes don't exist unfortunately. Maybe you forgot to send one
> patch?
> 
> Thanks!
> Maxime
> 
> -- 
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

 It's based on a previous sent patch :
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/469288.html

 You said you'll squash the two commits.

-- 
Emmanuel Vadot <manu@bidouilliste.com> <manu@freebsd.org>

^ permalink raw reply

* Re: [PATCH 5/5] arm64: dts: add BananaPi-M64 support
From: Maxime Ripard @ 2017-01-05 17:36 UTC (permalink / raw)
  To: Andre Przywara
  Cc: Ulf Hansson, Chen-Yu Tsai, Hans De Goede, Icenowy Zheng,
	Mark Rutland, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1483398226-29321-6-git-send-email-andre.przywara-5wv7dgnIgG8@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 6319 bytes --]

On Mon, Jan 02, 2017 at 11:03:46PM +0000, Andre Przywara wrote:
> The Banana Pi M64 board is a typical single board computer based on the
> Allwinner A64 SoC. Aside from the usual peripherals it features eMMC
> storage, which is connected to the 8-bit capable SDHC2 controller.
> Also it has a soldered WiFi/Bluetooth chip, so we enable UART1 and SDHC1
> as those two interfaces are connected to it.
> 
> Signed-off-by: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>
> ---
>  arch/arm64/boot/dts/allwinner/Makefile             |   1 +
>  .../boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 125 +++++++++++++++++++++
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi      |  10 ++
>  3 files changed, 136 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
> 
> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> index 1e29a5a..51ecb04 100644
> --- a/arch/arm64/boot/dts/allwinner/Makefile
> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> @@ -1,4 +1,5 @@
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb

Please sort it by alphabetical order.

>  
>  always		:= $(dtb-y)
>  subdir-y	:= $(dts-dirs)
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
> new file mode 100644
> index 0000000..941ea07
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
> @@ -0,0 +1,125 @@
> +/*
> + * Copyright (c) 2016 ARM Ltd.
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This library is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This library is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +
> +#include "sun50i-a64.dtsi"
> +
> +/ {
> +	model = "BananaPi-M64";
> +	compatible = "sinovoip,bananapi-m64", "allwinner,sun50i-a64";
> +
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	reg_vcc3v3: vcc3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc3v3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +	};
> +};
> +
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_pins_a>;
> +	status = "okay";
> +};
> +
> +&uart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart1_pins_4>;
> +	status = "okay";
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c1_pins>;
> +	status = "okay";
> +};

And the nodes too.

> +
> +&i2c1_pins {
> +	bias-pull-up;
> +};
> +
> +&mmc0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc0_pins>, <&mmc0_default_cd_pin>;
> +	vmmc-supply = <&reg_vcc3v3>;
> +	cd-gpios = <&pio 5 6 0>;

Please use a define here.

> +	cd-inverted;
> +	disable-wp;
> +	bus-width = <4>;
> +	status = "okay";
> +};
> +
> +&mmc1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc1_pins>;
> +	vmmc-supply = <&reg_vcc3v3>;
> +	bus-width = <4>;
> +	non-removable;
> +	status = "okay";
> +};
> +
> +&mmc2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc2_pins>;
> +	vmmc-supply = <&reg_vcc3v3>;
> +	bus-width = <8>;
> +	non-removable;
> +	cap-mmc-hw-reset;
> +	status = "okay";
> +};
> +
> +&mmc2_pins {
> +	/* Increase drive strength for DDR modes */
> +	drive-strength = <40>;

Allwinner recommends to use 30mA, have you tested it?

> +	/* eMMC is missing pull-ups */
> +	bias-pull-up;

This is the default now.

> +};
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index c680566..9de96ba 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -151,6 +151,16 @@
>  				function = "uart0";
>  			};
>  
> +			uart1_pins: uart1@0 {
> +				pins = "PG6", "PG7";
> +				function = "uart1";
> +			};
> +
> +			uart1_pins_4: uart1_4@0 {
> +				pins = "PG6", "PG7", "PG8", "PG9";

For other nodes, we've been creating another node for the cts and rts
signals, and reference both nodes in the pinctrl properties. It allows
to avoid duplication.

> +				function = "uart1";
> +			};
> +
>  			mmc0_pins: mmc0@0 {

Please sort it by alphabetical order. And it should be in a separate
patch.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
From: Ezequiel Garcia @ 2017-01-05 17:34 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Mark Rutland, Thomas Petazzoni, lars, devicetree@vger.kernel.org,
	linux-iio, linux-kernel@vger.kernel.org, linux-pm, sre, linux,
	Chen-Yu Tsai, Rob Herring, icenowy, pmeerw, knaack.h,
	Maxime Ripard, bonbons, Lee Jones, jic23, linux-arm-kernel
In-Reply-To: <20170102163723.7939-18-quentin.schulz@free-electrons.com>

On 2 January 2017 at 13:37, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
[...]
> +
> +#define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2)
> +
> +#define AXP20X_PWR_OP_BATT_PRESENT     BIT(5)
> +#define AXP20X_PWR_OP_BATT_ACTIVATED   BIT(3)
> +
> +#define AXP209_FG_PERCENT              GENMASK(6, 0)
> +#define AXP22X_FG_VALID                        BIT(7)
> +
> +#define AXP20X_CHRG_CTRL1_TGT_VOLT     GENMASK(6, 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_1V     (0 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_15V    BIT(5)

This is just a silly nit, but I would put (1 << 5) here
for readability.

> +#define AXP20X_CHRG_CTRL1_TGT_4_2V     (2 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_36V    (3 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_CURR     GENMASK(3, 0)
> +
> +#define AXP22X_CHRG_CTRL1_TGT_4_22V    BIT(5)

Ditto.

> +#define AXP22X_CHRG_CTRL1_TGT_4_24V    (3 << 5)
> +
> +#define AXP20X_V_OFF_MASK              GENMASK(2, 0)
> +
> +struct axp20x_batt_ps {
> +       struct regmap *regmap;
> +       struct power_supply *batt;
> +       struct axp20x_dev *axp20x;
> +       struct iio_channel *batt_chrg_i;
> +       struct iio_channel *batt_dischrg_i;
> +       struct iio_channel *batt_v;
> +       u8 axp_id;
> +};
> +
[..]
> +static int axp20x_power_probe(struct platform_device *pdev)
> +{
> +       struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +       struct axp20x_batt_ps *axp20x_batt;
> +       struct power_supply_config psy_cfg = {};
> +

To be consistent with the AC power supply and USB power supply,
you might want to call of_device_is_available() here.
Otherwise, the device probes even if "disabled" in the DTS.

> +       axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
> +                                  GFP_KERNEL);
> +       if (!axp20x_batt)
> +               return -ENOMEM;
> +

Thanks for the good work,
-- 
Ezequiel García, VanguardiaSur
www.vanguardiasur.com.ar

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCHv3 3/8] rtc: add STM32 RTC driver
From: Mathieu Poirier @ 2017-01-05 17:33 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue, Russell King,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Gabriel Fernandez,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1483623809-29937-4-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>

On Thu, Jan 05, 2017 at 02:43:24PM +0100, Amelie Delaunay wrote:
> This patch adds support for the STM32 RTC.
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
> ---
>  drivers/rtc/Kconfig     |  11 +
>  drivers/rtc/Makefile    |   1 +
>  drivers/rtc/rtc-stm32.c | 776 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 788 insertions(+)
>  create mode 100644 drivers/rtc/rtc-stm32.c
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index e859d14..11eb28a 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1706,6 +1706,17 @@ config RTC_DRV_PIC32
>  	   This driver can also be built as a module. If so, the module
>  	   will be called rtc-pic32
>  
> +config RTC_DRV_STM32
> +	tristate "STM32 RTC"
> +	select REGMAP_MMIO
> +	depends on ARCH_STM32 || COMPILE_TEST
> +	help
> +	   If you say yes here you get support for the STM32 On-Chip
> +	   Real Time Clock.
> +
> +	   This driver can also be built as a module, if so, the module
> +	   will be called "rtc-stm32".
> +
>  comment "HID Sensor RTC drivers"
>  
>  config RTC_DRV_HID_SENSOR_TIME
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 1ac694a..87bd9cc 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -144,6 +144,7 @@ obj-$(CONFIG_RTC_DRV_SNVS)	+= rtc-snvs.o
>  obj-$(CONFIG_RTC_DRV_SPEAR)	+= rtc-spear.o
>  obj-$(CONFIG_RTC_DRV_STARFIRE)	+= rtc-starfire.o
>  obj-$(CONFIG_RTC_DRV_STK17TA8)	+= rtc-stk17ta8.o
> +obj-$(CONFIG_RTC_DRV_STM32) 	+= rtc-stm32.o
>  obj-$(CONFIG_RTC_DRV_STMP)	+= rtc-stmp3xxx.o
>  obj-$(CONFIG_RTC_DRV_ST_LPC)	+= rtc-st-lpc.o
>  obj-$(CONFIG_RTC_DRV_SUN4V)	+= rtc-sun4v.o
> diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
> new file mode 100644
> index 0000000..fdd3a31
> --- /dev/null
> +++ b/drivers/rtc/rtc-stm32.c
> @@ -0,0 +1,776 @@
> +/*
> + * Copyright (C) Amelie Delaunay 2016
> + * Author:  Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/bcd.h>
> +#include <linux/clk.h>
> +#include <linux/iopoll.h>
> +#include <linux/ioport.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/regmap.h>
> +#include <linux/rtc.h>
> +#include <linux/spinlock.h>
> +
> +#define DRIVER_NAME "stm32_rtc"
> +
> +/* STM32 RTC registers */
> +#define STM32_RTC_TR		0x00
> +#define STM32_RTC_DR		0x04
> +#define STM32_RTC_CR		0x08
> +#define STM32_RTC_ISR		0x0C
> +#define STM32_RTC_PRER		0x10
> +#define STM32_RTC_ALRMAR	0x1C
> +#define STM32_RTC_WPR		0x24
> +
> +/* STM32_RTC_TR bit fields  */
> +#define STM32_RTC_TR_SEC_SHIFT		0
> +#define STM32_RTC_TR_SEC		GENMASK(6, 0)
> +#define STM32_RTC_TR_MIN_SHIFT		8
> +#define STM32_RTC_TR_MIN		GENMASK(14, 8)
> +#define STM32_RTC_TR_HOUR_SHIFT		16
> +#define STM32_RTC_TR_HOUR		GENMASK(21, 16)
> +
> +/* STM32_RTC_DR bit fields */
> +#define STM32_RTC_DR_DATE_SHIFT		0
> +#define STM32_RTC_DR_DATE		GENMASK(5, 0)
> +#define STM32_RTC_DR_MONTH_SHIFT	8
> +#define STM32_RTC_DR_MONTH		GENMASK(12, 8)
> +#define STM32_RTC_DR_WDAY_SHIFT		13
> +#define STM32_RTC_DR_WDAY		GENMASK(15, 13)
> +#define STM32_RTC_DR_YEAR_SHIFT		16
> +#define STM32_RTC_DR_YEAR		GENMASK(23, 16)
> +
> +/* STM32_RTC_CR bit fields */
> +#define STM32_RTC_CR_FMT		BIT(6)
> +#define STM32_RTC_CR_ALRAE		BIT(8)
> +#define STM32_RTC_CR_ALRAIE		BIT(12)
> +
> +/* STM32_RTC_ISR bit fields */
> +#define STM32_RTC_ISR_ALRAWF		BIT(0)
> +#define STM32_RTC_ISR_INITS		BIT(4)
> +#define STM32_RTC_ISR_RSF		BIT(5)
> +#define STM32_RTC_ISR_INITF		BIT(6)
> +#define STM32_RTC_ISR_INIT		BIT(7)
> +#define STM32_RTC_ISR_ALRAF		BIT(8)
> +
> +/* STM32_RTC_PRER bit fields */
> +#define STM32_RTC_PRER_PRED_S_SHIFT	0
> +#define STM32_RTC_PRER_PRED_S		GENMASK(14, 0)
> +#define STM32_RTC_PRER_PRED_A_SHIFT	16
> +#define STM32_RTC_PRER_PRED_A		GENMASK(22, 16)
> +
> +/* STM32_RTC_ALRMAR and STM32_RTC_ALRMBR bit fields */
> +#define STM32_RTC_ALRMXR_SEC_SHIFT	0
> +#define STM32_RTC_ALRMXR_SEC		GENMASK(6, 0)
> +#define STM32_RTC_ALRMXR_SEC_MASK	BIT(7)
> +#define STM32_RTC_ALRMXR_MIN_SHIFT	8
> +#define STM32_RTC_ALRMXR_MIN		GENMASK(14, 8)
> +#define STM32_RTC_ALRMXR_MIN_MASK	BIT(15)
> +#define STM32_RTC_ALRMXR_HOUR_SHIFT	16
> +#define STM32_RTC_ALRMXR_HOUR		GENMASK(21, 16)
> +#define STM32_RTC_ALRMXR_PM		BIT(22)
> +#define STM32_RTC_ALRMXR_HOUR_MASK	BIT(23)
> +#define STM32_RTC_ALRMXR_DATE_SHIFT	24
> +#define STM32_RTC_ALRMXR_DATE		GENMASK(29, 24)
> +#define STM32_RTC_ALRMXR_WDSEL		BIT(30)
> +#define STM32_RTC_ALRMXR_WDAY_SHIFT	24
> +#define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)
> +#define STM32_RTC_ALRMXR_DATE_MASK	BIT(31)
> +
> +/* STM32_RTC_WPR key constants */
> +#define RTC_WPR_1ST_KEY			0xCA
> +#define RTC_WPR_2ND_KEY			0x53
> +#define RTC_WPR_WRONG_KEY		0xFF
> +
> +/*
> + * RTC registers are protected agains parasitic write access.
> + * PWR_CR_DBP bit must be set to enable write access to RTC registers.
> + */
> +/* STM32_PWR_CR */
> +#define PWR_CR				0x00
> +/* STM32_PWR_CR bit field */
> +#define PWR_CR_DBP			BIT(8)
> +
> +static struct regmap *dbp;
> +
> +struct stm32_rtc {
> +	struct rtc_device *rtc_dev;
> +	void __iomem *base;
> +	struct clk *ck_rtc;
> +	spinlock_t lock; /* Protects registers accesses */
> +	int irq_alarm;
> +};
> +
> +static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
> +{
> +	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
> +	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
> +}
> +
> +static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
> +{
> +	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
> +}
> +
> +static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
> +{
> +	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
> +
> +	if (!(isr & STM32_RTC_ISR_INITF)) {
> +		isr |= STM32_RTC_ISR_INIT;
> +		writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
> +
> +		/*
> +		 * It takes around 2 ck_rtc clock cycles to enter in
> +		 * initialization phase mode (and have INITF flag set). As
> +		 * slowest ck_rtc frequency may be 32kHz and highest should be
> +		 * 1MHz, we poll every 10 us with a timeout of 100ms.
> +		 */
> +		return readl_relaxed_poll_timeout_atomic(
> +					rtc->base + STM32_RTC_ISR,
> +					isr, (isr & STM32_RTC_ISR_INITF),
> +					10, 100000);
> +	}
> +
> +	return 0;
> +}
> +
> +static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
> +{
> +	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
> +
> +	isr &= ~STM32_RTC_ISR_INIT;
> +	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
> +}
> +
> +static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
> +{
> +	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
> +
> +	isr &= ~STM32_RTC_ISR_RSF;
> +	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
> +
> +	/*
> +	 * Wait for RSF to be set to ensure the calendar registers are
> +	 * synchronised, it takes around 2 ck_rtc clock cycles
> +	 */
> +	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
> +						 isr,
> +						 (isr & STM32_RTC_ISR_RSF),
> +						 10, 100000);
> +}
> +
> +static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
> +{
> +	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
> +	unsigned int isr, cr;
> +
> +	mutex_lock(&rtc->rtc_dev->ops_lock);
> +
> +	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
> +	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
> +
> +	if ((isr & STM32_RTC_ISR_ALRAF) &&
> +	    (cr & STM32_RTC_CR_ALRAIE)) {
> +		/* Alarm A flag - Alarm interrupt */
> +		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
> +
> +		/* Pass event to the kernel */
> +		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
> +
> +		/* Clear event flag, otherwise new events won't be received */
> +		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
> +			       rtc->base + STM32_RTC_ISR);
> +	}
> +
> +	mutex_unlock(&rtc->rtc_dev->ops_lock);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +/* Convert rtc_time structure from bin to bcd format */
> +static void tm2bcd(struct rtc_time *tm)
> +{
> +	tm->tm_sec = bin2bcd(tm->tm_sec);
> +	tm->tm_min = bin2bcd(tm->tm_min);
> +	tm->tm_hour = bin2bcd(tm->tm_hour);
> +
> +	tm->tm_mday = bin2bcd(tm->tm_mday);
> +	tm->tm_mon = bin2bcd(tm->tm_mon + 1);
> +	tm->tm_year = bin2bcd(tm->tm_year - 100);
> +	/*
> +	 * Number of days since Sunday
> +	 * - on kernel side, 0=Sunday...6=Saturday
> +	 * - on rtc side, 0=invalid,1=Monday...7=Sunday
> +	 */
> +	tm->tm_wday = (!tm->tm_wday) ? 7 : tm->tm_wday;
> +}
> +
> +/* Convert rtc_time structure from bcd to bin format */
> +static void bcd2tm(struct rtc_time *tm)
> +{
> +	tm->tm_sec = bcd2bin(tm->tm_sec);
> +	tm->tm_min = bcd2bin(tm->tm_min);
> +	tm->tm_hour = bcd2bin(tm->tm_hour);
> +
> +	tm->tm_mday = bcd2bin(tm->tm_mday);
> +	tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
> +	tm->tm_year = bcd2bin(tm->tm_year) + 100;
> +	/*
> +	 * Number of days since Sunday
> +	 * - on kernel side, 0=Sunday...6=Saturday
> +	 * - on rtc side, 0=invalid,1=Monday...7=Sunday
> +	 */
> +	tm->tm_wday %= 7;
> +}
> +
> +static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned int tr, dr;
> +	unsigned long irqflags;
> +
> +	spin_lock_irqsave(&rtc->lock, irqflags);
> +
> +	/* Time and Date in BCD format */
> +	tr = readl_relaxed(rtc->base + STM32_RTC_TR);
> +	dr = readl_relaxed(rtc->base + STM32_RTC_DR);
> +
> +	spin_unlock_irqrestore(&rtc->lock, irqflags);
> +
> +	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
> +	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
> +	tm->tm_hour = (tr & STM32_RTC_TR_HOUR) >> STM32_RTC_TR_HOUR_SHIFT;
> +
> +	tm->tm_mday = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
> +	tm->tm_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
> +	tm->tm_year = (dr & STM32_RTC_DR_YEAR) >> STM32_RTC_DR_YEAR_SHIFT;
> +	tm->tm_wday = (dr & STM32_RTC_DR_WDAY) >> STM32_RTC_DR_WDAY_SHIFT;
> +
> +	/* We don't report tm_yday and tm_isdst */
> +
> +	bcd2tm(tm);
> +
> +	if (rtc_valid_tm(tm) < 0) {
> +		dev_err(dev, "%s: rtc_time is not valid.\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned int tr, dr;
> +	unsigned long irqflags;
> +	int ret = 0;
> +
> +	if (rtc_valid_tm(tm) < 0) {
> +		dev_err(dev, "%s: rtc_time is not valid.\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	tm2bcd(tm);
> +
> +	/* Time in BCD format */
> +	tr = ((tm->tm_sec << STM32_RTC_TR_SEC_SHIFT) & STM32_RTC_TR_SEC) |
> +	     ((tm->tm_min << STM32_RTC_TR_MIN_SHIFT) & STM32_RTC_TR_MIN) |
> +	     ((tm->tm_hour << STM32_RTC_TR_HOUR_SHIFT) & STM32_RTC_TR_HOUR);
> +
> +	/* Date in BCD format */
> +	dr = ((tm->tm_mday << STM32_RTC_DR_DATE_SHIFT) & STM32_RTC_DR_DATE) |
> +	     ((tm->tm_mon << STM32_RTC_DR_MONTH_SHIFT) & STM32_RTC_DR_MONTH) |
> +	     ((tm->tm_year << STM32_RTC_DR_YEAR_SHIFT) & STM32_RTC_DR_YEAR) |
> +	     ((tm->tm_wday << STM32_RTC_DR_WDAY_SHIFT) & STM32_RTC_DR_WDAY);
> +
> +	spin_lock_irqsave(&rtc->lock, irqflags);
> +
> +	stm32_rtc_wpr_unlock(rtc);
> +
> +	ret = stm32_rtc_enter_init_mode(rtc);
> +	if (ret) {
> +		dev_err(dev, "Can't enter in init mode. Set time aborted.\n");
> +		goto end;
> +	}
> +
> +	writel_relaxed(tr, rtc->base + STM32_RTC_TR);
> +	writel_relaxed(dr, rtc->base + STM32_RTC_DR);
> +
> +	stm32_rtc_exit_init_mode(rtc);
> +
> +	ret = stm32_rtc_wait_sync(rtc);
> +end:
> +	stm32_rtc_wpr_lock(rtc);
> +
> +	spin_unlock_irqrestore(&rtc->lock, irqflags);
> +
> +	return ret;
> +}
> +
> +static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +	struct rtc_time *tm = &alrm->time;
> +	unsigned int alrmar, cr, isr;
> +	unsigned long irqflags;
> +
> +	spin_lock_irqsave(&rtc->lock, irqflags);
> +
> +	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
> +	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
> +	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
> +
> +	spin_unlock_irqrestore(&rtc->lock, irqflags);
> +
> +	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
> +		/*
> +		 * Date/day doesn't matter in Alarm comparison so alarm
> +		 * triggers every day
> +		 */
> +		tm->tm_mday = -1;
> +		tm->tm_wday = -1;
> +	} else {
> +		if (alrmar & STM32_RTC_ALRMXR_WDSEL) {
> +			/* Alarm is set to a day of week */
> +			tm->tm_mday = -1;
> +			tm->tm_wday = (alrmar & STM32_RTC_ALRMXR_WDAY) >>
> +				      STM32_RTC_ALRMXR_WDAY_SHIFT;
> +			tm->tm_wday %= 7;
> +		} else {
> +			/* Alarm is set to a day of month */
> +			tm->tm_wday = -1;
> +			tm->tm_mday = (alrmar & STM32_RTC_ALRMXR_DATE) >>
> +				       STM32_RTC_ALRMXR_DATE_SHIFT;
> +		}
> +	}
> +
> +	if (alrmar & STM32_RTC_ALRMXR_HOUR_MASK) {
> +		/* Hours don't matter in Alarm comparison */
> +		tm->tm_hour = -1;
> +	} else {
> +		tm->tm_hour = (alrmar & STM32_RTC_ALRMXR_HOUR) >>
> +			       STM32_RTC_ALRMXR_HOUR_SHIFT;
> +		if (alrmar & STM32_RTC_ALRMXR_PM)
> +			tm->tm_hour += 12;
> +	}
> +
> +	if (alrmar & STM32_RTC_ALRMXR_MIN_MASK) {
> +		/* Minutes don't matter in Alarm comparison */
> +		tm->tm_min = -1;
> +	} else {
> +		tm->tm_min = (alrmar & STM32_RTC_ALRMXR_MIN) >>
> +			      STM32_RTC_ALRMXR_MIN_SHIFT;
> +	}
> +
> +	if (alrmar & STM32_RTC_ALRMXR_SEC_MASK) {
> +		/* Seconds don't matter in Alarm comparison */
> +		tm->tm_sec = -1;
> +	} else {
> +		tm->tm_sec = (alrmar & STM32_RTC_ALRMXR_SEC) >>
> +			      STM32_RTC_ALRMXR_SEC_SHIFT;
> +	}
> +
> +	bcd2tm(tm);
> +
> +	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
> +	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
> +
> +	return 0;
> +}
> +
> +static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +	unsigned long irqflags;
> +	unsigned int isr, cr;
> +
> +	spin_lock_irqsave(&rtc->lock, irqflags);
> +
> +	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
> +
> +	stm32_rtc_wpr_unlock(rtc);
> +
> +	/* We expose Alarm A to the kernel */
> +	if (enabled)
> +		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
> +	else
> +		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
> +	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
> +
> +	/* Clear event irqflags, otherwise new events won't be received */
> +	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
> +	isr &= ~STM32_RTC_ISR_ALRAF;
> +	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
> +
> +	stm32_rtc_wpr_lock(rtc);
> +
> +	spin_unlock_irqrestore(&rtc->lock, irqflags);
> +
> +	return 0;
> +}
> +
> +static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
> +{
> +	unsigned int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
> +	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
> +	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
> +
> +	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
> +	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
> +	cur_year = (dr & STM32_RTC_DR_YEAR) >> STM32_RTC_DR_YEAR_SHIFT;
> +	cur_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
> +	cur_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
> +	cur_hour = (tr & STM32_RTC_TR_HOUR) >> STM32_RTC_TR_HOUR_SHIFT;
> +
> +	/*
> +	 * Assuming current date is M-D-Y H:M:S.
> +	 * RTC alarm can't be set on a specific month and year.
> +	 * So the valid alarm range is:
> +	 *	M-D-Y H:M:S < alarm <= (M+1)-D-Y H:M:S
> +	 * with a specific case for December...
> +	 */
> +	if ((((tm->tm_year > cur_year) &&
> +	      (tm->tm_mon == 0x1) && (cur_mon == 0x12)) ||
> +	     ((tm->tm_year == cur_year) &&
> +	      (tm->tm_mon <= cur_mon + 1))) &&
> +	    ((tm->tm_mday < cur_day) ||
> +	     ((tm->tm_mday == cur_day) &&
> +	     ((tm->tm_hour < cur_hour) ||
> +	      ((tm->tm_hour == cur_hour) && (tm->tm_min < cur_min)) ||
> +	      ((tm->tm_hour == cur_hour) && (tm->tm_min == cur_min) &&
> +	       (tm->tm_sec <= cur_sec))))))
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
> +static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +	struct rtc_time *tm = &alrm->time;
> +	unsigned long irqflags;
> +	unsigned int cr, isr, alrmar;
> +	int ret = 0;
> +
> +	if (rtc_valid_tm(tm)) {
> +		dev_err(dev, "Alarm time not valid.\n");
> +		return -EINVAL;
> +	}
> +
> +	tm2bcd(tm);
> +
> +	/*
> +	 * RTC alarm can't be set on a specific date, unless this date is
> +	 * up to the same day of month next month.
> +	 */
> +	if (stm32_rtc_valid_alrm(rtc, tm) < 0) {
> +		dev_err(dev, "Alarm can be set only on upcoming month.\n");
> +		return -EINVAL;
> +	}
> +
> +	alrmar = 0;
> +	/* tm_year and tm_mon are not used because not supported by RTC */
> +	alrmar |= (tm->tm_mday << STM32_RTC_ALRMXR_DATE_SHIFT) &
> +		  STM32_RTC_ALRMXR_DATE;
> +	/* 24-hour format */
> +	alrmar &= ~STM32_RTC_ALRMXR_PM;
> +	alrmar |= (tm->tm_hour << STM32_RTC_ALRMXR_HOUR_SHIFT) &
> +		  STM32_RTC_ALRMXR_HOUR;
> +	alrmar |= (tm->tm_min << STM32_RTC_ALRMXR_MIN_SHIFT) &
> +		  STM32_RTC_ALRMXR_MIN;
> +	alrmar |= (tm->tm_sec << STM32_RTC_ALRMXR_SEC_SHIFT) &
> +		  STM32_RTC_ALRMXR_SEC;
> +
> +	spin_lock_irqsave(&rtc->lock, irqflags);
> +
> +	stm32_rtc_wpr_unlock(rtc);
> +
> +	/* Disable Alarm */
> +	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
> +	cr &= ~STM32_RTC_CR_ALRAE;
> +	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
> +
> +	/*
> +	 * Poll Alarm write flag to be sure that Alarm update is allowed: it
> +	 * takes around 2 ck_rtc clock cycles
> +	 */
> +	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
> +						isr,
> +						(isr & STM32_RTC_ISR_ALRAWF),
> +						10, 100000);
> +
> +	if (ret) {
> +		dev_err(dev, "Alarm update not allowed\n");
> +		goto end;
> +	}
> +
> +	/* Write to Alarm register */
> +	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
> +
> +	if (alrm->enabled)
> +		stm32_rtc_alarm_irq_enable(dev, 1);
> +	else
> +		stm32_rtc_alarm_irq_enable(dev, 0);
> +
> +end:
> +	stm32_rtc_wpr_lock(rtc);
> +
> +	spin_unlock_irqrestore(&rtc->lock, irqflags);
> +
> +	return ret;
> +}
> +
> +static const struct rtc_class_ops stm32_rtc_ops = {
> +	.read_time	= stm32_rtc_read_time,
> +	.set_time	= stm32_rtc_set_time,
> +	.read_alarm	= stm32_rtc_read_alarm,
> +	.set_alarm	= stm32_rtc_set_alarm,
> +	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
> +};
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id stm32_rtc_of_match[] = {
> +	{ .compatible = "st,stm32-rtc" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
> +#endif
> +
> +static int stm32_rtc_init(struct platform_device *pdev,
> +			  struct stm32_rtc *rtc)
> +{
> +	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
> +	unsigned int rate;
> +	unsigned long irqflags;
> +	int ret = 0;
> +
> +	rate = clk_get_rate(rtc->ck_rtc);
> +
> +	/* Find prediv_a and prediv_s to obtain the 1Hz calendar clock */
> +	pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT;
> +	pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT;
> +
> +	for (pred_a = pred_a_max; pred_a >= 0; pred_a--) {
> +		pred_s = (rate / (pred_a + 1)) - 1;
> +
> +		if (((pred_s + 1) * (pred_a + 1)) == rate)
> +			break;
> +	}
> +
> +	/*
> +	 * Can't find a 1Hz, so give priority to RTC power consumption
> +	 * by choosing the higher possible value for prediv_a
> +	 */
> +	if ((pred_s > pred_s_max) || (pred_a > pred_a_max)) {
> +		pred_a = pred_a_max;
> +		pred_s = (rate / (pred_a + 1)) - 1;
> +
> +		dev_warn(&pdev->dev, "ck_rtc is %s\n",
> +			 (rate - ((pred_a + 1) * (pred_s + 1)) < 0) ?
> +			 "fast" : "slow");
> +	}
> +
> +	spin_lock_irqsave(&rtc->lock, irqflags);
> +
> +	stm32_rtc_wpr_unlock(rtc);
> +
> +	ret = stm32_rtc_enter_init_mode(rtc);
> +	if (ret) {
> +		dev_err(&pdev->dev,
> +			"Can't enter in init mode. Prescaler config failed.\n");
> +		goto end;
> +	}
> +
> +	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
> +	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
> +	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
> +	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
> +
> +	/* Force 24h time format */
> +	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
> +	cr &= ~STM32_RTC_CR_FMT;
> +	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
> +
> +	stm32_rtc_exit_init_mode(rtc);
> +
> +	ret = stm32_rtc_wait_sync(rtc);
> +end:
> +	stm32_rtc_wpr_lock(rtc);
> +
> +	spin_unlock_irqrestore(&rtc->lock, irqflags);
> +
> +	return ret;
> +}
> +
> +static int stm32_rtc_probe(struct platform_device *pdev)
> +{
> +	struct stm32_rtc *rtc;
> +	struct resource *res;
> +	int ret;
> +
> +	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
> +	if (!rtc)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	rtc->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(rtc->base))
> +		return PTR_ERR(rtc->base);
> +
> +	dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "st,syscfg");
> +	if (IS_ERR(dbp)) {
> +		dev_err(&pdev->dev, "no st,syscfg\n");
> +		return PTR_ERR(dbp);
> +	}
> +
> +	spin_lock_init(&rtc->lock);
> +
> +	rtc->ck_rtc = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(rtc->ck_rtc)) {
> +		dev_err(&pdev->dev, "no ck_rtc clock");
> +		return PTR_ERR(rtc->ck_rtc);
> +	}
> +
> +	ret = clk_prepare_enable(rtc->ck_rtc);
> +	if (ret)
> +		return ret;
> +
> +	regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, PWR_CR_DBP);
> +
> +	/*
> +	 * After a system reset, RTC_ISR.INITS flag can be read to check if
> +	 * the calendar has been initalized or not. INITS flag is reset by a
> +	 * power-on reset (no vbat, no power-supply). It is not reset if
> +	 * ck_rtc parent clock has changed (so RTC prescalers need to be
> +	 * changed). That's why we cannot rely on this flag to know if RTC
> +	 * init has to be done.
> +	 */
> +	ret = stm32_rtc_init(pdev, rtc);
> +	if (ret)
> +		goto err;
> +
> +	rtc->irq_alarm = platform_get_irq(pdev, 0);
> +	if (rtc->irq_alarm <= 0) {
> +		dev_err(&pdev->dev, "no alarm irq\n");
> +		ret = rtc->irq_alarm;
> +		goto err;
> +	}
> +
> +	platform_set_drvdata(pdev, rtc);
> +
> +	ret = device_init_wakeup(&pdev->dev, true);
> +	if (ret)
> +		dev_warn(&pdev->dev,
> +			 "alarm won't be able to wake up the system");
> +
> +	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
> +			&stm32_rtc_ops, THIS_MODULE);
> +	if (IS_ERR(rtc->rtc_dev)) {
> +		ret = PTR_ERR(rtc->rtc_dev);
> +		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
> +			ret);
> +		goto err;
> +	}
> +
> +	/* Handle RTC alarm interrupts */
> +	ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_alarm, NULL,
> +					stm32_rtc_alarm_irq,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +					pdev->name, rtc);
> +	if (ret) {
> +		dev_err(&pdev->dev, "IRQ%d (alarm interrupt) already claimed\n",
> +			rtc->irq_alarm);
> +		goto err;
> +	}
> +
> +	/*
> +	 * If INITS flag is reset (calendar year field set to 0x00), calendar
> +	 * must be initialized
> +	 */
> +	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
> +		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
> +
> +	return 0;
> +err:
> +	clk_disable_unprepare(rtc->ck_rtc);
> +
> +	regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, ~PWR_CR_DBP);
> +
> +	device_init_wakeup(&pdev->dev, false);
> +
> +	return ret;
> +}
> +
> +static int __exit stm32_rtc_remove(struct platform_device *pdev)
> +{
> +	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
> +	unsigned int cr;
> +
> +	/* Disable interrupts */
> +	stm32_rtc_wpr_unlock(rtc);
> +	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
> +	cr &= ~STM32_RTC_CR_ALRAIE;
> +	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
> +	stm32_rtc_wpr_lock(rtc);
> +
> +	clk_disable_unprepare(rtc->ck_rtc);
> +
> +	/* Enable backup domain write protection */
> +	regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, ~PWR_CR_DBP);
> +
> +	device_init_wakeup(&pdev->dev, false);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int stm32_rtc_suspend(struct device *dev)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +
> +	if (device_may_wakeup(dev))
> +		return enable_irq_wake(rtc->irq_alarm);
> +
> +	return 0;
> +}
> +
> +static int stm32_rtc_resume(struct device *dev)
> +{
> +	struct stm32_rtc *rtc = dev_get_drvdata(dev);
> +	int ret = 0;
> +
> +	ret = stm32_rtc_wait_sync(rtc);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (device_may_wakeup(dev))
> +		return disable_irq_wake(rtc->irq_alarm);
> +
> +	return ret;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(stm32_rtc_pm_ops,
> +			 stm32_rtc_suspend, stm32_rtc_resume);
> +
> +static struct platform_driver stm32_rtc_driver = {
> +	.probe		= stm32_rtc_probe,
> +	.remove		= stm32_rtc_remove,
> +	.driver		= {
> +		.name	= DRIVER_NAME,
> +		.pm	= &stm32_rtc_pm_ops,
> +		.of_match_table = stm32_rtc_of_match,
> +	},
> +};
> +
> +module_platform_driver(stm32_rtc_driver);
> +
> +MODULE_ALIAS("platform:" DRIVER_NAME);
> +MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>");
> +MODULE_DESCRIPTION("STMicroelectronics STM32 Real Time Clock driver");
> +MODULE_LICENSE("GPL v2");

Looks much better now.

Reviewed-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] ARM: dts: am335x-icev2: Remove the duplicated pinmux setting
From: Tony Lindgren @ 2017-01-05 17:31 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Linux OMAP Mailing List, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Tero Kristo, Sekhar Nori,
	Linux ARM Mailing List
In-Reply-To: <20170104050940.25698-1-lokeshvutla-l0cyMroinI0@public.gmane.org>

* Lokesh Vutla <lokeshvutla-l0cyMroinI0@public.gmane.org> [170103 21:12]:
> There is no mmc sd card detect on am335x-ice board. But the spi0_cs1
> pin being configured as mmcsd_cd. Removing it fixes the below warning
> during boot.

Applying into omap-for-v4.11/fixes thanks.

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/3] ARM64: dts: exynos5433: add DECON_TV node
From: Krzysztof Kozlowski @ 2017-01-05 17:26 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: linux-samsung-soc, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Marek Szyprowski, Inki Dae, Rob Herring, Mark Rutland,
	Javier Martinez Canillas, devicetree
In-Reply-To: <1483629943-31183-1-git-send-email-a.hajda@samsung.com>

On Thu, Jan 05, 2017 at 04:25:41PM +0100, Andrzej Hajda wrote:
> DECON_TV is 2nd display controller on Exynos5433, used in HDMI path
> or 2nd DSI path.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  arch/arm64/boot/dts/exynos/exynos5433.dtsi | 44 ++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> index 8cbfd1d..b47951b 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> @@ -821,6 +821,28 @@
>  			};
>  		};
>  
> +		decon_tv: decon@13880000 {
> +			compatible = "samsung,exynos5433-decon-tv";
> +			reg = <0x13880000 0x20B8>;
> +			clocks = <&cmu_disp CLK_PCLK_DECON_TV>,
> +				 <&cmu_disp CLK_ACLK_DECON_TV>,
> +				 <&cmu_disp CLK_ACLK_SMMU_TV0X>,
> +				 <&cmu_disp CLK_ACLK_XIU_TV0X>,
> +				 <&cmu_disp CLK_PCLK_SMMU_TV0X>,
> +				 <&cmu_disp CLK_SCLK_DECON_TV_VCLK>,
> +				 <&cmu_disp CLK_SCLK_DECON_TV_ECLK>;
> +			clock-names = "pclk", "aclk_decon", "aclk_smmu_decon0x",
> +				      "aclk_xiu_decon0x", "pclk_smmu_decon0x",
> +				      "sclk_decon_vclk", "sclk_decon_eclk";
> +			samsung,disp-sysreg = <&syscon_disp>;
> +			interrupt-names = "fifo", "vsync", "lcd_sys";
> +			interrupts = <0 210 0>, <0 211 0>, <0 212 0>;
> +			power-domains = <&pd_disp>;
> +			status = "disabled";
> +			iommus = <&sysmmu_tv0x>, <&sysmmu_tv1x>;
> +			iommu-names = "m0", "m1";
> +		};
> +
>  		syscon_disp: syscon@13b80000 {
>  			compatible = "syscon";
>  			reg = <0x13b80000 0x1010>;
> @@ -926,6 +948,28 @@
>  			power-domains = <&pd_disp>;
>  		};
>  
> +		sysmmu_tv0x: sysmmu@0x13a20000 {

Without the '0x' in the address, please. I see that you copied it from
existing nodes, so maybe you could fix them as well in following patch.

Beside that (and Javier's comments) looks okay, but please choose
suitable subject prefix matching recent commits. I think it is the third
time I am mentioning this recently (to different Samsung folks,
though)... 

Best regards,
Krzysztof

^ permalink raw reply

* Re: [RFC 1/3] iommu/arm-smmu: Add support to opt-in to stalling
From: Will Deacon @ 2017-01-05 17:25 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Mark Rutland, robh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Jordan Crouse
In-Reply-To: <611575f4-3e37-1f4d-ef29-94e6f65baf66-5wv7dgnIgG8@public.gmane.org>

On Thu, Jan 05, 2017 at 05:03:30PM +0000, Robin Murphy wrote:
> On 05/01/17 16:07, Will Deacon wrote:
> > On Thu, Jan 05, 2017 at 03:32:50PM +0000, Robin Murphy wrote:
> >> I think this needs to be some kind of "arm,smmu-stall-safe" property
> >> placed on individual master device nodes (mad idea: or even an extra
> >> cell of flags in the IOMMU specifier) to encapsulate both that the given
> >> device itself is OK with being stalled, and that it's integrated in such
> >> a way that its stalled transactions cannot disrupt any *other* device
> >> (e.g. it has a TBU all to itself). Then upon initialising a context bank
> >> on a suitable SMMU implementation, we set CFCFG based on whatever device
> >> is being attached to the corresponding domain, and refuse any subsequent
> >> attempts to attach a non-stallable device to a stalling domain (and
> >> possibly even vice-versa).
> > 
> > If we're going to add per-master properties, I'd *really* like them to be
> > independent of the IOMMU in use. That is, we should be able to re-use this
> > property as part of supporting SVM for platform devices in future.
> 
> I'd argue that they are still fairly separate things despite the
> overlap: stalling is a specific ARM SMMU architecture thing (in both
> architectures) which may be used for purposes unrelated to SVM;
> conversely SVM implemented via PRI or similar mechanisms should be
> pretty much oblivious to the transaction fault model.

But SVM for a platform device is likely to require working stalls, so
they're highly related concepts. Having the former be a generic property
but the second tied to the SMMU means we have to duplicate information
(that is, we end up with a generic "SVM-capable" property that implies
that stalling works). I don't think we want that at all.

> > But I think we agree that we need:
> > 
> >   1. A compatible string for the SMMU that can be used to infer the SS
> >      behaviour in the driver
> > 
> >   2. A property on the SMMU to say that it's been integrated in such a
> >      way that stalling is safe (doesn't deadlock)
> 
> That's still got to be a per-master property, not a SMMU property, I
> think. To illustrate:
> 
>   [A]         [B]   [C]
>    |           |_____|
>  __|______________|___
> | TBU |        | TBU |
> |_____|  SMMU  |_____|
> |__|______________|__|
>    |              |
> 
> Say A and B are instances of some device happy to be stalled, and C is a
> PCIe RC, and each is attached to their own context bank - enabling
> stalls for A is definitely fine. However even though B and C are using
> different context banks, enabling stalls for B might deadlock C if it
> results in more total outstanding transactions than the TBU's slave port
> supports. Therefore A can happily claim to be stall-safe, but B cannot
> due to its integration with respect to C.

So in this case, don't say that B and C can DMA to unpinned memory. You
need the third property. This property (property 2) is concerned with the
SMMU itself because, e.g. the way the walker has been integrated can
cause a deadlock.

> And yes, I can point you at some existing hardware which really does
> posess a topology like that.
> 
> >   3. A generic master property that says that the device can DMA to
> >      unpinned memory
> 
> That sounds a bit *too* generic to me, given that there are multiple
> incompatible ways that could be implemented. I'm not the biggest fan of
> properties with heavily context-specific interpretations, especially
> when there's more than a hint of software implementation details in the mix.

So what would you propose for SVM? I really want that to be opt-in, so a
per-master flag seems like the right way forward to me.

Will

^ permalink raw reply

* [PATCH v2] iio:temperature: Add support for TI TMP007 sensor
From: Mani Sadhasivam @ 2017-01-05 17:24 UTC (permalink / raw)
  To: jic23-DgEjT+Ai2ygdnm+yROfE0A, pmeerw-jW+XmwGofnusTnJN9+BGXg
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA

This patch adds support for TI TMP007 - 16 bit IR thermopile sensor with integrated Math engine.
Sensor takes care of calculating the object temperature with the help of calibrated constants stored in non-volatile memory,
reducing the calculation overhead.

Signed-off-by: Mani Sadhasivam <manivannanece23-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../devicetree/bindings/iio/temperature/tmp007.txt |  16 +
 drivers/iio/temperature/Kconfig                    |  10 +
 drivers/iio/temperature/Makefile                   |   1 +
 drivers/iio/temperature/tmp007.c                   | 338 +++++++++++++++++++++
 4 files changed, 365 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/temperature/tmp007.txt
 create mode 100644 drivers/iio/temperature/tmp007.c

diff --git a/Documentation/devicetree/bindings/iio/temperature/tmp007.txt b/Documentation/devicetree/bindings/iio/temperature/tmp007.txt
new file mode 100644
index 0000000..9ae0519
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/tmp007.txt
@@ -0,0 +1,16 @@
+* TI TMP007 - IR thermopile sensor with integrated math engine
+
+Link to datasheet: http://www.ti.com/lit/ds/symlink/tmp007.pdf
+
+Required properties:
+
+  - compatible: should be "ti,tmp007"
+  - reg: the I2C address of the sensor (changeable via ADR pins)
+
+Example:
+
+tmp007@40 {
+        compatible = "ti,tmp007";
+        reg = <0x40>;
+};
+
diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index c4664e5..538ce9e 100644
--- a/drivers/iio/temperature/Kconfig
+++ b/drivers/iio/temperature/Kconfig
@@ -23,6 +23,16 @@ config TMP006
 	  This driver can also be built as a module. If so, the module will
 	  be called tmp006.
 
+config TMP007
+        tristate "TMP007 infrared thermopile sensor with Integrated Math Engine"
+        depends on I2C
+        help
+          If you say yes here you get support for the Texas Instruments
+          TMP007 infrared thermopile sensor with Integrated Math Engine.
+
+          This driver can also be built as a module. If so, the module will
+          be called tmp007.
+
 config TSYS01
 	tristate "Measurement Specialties TSYS01 temperature sensor using I2C bus connection"
 	depends on I2C
diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile
index 02bc79d..f0cf5c5 100644
--- a/drivers/iio/temperature/Makefile
+++ b/drivers/iio/temperature/Makefile
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_MLX90614) += mlx90614.o
 obj-$(CONFIG_TMP006) += tmp006.o
+obj-$(CONFIG_TMP007) += tmp007.o
 obj-$(CONFIG_TSYS01) += tsys01.o
 obj-$(CONFIG_TSYS02D) += tsys02d.o
diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c
new file mode 100644
index 0000000..b76fecc
--- /dev/null
+++ b/drivers/iio/temperature/tmp007.c
@@ -0,0 +1,338 @@
+/*
+ * tmp007.c - Support for TI TMP007 IR thermopile sensor with integrated math engine
+ *
+ * Copyright (c) 2017 Manivannan Sadhasivam <manivannanece23-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Driver for the Texas Instruments I2C 16-bit IR thermopile sensor
+ *
+ * (7-bit I2C slave address (0x40 - 0x47), changeable via ADR pins)
+ *
+ * Note: This driver assumes that the sensor has been calibrated beforehand
+ *
+ * TODO: ALERT irq, limit threshold events
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+#include <linux/of.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define TMP007_TDIE 0x01
+#define TMP007_CONFIG 0x02
+#define TMP007_TOBJECT 0x03
+#define TMP007_STATUS 0x04
+#define TMP007_STATUS_MASK 0x05
+#define TMP007_MANUFACTURER_ID 0x1e
+#define TMP007_DEVICE_ID 0x1f
+
+#define TMP007_CONFIG_CONV_EN BIT(12)
+#define TMP007_CONFIG_COMP_EN BIT(5)
+#define TMP007_CONFIG_TC_EN BIT(6)
+#define TMP007_CONFIG_CR_MASK GENMASK(11, 9)
+#define TMP007_CONFIG_CR_SHIFT 9
+
+#define TMP007_STATUS_CONV_READY BIT(14)
+#define TMP007_STATUS_DATA_VALID BIT(9)
+
+#define TMP007_MANUFACTURER_MAGIC 0x5449
+#define TMP007_DEVICE_MAGIC 0x0078
+
+#define TMP007_TEMP_SHIFT 2
+
+struct tmp007_data {
+	struct i2c_client *client;
+	u16 config;
+	u16 status_mask;
+};
+
+static const int tmp007_avgs[5][2] = { {4, 0}, {2, 0}, {1, 0},
+					{0, 500000}, {0, 250000} };
+
+static int tmp007_read_temperature(struct tmp007_data *data, u8 reg)
+{
+	s32 ret;
+	int tries = 50;
+
+	while (tries-- > 0) {
+		ret = i2c_smbus_read_word_swapped(data->client,
+			TMP007_STATUS);
+		if (ret < 0)
+			return ret;
+		if ((ret & TMP007_STATUS_CONV_READY) &&
+			!(ret & TMP007_STATUS_DATA_VALID))
+				break;
+		msleep(100);
+	}
+
+	if (tries < 0)
+		return -EIO;
+
+	return i2c_smbus_read_word_swapped(data->client, reg);
+}
+
+static int tmp007_powerdown(struct tmp007_data *data)
+{
+	return i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
+			data->config & ~TMP007_CONFIG_CONV_EN);
+}
+
+static int tmp007_read_raw(struct iio_dev *indio_dev,
+		struct iio_chan_spec const *channel, int *val,
+		int *val2, long mask)
+{
+	struct tmp007_data *data = iio_priv(indio_dev);
+	s32 ret;
+	int conv_rate;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (channel->channel2) {
+		case IIO_MOD_TEMP_AMBIENT: /* LSB: 0.03125 degree Celsius */
+			ret = i2c_smbus_read_word_swapped(data->client, TMP007_TDIE);
+			if (ret < 0)
+				return ret;
+			break;
+		case IIO_MOD_TEMP_OBJECT:
+			ret = tmp007_read_temperature(data, TMP007_TOBJECT);
+			if (ret < 0)
+				return ret;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		*val = sign_extend32(ret, 15) >> TMP007_TEMP_SHIFT;
+
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 31;
+		*val2 = 250000;
+
+		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		conv_rate = (data->config & TMP007_CONFIG_CR_MASK)
+				>> TMP007_CONFIG_CR_SHIFT;
+		*val = tmp007_avgs[conv_rate][0];
+		*val2 = tmp007_avgs[conv_rate][1];
+
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int tmp007_write_raw(struct iio_dev *indio_dev,
+		struct iio_chan_spec const *channel, int val,
+		int val2, long mask)
+{
+	struct tmp007_data *data = iio_priv(indio_dev);
+	int i;
+	u16 tmp;
+
+	if (mask == IIO_CHAN_INFO_SAMP_FREQ) {
+		for (i = 0; i < ARRAY_SIZE(tmp007_avgs); i++) {
+			if ((val == tmp007_avgs[i][0]) &&
+			(val2 == tmp007_avgs[i][1])) {
+				tmp = data->config & ~TMP007_CONFIG_CR_MASK;
+				tmp |= (i << TMP007_CONFIG_CR_SHIFT);
+
+				return i2c_smbus_write_word_swapped(data->client,
+								TMP007_CONFIG,
+								data->config = tmp);
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
+
+static struct attribute *tmp007_attributes[] = {
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group tmp007_attribute_group = {
+	.attrs = tmp007_attributes,
+};
+
+static const struct iio_chan_spec tmp007_channels[] = {
+	{
+		.type = IIO_TEMP,
+		.modified = 1,
+		.channel2 = IIO_MOD_TEMP_AMBIENT,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				BIT(IIO_CHAN_INFO_SCALE),
+		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+	},
+	{
+		.type = IIO_TEMP,
+		.modified = 1,
+		.channel2 = IIO_MOD_TEMP_OBJECT,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				BIT(IIO_CHAN_INFO_SCALE),
+		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+	}
+};
+
+static const struct iio_info tmp007_info = {
+	.read_raw = tmp007_read_raw,
+	.write_raw = tmp007_write_raw,
+	.attrs = &tmp007_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static bool tmp007_identify(struct i2c_client *client)
+{
+	int manf_id, dev_id;
+
+	manf_id = i2c_smbus_read_word_swapped(client, TMP007_MANUFACTURER_ID);
+	if (manf_id < 0)
+		return false;
+
+	dev_id = i2c_smbus_read_word_swapped(client, TMP007_DEVICE_ID);
+	if (dev_id < 0)
+		return false;
+
+	return (manf_id == TMP007_MANUFACTURER_MAGIC && dev_id == TMP007_DEVICE_MAGIC);
+}
+
+static int tmp007_probe(struct i2c_client *client,
+			const struct i2c_device_id *tmp007_id)
+{
+	struct tmp007_data *data;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
+		return -EOPNOTSUPP;
+
+	if (!tmp007_identify(client)) {
+		dev_err(&client->dev, "TMP007 not found\n");
+		return -ENODEV;
+	}
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = dev_name(&client->dev);
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &tmp007_info;
+
+	indio_dev->channels = tmp007_channels;
+	indio_dev->num_channels = ARRAY_SIZE(tmp007_channels);
+
+	/* Set Configuration register:
+	 * 1. Conversion ON
+	 * 2. Comparator mode
+	 * 3. Transient correction enable
+	 */
+
+	ret = i2c_smbus_read_word_swapped(data->client, TMP007_CONFIG);
+	if (ret < 0)
+		return ret;
+
+	data->config = ret;
+	data->config |= (TMP007_CONFIG_CONV_EN | TMP007_CONFIG_COMP_EN | TMP007_CONFIG_TC_EN);
+
+	ret = i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
+					data->config);
+	if (ret < 0)
+		return ret;
+
+	/* Set Status Mask register:
+	 * 1. Conversion ready enable
+	 */
+
+	ret = i2c_smbus_read_word_swapped(data->client, TMP007_STATUS_MASK);
+	if (ret < 0)
+		return tmp007_powerdown(data);
+
+	data->status_mask = ret;
+	data->status_mask |= TMP007_STATUS_CONV_READY;
+
+	ret = i2c_smbus_write_word_swapped(data->client, TMP007_STATUS_MASK,
+					data->status_mask);
+	if (ret < 0)
+		return tmp007_powerdown(data);
+
+	return iio_device_register(indio_dev);
+}
+
+static int tmp007_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct tmp007_data *data = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	tmp007_powerdown(data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tmp007_suspend(struct device *dev)
+{
+	struct tmp007_data *data = iio_priv(i2c_get_clientdata(
+			to_i2c_client(dev)));
+
+	return tmp007_powerdown(data);
+}
+
+static int tmp007_resume(struct device *dev)
+{
+	struct tmp007_data *data = iio_priv(i2c_get_clientdata(
+			to_i2c_client(dev)));
+
+	return i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
+			data->config | TMP007_CONFIG_CONV_EN);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tmp007_pm_ops, tmp007_suspend, tmp007_resume);
+
+static const struct of_device_id tmp007_of_match[] = {
+	{ .compatible = "ti,tmp007", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, tmp007_of_match);
+
+static const struct i2c_device_id tmp007_id[] = {
+	{ "tmp007", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tmp007_id);
+
+static struct i2c_driver tmp007_driver = {
+	.driver = {
+		.name	= "tmp007",
+		.of_match_table = of_match_ptr(tmp007_of_match),
+		.pm	= &tmp007_pm_ops,
+	},
+	.probe		= tmp007_probe,
+	.remove		= tmp007_remove,
+	.id_table	= tmp007_id,
+};
+module_i2c_driver(tmp007_driver);
+
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannanece23-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("TI TMP007 IR thermopile sensor driver");
+MODULE_LICENSE("GPL");
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH] i2c: core: helper function to detect slave mode
From: Luis Oliveira @ 2017-01-05 17:24 UTC (permalink / raw)
  To: wsa-z923LK4zBo2bacvFa/9K2g, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, jarkko.nikula-VuQAYsv1563Yd54FQh9/CA,
	andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA,
	mika.westerberg-VuQAYsv1563Yd54FQh9/CA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Luis.Oliveira-HKixBCOQz3hWk0Htik3J/w,
	Ramiro.Oliveira-HKixBCOQz3hWk0Htik3J/w,
	Joao.Pinto-HKixBCOQz3hWk0Htik3J/w,
	CARLOS.PALMINHA-HKixBCOQz3hWk0Htik3J/w

This function has the purpose of mode detection by checking the
device nodes for a reg matching with the I2C_OWN_SLAVE_ADDREESS flag.
Currently only checks using OF functions (ACPI slave not supported yet).

Signed-off-by: Luis Oliveira <lolivei-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
---
Due to the need of checking if the I2C slave address is our own (in 
other words: if we are the I2C slave) I created a helper function 
(proposed to me by @Andy) to enable that check. 
Currently (because I am not able to test it using ACPI) it only 
supports devicetree declarations.

 drivers/i2c/i2c-core.c | 19 +++++++++++++++++++
 include/linux/i2c.h    |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 3de95a29024c..48e705b23c59 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -3691,6 +3691,25 @@ int i2c_slave_unregister(struct i2c_client *client)
 	return ret;
 }
 EXPORT_SYMBOL_GPL(i2c_slave_unregister);
+
+int i2c_slave_mode_detect(struct device *dev)
+{
+	struct device_node *child;
+	u32 reg;
+
+	if (IS_BUILTIN(CONFIG_OF) && dev->of_node) {
+		for_each_child_of_node(dev->of_node, child) {
+			of_property_read_u32(child, "reg", &reg);
+			if (reg & I2C_OWN_SLAVE_ADDRESS)
+				return 1;
+		}
+	} else if (IS_BUILTIN(CONFIG_ACPI) && ACPI_HANDLE(dev)) {
+		dev_dbg(dev, "ACPI slave is not supported yet\n");
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(i2c_slave_mode_detect);
+
 #endif
 
 MODULE_AUTHOR("Simon G. Vogl <simon-nD9nYVNVf00W+b/DJNNodF6hYfS7NtTn@public.gmane.org>");
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index b2109c522dec..53cf99569af5 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -282,6 +282,7 @@ enum i2c_slave_event {
 
 extern int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb);
 extern int i2c_slave_unregister(struct i2c_client *client);
+extern int i2c_slave_mode_detect(struct device *dev);
 
 static inline int i2c_slave_event(struct i2c_client *client,
 				  enum i2c_slave_event event, u8 *val)
-- 
2.11.0


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH 1/6] ARM: dts: am335x-phycore-som: Update NAND partition table
From: Tony Lindgren @ 2017-01-05 17:18 UTC (permalink / raw)
  To: Teresa Remmet
  Cc: Mark Rutland, devicetree, Brian Norris, Rob Herring,
	Benoît Cousson, linux-omap, Adam Ford, linux-arm-kernel
In-Reply-To: <20170105153637.GA4310@atomide.com>

* Tony Lindgren <tony@atomide.com> [170105 07:37]:
> * Teresa Remmet <t.remmet@phytec.de> [170105 06:57]:
> > To improve NAND safety we updated the partition layout.
> > Added barebox backup partition and removed kernel and oftree
> > partition. They are kept in ubi now.
> 
> What about the users with earlier partition tables?
> 
> Please read about "flag day" changes, typically they are not
> acceptable.

Adding Brian and Adam to Cc. Can you guys come up with some
solution on this?

I'm suggesting we leave the kernel nodes empty and let u-boot
populate them, so maybe you guys can discuss this on the related
lists.

The rest of the series looks fine to me so applying it into
omap-for-v4.11/dt.

Cheers,

Tony

^ permalink raw reply

* Re: [PATCH] ARM: dts: sunxi: Enable spi1 and spi2 for Olimex A20 SOM EVB
From: Maxime Ripard @ 2017-01-05 17:16 UTC (permalink / raw)
  To: Emmanuel Vadot
  Cc: mark.rutland, devicetree, linux, linux-kernel, wens, robh+dt,
	linux-arm-kernel
In-Reply-To: <20161226175349.17712-1-manu@bidouilliste.com>


[-- Attachment #1.1: Type: text/plain, Size: 1084 bytes --]

Hi,

On Mon, Dec 26, 2016 at 06:53:49PM +0100, Emmanuel Vadot wrote:
> Enable the spi1 and spi2 node since the pins are exposed on the UEXT
> connectors.
> 
> Signed-off-by: Emmanuel Vadot <manu@bidouilliste.com>
> ---
>  arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
> index 669a1c338c76..fa8c6f60552b 100644
> --- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
> @@ -300,12 +300,14 @@
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&spi1_pins_a>,
>  		    <&spi1_cs0_pins_a>;
> +	status = "okay";
>  };
>  
>  &spi2 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&spi2_pins_a>,
>  		    <&spi2_cs0_pins_a>;
> +	status = "okay";
>  };

Those nodes don't exist unfortunately. Maybe you forgot to send one
patch?

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3] ARM: dts: sunxi: Add num-cs for A20 spi nodes
From: Maxime Ripard @ 2017-01-05 17:14 UTC (permalink / raw)
  To: Emmanuel Vadot
  Cc: mark.rutland, devicetree, linux, linux-kernel, wens, robh+dt,
	linux-arm-kernel
In-Reply-To: <20161227102807.20244-1-manu@bidouilliste.com>


[-- Attachment #1.1: Type: text/plain, Size: 523 bytes --]

On Tue, Dec 27, 2016 at 11:28:07AM +0100, Emmanuel Vadot wrote:
> The spi0 controller on the A20 have up to 4 CS (Chip Select) while the
> others three only have 1.
> Add the num-cs property to each node.
> The current driver doesn't read this property but this is useful for
> downstream user of DTS (FreeBSD for example).
> 
> Signed-off-by: Emmanuel Vadot <manu@bidouilliste.com>

Applied, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] ARM: dts: sunxi: Use axp209.dtsi for Olinuxino Lime2
From: Maxime Ripard @ 2017-01-05 17:14 UTC (permalink / raw)
  To: Emmanuel Vadot
  Cc: mark.rutland, devicetree, linux, linux-kernel, wens, robh+dt,
	linux-arm-kernel
In-Reply-To: <20161227102238.20110-1-manu@bidouilliste.com>


[-- Attachment #1.1: Type: text/plain, Size: 736 bytes --]

On Tue, Dec 27, 2016 at 11:22:38AM +0100, Emmanuel Vadot wrote:
> Use axp209.dtsi in sun7i-a20-olinuxino-lime2.dts and correct
> some regulators.
> 
> DCDC2 is used for vdd-cpu so it should never be bellow 1V and above 1.4V
> DCDC3 is used for VDD_INT so same as above.
> LD01 is used for the RTC, and should have a typical value of 1.3V
> LD02 is used for AVCC and should have a typical value of 3.0V
> LD03/4 are used for Port-E/Port-G Power pin, and the schematics recommands
> to set them to 2.8V as they can be used for CSI0/1.
> 
> Signed-off-by: Emmanuel Vadot <manu@bidouilliste.com>

Applied, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
From: Sean Young @ 2017-01-05 17:12 UTC (permalink / raw)
  To: sean.wang
  Cc: mark.rutland, devicetree, ivo.g.dimitrov.75, keyhaede, mchehab,
	linux-kernel, andi.shyti, hverkuil, hdegoede, robh+dt,
	linux-mediatek, matthias.bgg, linux-media, linux-arm-kernel,
	hkallweit1
In-Reply-To: <1483632384-8107-3-git-send-email-sean.wang@mediatek.com>

Hi Sean,

Some review comments.

On Fri, Jan 06, 2017 at 12:06:24AM +0800, sean.wang@mediatek.com wrote:
> From: Sean Wang <sean.wang@mediatek.com>
> 
> This patch adds driver for IR controller on
> Mediatek MT7623 SoC. Currently testing successfully
> on NEC and SONY remote controller only but it should
> work on others (lirc, rc-5 and rc-6).
> 
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> ---
>  drivers/media/rc/Kconfig   |  10 ++
>  drivers/media/rc/Makefile  |   1 +
>  drivers/media/rc/mtk-cir.c | 319 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 330 insertions(+)
>  create mode 100644 linux-4.8.rc1_p0/drivers/media/rc/mtk-cir.c
> 
> diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
> index 370e16e..626c500 100644
> --- a/drivers/media/rc/Kconfig
> +++ b/drivers/media/rc/Kconfig
> @@ -389,4 +389,14 @@ config IR_SUNXI
>  	   To compile this driver as a module, choose M here: the module will
>  	   be called sunxi-ir.
>  
> +config IR_MTK
> +	tristate "Mediatek IR remote control"
> +	depends on RC_CORE
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	---help---
> +	   Say Y if you want to use Mediatek internal IR Controller
> +
> +	   To compile this driver as a module, choose M here: the module will
> +	   be called mtk-cir.
> +
>  endif #RC_DEVICES
> diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
> index 379a5c0..505908d 100644
> --- a/drivers/media/rc/Makefile
> +++ b/drivers/media/rc/Makefile
> @@ -37,3 +37,4 @@ obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
>  obj-$(CONFIG_RC_ST) += st_rc.o
>  obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
>  obj-$(CONFIG_IR_IMG) += img-ir/
> +obj-$(CONFIG_IR_MTK) += mtk-cir.o
> diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
> new file mode 100644
> index 0000000..4fa4cab
> --- /dev/null
> +++ b/drivers/media/rc/mtk-cir.c
> @@ -0,0 +1,319 @@
> +/*
> + * Driver for Mediatek MT7623 IR Receiver Controller
> + *
> + * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/reset.h>
> +#include <media/rc-core.h>
> +
> +#define MTK_IR_DEV "mtk-ir"

KBUILD_MODNAME could be used instead. Currently the module is called
mtk-cir but the rc device will have driver name mtk-ir.

> +
> +/* Register to enable PWM and IR */
> +#define MTK_CONFIG_HIGH_REG       0x0c
> +/* Enable IR pulse width detection */
> +#define MTK_PWM_EN		  BIT(13)
> +/* Enable IR hardware function */
> +#define MTK_IR_EN		  BIT(0)
> +
> +/* Register to setting sample period */
> +#define MTK_CONFIG_LOW_REG        0x10
> +/* Field to set sample period */
> +#define CHK_PERIOD		  0xC00
> +#define MTK_CHK_PERIOD            (((CHK_PERIOD) << 8) & (GENMASK(20, 8)))
> +#define MTK_CHK_PERIOD_MASK	  (GENMASK(20, 8))
> +
> +/* Register to clear state of state machine */
> +#define MTK_IRCLR_REG             0x20
> +/* Bit to restart IR receiving */
> +#define MTK_IRCLR		  BIT(0)
> +
> +/* Register containing pulse width data */
> +#define MTK_CHKDATA_REG(i)        (0x88 + 4 * i)
> +
> +/* Register to enable IR interrupt */
> +#define MTK_IRINT_EN_REG          0xcc
> +/* Bit to enable interrupt */
> +#define MTK_IRINT_EN		  BIT(0)
> +
> +/* Register to ack IR interrupt */
> +#define MTK_IRINT_CLR_REG         0xd0
> +/* Bit to clear interrupt status */
> +#define MTK_IRINT_CLR		  BIT(0)
> +
> +/* Number of registers to record the pulse width */
> +#define MTK_CHKDATA_SZ		  17
> +/* Required frequency */
> +#define MTK_IR_BASE_CLK		  273000000
> +/* Frequency after IR internal divider */
> +#define MTK_IR_CLK		  (MTK_IR_BASE_CLK / 4)
> +/* Sample period in ns */
> +#define MTK_IR_SAMPLE		  (((1000000000ul / MTK_IR_CLK) * CHK_PERIOD))
> +/* Indicate the end of IR data*/
> +#define MTK_IR_END(v)		  (v == 0xff)
> +
> +/* struct mtk_ir -	This is the main datasructure for holding the state
> + *			of the driver
> + * @dev:		The device pointer
> + * @ir_lock:		Make sure that synchronization between remove and ISR
> + * @rc:			The rc instrance
> + * @base:		The mapped register i/o base
> + * @irq:		The IRQ that we are using
> + * @clk:		The clock that we are using
> + * @map_name:		The name for keymap lookup
> + */
> +struct mtk_ir {
> +	struct device   *dev;
> +	/*Protect concurrency between driver removal and ISR*/
> +	spinlock_t      ir_lock;
> +	struct rc_dev   *rc;
> +	void __iomem    *base;
> +	int             irq;
> +	struct clk      *clk;
> +	const char      *map_name;

irq and map_name don't need to be stored here, they're only used in 
mtk_ir_probe.

> +};
> +
> +static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
> +{
> +	u32 tmp;
> +
> +	tmp = __raw_readl(ir->base + reg);
> +	tmp = (tmp & ~mask) | val;
> +	__raw_writel(tmp, ir->base + reg);
> +}
> +
> +static void mtk_w32(struct mtk_ir *ir, u32 val, unsigned int reg)
> +{
> +	__raw_writel(val, ir->base + reg);
> +}
> +
> +static u32 mtk_r32(struct mtk_ir *ir, unsigned int reg)
> +{
> +	return __raw_readl(ir->base + reg);
> +}
> +
> +static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
> +{
> +	u32 val;
> +
> +	val = mtk_r32(ir, MTK_IRINT_EN_REG);
> +	mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG);
> +}
> +
> +static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
> +{
> +	u32 val;
> +
> +	val = mtk_r32(ir, MTK_IRINT_EN_REG);
> +	mtk_w32(ir, val | mask, MTK_IRINT_EN_REG);
> +}
> +
> +static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
> +{
> +	struct mtk_ir *ir = dev_id;
> +	u8  wid = 0;
> +	u32 i, j, val;
> +	DEFINE_IR_RAW_EVENT(rawir);
> +
> +	spin_lock(&ir->ir_lock);
> +
> +	mtk_irq_disable(ir, MTK_IRINT_EN);
> +
> +	/* Reset decoder state machine */
> +	ir_raw_event_reset(ir->rc);
> +
> +	/* First message must be pulse */
> +	rawir.pulse = false;
> +
> +	/* Handle pulse and space until end of message */
> +	for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
> +		val = mtk_r32(ir, MTK_CHKDATA_REG(i));
> +		dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);
> +
> +		for (j = 0 ; j < 4 ; j++) {
> +			wid = (val & (0xff << j * 8)) >> j * 8;
> +			rawir.pulse = !rawir.pulse;
> +			rawir.duration = wid * (MTK_IR_SAMPLE + 1);
> +			ir_raw_event_store_with_filter(ir->rc, &rawir);
> +
> +			if (MTK_IR_END(wid))
> +				goto end_msg;
> +		}
> +	}

If I read this correctly, there is a maximum of 17 * 4 = 68 edges per
IR message. The rc6 mce key 0 (scancode 0x800f0400) is 69 edges, so that
won't work.

> +end_msg:
> +	/* Restart the next receive */
> +	mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG);
> +
> +	ir_raw_event_set_idle(ir->rc, true);
> +	ir_raw_event_handle(ir->rc);
> +
> +	/* Clear interrupt status */
> +	mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG);
> +
> +	/* Enable interrupt */
> +	mtk_irq_enable(ir, MTK_IRINT_EN);
> +
> +	spin_unlock(&ir->ir_lock);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int mtk_ir_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *dn = dev->of_node;
> +	struct resource *res;
> +	struct mtk_ir *ir;
> +	u32 val;
> +	int ret = 0;
> +
> +	ir = devm_kzalloc(dev, sizeof(struct mtk_ir), GFP_KERNEL);
> +	if (!ir)
> +		return -ENOMEM;
> +
> +	spin_lock_init(&ir->ir_lock);
> +
> +	ir->dev = dev;
> +
> +	if (!of_device_is_compatible(dn, "mediatek,mt7623-ir"))
> +		return -ENODEV;
> +
> +	ir->clk = devm_clk_get(dev, "clk");
> +	if (IS_ERR(ir->clk)) {
> +		dev_err(dev, "failed to get a ir clock.\n");
> +		return PTR_ERR(ir->clk);
> +	}
> +
> +	if (clk_prepare_enable(ir->clk)) {
> +		dev_err(dev, "try to enable ir_clk failed\n");
> +		ret = -EINVAL;
> +		goto exit_clkdisable_clk;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	ir->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(ir->base)) {
> +		dev_err(dev, "failed to map registers\n");
> +		ret = PTR_ERR(ir->base);
> +		goto exit_clkdisable_clk;
> +	}
> +
> +	ir->rc = rc_allocate_device();
> +	if (!ir->rc) {
> +		dev_err(dev, "failed to allocate device\n");
> +		ret = -ENOMEM;
> +		goto exit_clkdisable_clk;
> +	}
> +
> +	ir->rc->priv = ir;
> +	ir->rc->input_name = MTK_IR_DEV;
> +	ir->rc->input_phys = "mtk-ir/input0";
> +	ir->rc->input_id.bustype = BUS_HOST;
> +	ir->rc->input_id.vendor = 0x0001;
> +	ir->rc->input_id.product = 0x0001;
> +	ir->rc->input_id.version = 0x0001;
> +	ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL);
> +	ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
> +	ir->rc->dev.parent = dev;
> +	ir->rc->driver_type = RC_DRIVER_IR_RAW;
> +	ir->rc->driver_name = MTK_IR_DEV;
> +	ir->rc->allowed_protocols = RC_BIT_ALL;
> +	ir->rc->rx_resolution = MTK_IR_SAMPLE;
> +
> +	ret = rc_register_device(ir->rc);
> +	if (ret) {
> +		dev_err(dev, "failed to register rc device\n");
> +		goto exit_free_dev;
> +	}
> +
> +	platform_set_drvdata(pdev, ir);
> +
> +	ir->irq = platform_get_irq(pdev, 0);
> +	if (ir->irq < 0) {
> +		dev_err(dev, "no irq resource\n");
> +		ret = ir->irq;

>From here on onwards the errors paths should call rc_unregister_device(),
and no longer call rc_free_device(). Note that current master has
devm_rc_allocate_device() and devm_rc_register_device() which would
simplify this code.

> +		goto exit_free_dev;
> +	}
> +
> +	ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
> +	if (ret) {
> +		dev_err(dev, "failed request irq\n");
> +		goto exit_free_dev;
> +	}
> +
> +	mtk_irq_disable(ir, MTK_IRINT_EN);
> +
> +	val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
> +	val |= MTK_PWM_EN | MTK_IR_EN;
> +	mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);
> +
> +	/* Setting sample period */
> +	mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK,
> +		     MTK_CONFIG_LOW_REG);
> +
> +	mtk_irq_enable(ir, MTK_IRINT_EN);
> +
> +	dev_info(dev, "initialized MT7623 IR driver\n");
> +	return 0;
> +
> +exit_free_dev:
> +	rc_free_device(ir->rc);
> +exit_clkdisable_clk:
> +	clk_disable_unprepare(ir->clk);
> +
> +	return ret;
> +}
> +
> +static int mtk_ir_remove(struct platform_device *pdev)
> +{
> +	unsigned long flags;
> +
> +	struct mtk_ir *ir = platform_get_drvdata(pdev);
> +
> +	spin_lock_irqsave(&ir->ir_lock, flags);
> +
> +	mtk_irq_disable(ir, MTK_IRINT_EN);
> +
> +	clk_disable_unprepare(ir->clk);
> +
> +	spin_unlock_irqrestore(&ir->ir_lock, flags);

I'm not convinced the ir_lock is helping to prevent any race condition. An
irq might still already have occurred which will now try to use ir->rc 
which is freed. You can remove the spinlock completely and call 
sychronize_irq() after disabling the mtk interrupt. That way you're sure
the remove is safe to complete.

> +
> +	rc_unregister_device(ir->rc);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id mtk_ir_match[] = {
> +	{ .compatible = "mediatek,mt7623-ir" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, mtk_ir_match);
> +
> +static struct platform_driver mtk_ir_driver = {
> +	.probe          = mtk_ir_probe,
> +	.remove         = mtk_ir_remove,
> +	.driver = {
> +		.name = MTK_IR_DEV,
> +		.of_match_table = mtk_ir_match,
> +	},
> +};
> +
> +module_platform_driver(mtk_ir_driver);
> +
> +MODULE_DESCRIPTION("Mediatek MT7623 IR Receiver Controller Driver");
> +MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
> +MODULE_LICENSE("GPL");
> -- 
> 1.9.1
> 

^ permalink raw reply

* Re: [PATCH v2 4/4] ARM: dts: keystone: Add "ti, da830-uart" compatible string
From: Santosh Shilimkar @ 2017-01-05 17:10 UTC (permalink / raw)
  To: Sekhar Nori, David Lechner, Greg Kroah-Hartman, Santosh Shilimkar
  Cc: Mark Rutland, devicetree, Axel Haslam, Kevin Hilman, linux-kernel,
	Bartosz Golaszewski, Rob Herring, Alexandre Bailon, linux-serial,
	Jiri Slaby, Franklin S Cooper Jr, linux-arm-kernel
In-Reply-To: <824238e0-b710-7146-b67b-b2135c2a8bd2@ti.com>

On 1/5/2017 1:04 AM, Sekhar Nori wrote:
> Hi Santosh,
>
> On Thursday 05 January 2017 03:30 AM, Santosh Shilimkar wrote:
>> On 1/4/2017 12:30 PM, David Lechner wrote:
>>> The TI Keystone SoCs have extra UART registers beyond the standard 8250
>>> registers, so we need a new compatible string to indicate this. Also, at
>>> least one of these registers uses the full 32 bits, so we need to specify
>>> reg-io-width in addition to reg-shift.
>>>
>>> "ns16550a" is left in the compatible specification since it does work as
>>> long as the bootloader configures the SoC UART power management
>>> registers.
>>>
>> NAK!!
>> We can't break the booting boards with existing boot loaders.
>
> Sorry, but it not clear to me how this breaks booting with older
> bootloaders? If older DTB is ROM'ed, it will continue to work because of
> match with ns16550a.
>
> I just verified boot on K2E with these patches applied and using 2016.05
> based U-Boot from a TI release.
>
> http://pastebin.ubuntu.com/23744719/
>
Thanks for test. As long as it doesn't break the boot, am fine
with it.

>> I suggest you to first get the driver updated to take care of
>> the UART PM register and then enable the support for it.
>
> Isn't that what patch 2/4 is doing?
>
I see that now. Thanks for clarifying.

Serial patch needs to go via Greg's tree. I will pick up the
DTS bits.

Regards,
Santosh

^ permalink raw reply

* Re: [RFC 1/3] iommu/arm-smmu: Add support to opt-in to stalling
From: Robin Murphy @ 2017-01-05 17:03 UTC (permalink / raw)
  To: Will Deacon
  Cc: Mark Rutland, robh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Jordan Crouse
In-Reply-To: <20170105160755.GN679-5wv7dgnIgG8@public.gmane.org>

On 05/01/17 16:07, Will Deacon wrote:
> On Thu, Jan 05, 2017 at 03:32:50PM +0000, Robin Murphy wrote:
>> On 05/01/17 14:47, Will Deacon wrote:
>>> On Thu, Jan 05, 2017 at 02:07:31PM +0000, Mark Rutland wrote:
>>>> Ok. It would be good to elaborate on what "stalling is useable" means in
>>>> the property description. i.e. what specificallty the implementation and
>>>> integration need to ensure.
>>>
>>> We can describe some of those guarantees in the property description, but
>>> it's difficult to enumerate them exhaustively. For example, you wouldn't
>>> want stalling to lead to data corruption, denial of service, or for the
>>> thing to catch fire, but having those as explicit requirements is a bit
>>> daft. It's also impossible to check that you thought of everything.
>>>
>>> Aside from renaming the option, I'm really after an opinion on whether
>>> it's better to have one property or combine it with the compatible
>>> string, because I can see benefits of both and don't much care either
>>> way.
>>
>> The SMMU implementation side of the decision (i.e. independence of IRQ
>> assertion vs. SS) seems like exactly the sort of stuff the compatible
>> string already has covered. The integration side I'm less confident can
>> be described this way at all - the "this device definitely won't go
>> wrong if stalled for an indefinite length of time" is inherently a
>> per-master thing, so a single property on the SMMU implying that for
>> every device connected to it seems a bit optimistic, and breaks down as
>> soon as you have one device in the system for which that isn't true (a
>> PCI root complex, say), even if that guy's traffic never crosses paths
>> with whichever few devices you actually care about using stalls with.
>>
>> I think this needs to be some kind of "arm,smmu-stall-safe" property
>> placed on individual master device nodes (mad idea: or even an extra
>> cell of flags in the IOMMU specifier) to encapsulate both that the given
>> device itself is OK with being stalled, and that it's integrated in such
>> a way that its stalled transactions cannot disrupt any *other* device
>> (e.g. it has a TBU all to itself). Then upon initialising a context bank
>> on a suitable SMMU implementation, we set CFCFG based on whatever device
>> is being attached to the corresponding domain, and refuse any subsequent
>> attempts to attach a non-stallable device to a stalling domain (and
>> possibly even vice-versa).
> 
> If we're going to add per-master properties, I'd *really* like them to be
> independent of the IOMMU in use. That is, we should be able to re-use this
> property as part of supporting SVM for platform devices in future.

I'd argue that they are still fairly separate things despite the
overlap: stalling is a specific ARM SMMU architecture thing (in both
architectures) which may be used for purposes unrelated to SVM;
conversely SVM implemented via PRI or similar mechanisms should be
pretty much oblivious to the transaction fault model.

> But I think we agree that we need:
> 
>   1. A compatible string for the SMMU that can be used to infer the SS
>      behaviour in the driver
> 
>   2. A property on the SMMU to say that it's been integrated in such a
>      way that stalling is safe (doesn't deadlock)

That's still got to be a per-master property, not a SMMU property, I
think. To illustrate:

  [A]         [B]   [C]
   |           |_____|
 __|______________|___
| TBU |        | TBU |
|_____|  SMMU  |_____|
|__|______________|__|
   |              |

Say A and B are instances of some device happy to be stalled, and C is a
PCIe RC, and each is attached to their own context bank - enabling
stalls for A is definitely fine. However even though B and C are using
different context banks, enabling stalls for B might deadlock C if it
results in more total outstanding transactions than the TBU's slave port
supports. Therefore A can happily claim to be stall-safe, but B cannot
due to its integration with respect to C.

And yes, I can point you at some existing hardware which really does
posess a topology like that.

>   3. A generic master property that says that the device can DMA to
>      unpinned memory

That sounds a bit *too* generic to me, given that there are multiple
incompatible ways that could be implemented. I'm not the biggest fan of
properties with heavily context-specific interpretations, especially
when there's more than a hint of software implementation details in the mix.

Robin.

> 
> Anything else?
> 
> Will
> 

^ permalink raw reply

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
From: Maxime Ripard @ 2017-01-05 17:02 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: mark.rutland, devicetree, lars, linux-pm, linux-iio, linux-kernel,
	sre, linux, wens, robh+dt, linux-arm-kernel, pmeerw, knaack.h,
	bonbons, lee.jones, thomas.petazzoni, jic23, icenowy
In-Reply-To: <20170102163723.7939-18-quentin.schulz@free-electrons.com>


[-- Attachment #1.1: Type: text/plain, Size: 1726 bytes --]

On Mon, Jan 02, 2017 at 05:37:17PM +0100, Quentin Schulz wrote:
> +		/*
> +		 * IIO framework gives mV but Power Supply framework gives µV.
> +		 */
> +		val->intval *= 1000;

s/gives/wants/ ?

> +static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +					  int val)
> +{
> +	switch (val) {
> +	case 4100000:
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_1V);
> +	case 4150000:
> +		if (axp20x_batt->axp_id == AXP221_ID)
> +			return -EINVAL;
> +
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_15V);
> +	case 4200000:
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_2V);
> +	default:
> +		/*
> +		 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
> +		 * can be set to 4.22V and 4.24V, but these voltages are too
> +		 * high for Lithium based batteries (AXP PMICs are supposed to
> +		 * be used with these kinds of battery).
> +		 */
> +		return -EINVAL;
> +	}

Since all your calls to regmap are the same, something like:

case 4100000:
	val = AXP20X_CHRG_CTRL1_TGT_4_1V;
	break;

case 4150000:
	val = AXP20X_CHRG_CTRL1_TGT_4_15V;
	break;

regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
		   AXP20X_CHRG_CTRL1_TGT_VOLT, val);


It would also get rid of your warnings in checkpatch.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Myir AM437x Rico board support (DTS) for Linux mainline 4.9 and 4.4 Ti Processor SDK 03.02.00.05
From: Pavel Pisa @ 2017-01-05 16:54 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-xIg/pKzrS19vn6HldHNs0ANdhmdF6hFW, Dan Murphy,
	support-0A6ZgDe55FJWk0Htik3J/w, Tomi Valkeinen

Hello Tony and others,

I have found some personal time during holydays[*] and proceed
furhers with RICO board support for perspective kernel versions.

I have prepared a device tree which provides quite complete
board support for the most of peripherals found on MyIR
AM437x Ricoboard. I have tested the kernel on the real board
which I have bought for myself to do testing and can contribute
previous work to to mainline.

LEDs, Ethernet, LEDs, SDcard, eMMC, onboard SPI NVM etc.
works. Generally the AM437x mainline support is great except
for SGX. It has been pleasant to work with it. I used TFTP boot
and ramdisk overlay over NFS exported Debian Jessie RO chroot
install.

Only significant missing piece is HDMI support. I have put
setup which I prepared for Ti kernels to device-tree.
But mainline supports SII9022 HDMI encoder only by

  drivers/gpu/drm/bridge/sii902x.c

but OMAP DSS changes "sil,sii9022" in device-tree
to omapdss,sil,sii9022 which seems to be customized
version found in Texas Instruments tree

  drivers/gpu/drm/omapdrm/displays/encoder-sii9022-video.c

Do you know if there are some plans to support combination
of this driver or include customized version in mainline
for OMAP?

I expect that non accelerated graphic with parallel
LCD panel would work with 4.9 mainline kernel and
the prepared device tree if #if 0 is changed to #if 1.

The 4.9 mainline support files can be found there

  http://pikron.com/files/linux/rico/linux-4.9/am437x-myir-ricoboard.dts
  http://pikron.com/files/linux/rico/linux-4.9/am437x-myir-ricoboard.dtb
  
http://pikron.com/files/linux/rico/linux-4.9/config-4.9-mainline-myir-ricoboard

I would be happy if they can help others, some feedback
and cooperation would be great as well. I would be happy
to contribute DTS to mainline if it is found acceptable.
I can prepare version without HDMI or complete DSS section
if actual untested/able section is unacceptable.

Because of missing HDMI support and attempt to test SGX
accelerated support, I have tried official Ti
Processor SDK image for AM437x (am437x-evm-linux-03.02.00.05).
I have prepared DTS and tested it with my overlay enabled
kernel and Debian and Ti root filesystems as well as with
original Ti kernel.

There are files for use with HDMI connected monitor

  files/linux/rico/linux-ti-4.4/am437x-myir-ricoboard-hdmi.dts
  files/linux/rico/linux-ti-4.4/am437x-myir-ricoboard-hdmi.dtb
  files/linux/rico/linux-ti-4.4/config-ti-4.4-myir-ricoboard

and another set for parallel LCD panel (untested)

  files/linux/rico/linux-ti-4.4/am437x-myir-ricoboard.dts
  files/linux/rico/linux-ti-4.4/am437x-myir-ricoboard.dtb

I have managed to build SGX driver for my kernel configuration
and from the testing of Ti image it seem to be used same way
as for original Ti kernel build.

I have no luck with accelerated Xorg. But Ti release notes
states that Xorg support is missing in 03.02.00.05.

There is question if it is permanent status or if there is some
change.

Is there chance that Ti includes this prepared DTS in their
kernel branch?

For sure mainline 4.9 support is even more interesting
for me and future.

Best wishes,

Pavel


[*] Our company partner cares mainly (and may be pays something)
for my work on maintenance of ancient MyIR Linux 3.12.10 kernel
in their products. And MyIR company does not seem to really
care about users and updates at all even if the enhancements
are sent them for free. Typical experience but great thing about
this board is that a schematic diagram is provided which makes
possible to develop proper support.


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
From: Maxime Ripard @ 2017-01-05 16:51 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: mark.rutland, devicetree, lars, linux-pm, linux-iio, linux-kernel,
	sre, linux, wens, robh+dt, linux-arm-kernel, pmeerw, knaack.h,
	bonbons, lee.jones, thomas.petazzoni, jic23, icenowy
In-Reply-To: <20170102163723.7939-4-quentin.schulz@free-electrons.com>


[-- Attachment #1.1: Type: text/plain, Size: 1575 bytes --]

On Mon, Jan 02, 2017 at 05:37:03PM +0100, Quentin Schulz wrote:
> +	switch (axp20x_id) {
> +	case AXP209_ID:
> +		indio_dev->info = &axp20x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp20x_adc_channels);
> +		indio_dev->channels = axp20x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_MASK);
> +
> +		/* Enable GPIO0/1 and internal temperature ADCs */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
> +				   AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP20X_ADC_RATE_50HZ);
> +		break;
> +
> +	case AXP221_ID:
> +		indio_dev->info = &axp22x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp22x_adc_channels);
> +		indio_dev->channels = axp22x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP22X_ADC_EN1_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP22X_ADC_RATE_200HZ);
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}

I'm not a big fan of those IDs. It always ends up with a ever
increasing list of cases without any consolidation.

In this case, the only thing you need is a list of pointers and values
that can definitely be stored in a structure.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2] ARM: omap3: beagleboard-xm: dt: Add ethernet to the device tree
From: Tony Lindgren @ 2017-01-05 16:51 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Rob Herring, linux-omap,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Benoît Cousson
In-Reply-To: <2557392.58vudoaMIY@avalon>

* Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org> [170105 08:49]:
> On Thursday 05 Jan 2017 08:39:29 Tony Lindgren wrote:
> > * Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> [170105 08:28]:
> > > On Fri, Dec 2, 2016 at 3:11 PM, Laurent Pinchart wrote:
> > >> The Beagleboard-xM has a LAN9514 USB hub and ethernet controller,
> > >> connected to port 2 of the OMAP EHCI controller. The board however has
> > >> no EEPROM to store the ethernet MAC address, which is programmed by the
> > >> boot loader.
> > >> 
> > >> To allow Linux to use the same MAC address as the boot loader (or for
> > >> that matter any fixed MAC address), we need a node in the device tree
> > >> for the ethernet controller that the boot loader can update at runtime
> > >> with a local-mac-address property. Add it, along with an alias for the
> > >> ethernet controller to let the boot loader locate it easily.
> > >> 
> > >> Signed-off-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
> > >> ---
> > >> Changes since v1:
> > >> 
> > >> - Renamed usb2 DT node to hub
> > >> ---
> > >> 
> > >>  arch/arm/boot/dts/omap3-beagle-xm.dts | 16 ++++++++++++++++
> > >>  1 file changed, 16 insertions(+)
> > >> 
> > >> diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts
> > >> b/arch/arm/boot/dts/omap3-beagle-xm.dts index
> > >> 85e297ed0ea1..673cee2234b2 100644
> > >> --- a/arch/arm/boot/dts/omap3-beagle-xm.dts
> > >> +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts
> > >> @@ -27,6 +27,7 @@
> > >>         aliases {
> > >>                 display0 = &dvi0;
> > >>                 display1 = &tv0;
> > >> +               ethernet = &ethernet;
> > > 
> > > Sorry, just noticed this, but this should be dropped. It's not used
> > > nor do we want an alias here.
> > 
> > OK, will update locally as I have not pushed out yet.
> 
> The ethernet alias is used by U-Boot to locate the ethernet controller and 
> update the MAC address.

OK let's wait a bit on this one then.

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ 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