Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Difference between IOVA and bus address when SMMU is enabled
From: valmiki @ 2018-05-12 12:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi All,

What is the difference between IOVA address and bus address
when SMMU is enabled ?

Is IOVA address term used only when hypervisor is present ?

Regards,
Valmiki

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

^ permalink raw reply

* [PATCH v3 3/3] arm64: Force swiotlb bounce buffering for non-coherent DMA with large CWG
From: Christoph Hellwig @ 2018-05-12 12:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180511135547.34521-4-catalin.marinas@arm.com>

On Fri, May 11, 2018 at 02:55:47PM +0100, Catalin Marinas wrote:
> On systems with a Cache Writeback Granule (CTR_EL0.CWG) greater than
> ARCH_DMA_MINALIGN, DMA cache maintenance on sub-CWG ranges is not safe,
> leading to data corruption. If such configuration is detected, the
> kernel will force swiotlb bounce buffering for all non-coherent devices.

Per the previous discussion I understand that so far this is a
purely theoretical condition.  Given that I'd rather avoid commiting
this patch and just refuse too boot in this case.

In a merge window or two I plan to have a noncoherent flag in struct
device, at which point we can handle this entirely in common code.

^ permalink raw reply

* [PATCH V3] ARM: dts: da850-evm: add WP and CD to MMC
From: Adam Ford @ 2018-05-12 12:23 UTC (permalink / raw)
  To: linux-arm-kernel

The legacy mode uses the write protect and card detect but DT does not.
This patch enables Write-Protect and Card-Detect pins for the MMC card, and
the gpio-ranges property sets the gpio pinmuxing for those respective pins.

Signed-off-by: Adam Ford <aford173@gmail.com>
--

V3: Update description of the patch. Rebase on davinci 4.18/dt
V2: Rebase on davinci master and remove GPIO pinmuxing

diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index e91f81f21b22..2e817da37fdb 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -149,6 +149,8 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
+	cd-gpios = <&gpio 64 GPIO_ACTIVE_LOW>;
+	wp-gpios = <&gpio 65 GPIO_ACTIVE_HIGH>;
 };
 
 &spi1 {
-- 
2.17.0

^ permalink raw reply related

* [GIT PULL] Gemini DTS updates for v4.18
From: Linus Walleij @ 2018-05-12 11:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi ARM SoC folks!

This fixes a host of issues and adds some new stuff to the
Gemini platforms. We now have them all running (more or
less) with OpenWRT. Details in the patches and signed tag.

Please pull this to ARM SoC DTS updates for v4.18.

Yours,
Linus Walleij

The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
tags/gemini-dts-arm-soc

for you to fetch changes up to e7c881596baf8d1a4a1b872c4670da6723246936:

  ARM: dts: Fix DTC warnings (2018-05-12 13:27:24 +0200)

----------------------------------------------------------------
DTS updates for the Gemini:
- Set righ flashes on DNS-313
- Activate ATA1 on NAS4220B
- Set right harddisk triggers on the D-Link devices
- Fix all DTC warnings

----------------------------------------------------------------
Geert Uytterhoeven (1):
      ARM: dts: gemini: Fix "debounce-interval" property misspelling

Linus Walleij (6):
      ARM: dtd: Set DNS-313 LEDs to use better triggers
      ARM: dts: Set DNS-685 LEDs to use better triggers
      ARM: dts: Fix the DNS-313 flash compatible
      ARM: dts: Fix bootargs for Gemini D-Link devices
      ARM: dts: Add second ATA to NAS4220B
      ARM: dts: Fix DTC warnings

 arch/arm/boot/dts/gemini-dlink-dir-685.dts | 16 +++++++++-------
 arch/arm/boot/dts/gemini-dlink-dns-313.dts | 19 +++++++++++--------
 arch/arm/boot/dts/gemini-nas4220b.dts      | 20 +++++++++++---------
 arch/arm/boot/dts/gemini-rut1xx.dts        | 12 +++++-------
 arch/arm/boot/dts/gemini-sq201.dts         | 12 +++++-------
 arch/arm/boot/dts/gemini-wbd111.dts        | 17 ++++++++---------
 arch/arm/boot/dts/gemini-wbd222.dts        | 16 +++++++---------
 arch/arm/boot/dts/gemini.dtsi              |  2 --
 8 files changed, 56 insertions(+), 58 deletions(-)

^ permalink raw reply

* [BUGFIX PATCH v3 0/4] arm: kprobes: Fix to prohibit probing on unsafe functions
From: Masami Hiramatsu @ 2018-05-12 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180508112503.GD16141@n2100.armlinux.org.uk>

Hi Russell,

On Tue, 8 May 2018 12:25:03 +0100
Russell King - ARM Linux <linux@armlinux.org.uk> wrote:

> On Fri, May 04, 2018 at 01:14:31PM +0900, Masami Hiramatsu wrote:
> > Hi,
> > 
> > This is the 3rd version of bugfix series for kprobes on arm.
> > This series fixes 4 different issues which I found.
> > 
> >  - Fix to use smp_processor_id() after disabling preemption.
> >  - Prohibit probing on optimized_callback() for avoiding
> >    recursive probe.
> >  - Prohibit kprobes on do_undefinstr() by same reason.
> >  - Prohibit kprobes on get_user() by same reason.
> > 
> > >From v2, I included another 2 bugfixes (1/4 and 2/4)
> > which are not merged yet, and added "Cc: stable at vger.kernel.org",
> > since there are obvious bugs.
> 
> Please submit them to the patch system, thanks.

Could you tell me what you mean the patch system?

Thank you,

> 
> > 
> > Thanks,
> > 
> > ---
> > 
> > Masami Hiramatsu (4):
> >       arm: kprobes: Fix to use get_kprobe_ctlblk after irq-disabed
> >       arm: kprobes: Prohibit probing on optimized_callback
> >       arm: kprobes: Prohibit kprobes on do_undefinstr
> >       arm: kprobes: Prohibit kprobes on get_user functions
> > 
> > 
> >  arch/arm/include/asm/assembler.h  |   10 ++++++++++
> >  arch/arm/kernel/traps.c           |    5 ++++-
> >  arch/arm/lib/getuser.S            |   10 ++++++++++
> >  arch/arm/probes/kprobes/opt-arm.c |    4 +++-
> >  4 files changed, 27 insertions(+), 2 deletions(-)
> > 
> > --
> > Masami Hiramatsu (Linaro) <mhiramat@kernel.org>
> 
> -- 
> RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
> According to speedtest.net: 8.21Mbps down 510kbps up


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply

* [PATCH 7/7 v2] ARM: dts: Fix DTC warnings
From: Linus Walleij @ 2018-05-12 11:22 UTC (permalink / raw)
  To: linux-arm-kernel

The DTC was warning a lot about unit names etc, I think I fixed
them all. Stopping to include skeleton.dtsi fixes the last one.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Stop including skeleton.dtsi and rid the last warning.
---
 arch/arm/boot/dts/gemini-dlink-dir-685.dts |  5 ++---
 arch/arm/boot/dts/gemini-dlink-dns-313.dts |  5 ++---
 arch/arm/boot/dts/gemini-nas4220b.dts      | 12 +++++-------
 arch/arm/boot/dts/gemini-rut1xx.dts        | 10 ++++------
 arch/arm/boot/dts/gemini-sq201.dts         | 10 ++++------
 arch/arm/boot/dts/gemini-wbd111.dts        | 15 +++++++--------
 arch/arm/boot/dts/gemini-wbd222.dts        | 14 ++++++--------
 arch/arm/boot/dts/gemini.dtsi              |  2 --
 8 files changed, 30 insertions(+), 43 deletions(-)

diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
index 89ce0d1916e3..fb5c954ab95a 100644
--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts
+++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
@@ -13,7 +13,7 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	memory {
+	memory at 0 {
 		/* 128 MB SDRAM in 2 x Hynix HY5DU121622DTP-D43 */
 		device_type = "memory";
 		reg = <0x00000000 0x8000000>;
@@ -26,8 +26,7 @@
 
 	gpio_keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
+
 		button-esc {
 			debounce-interval = <50>;
 			wakeup-source;
diff --git a/arch/arm/boot/dts/gemini-dlink-dns-313.dts b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
index da78a0aa389a..d1329322b968 100644
--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
+++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
@@ -15,7 +15,7 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	memory {
+	memory at 0 {
 		/* 64 MB SDRAM in a Nanya NT5DS32M16BS-6K package */
 		device_type = "memory";
 		reg = <0x00000000 0x4000000>;
@@ -32,8 +32,7 @@
 
 	gpio_keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
+
 		button-esc {
 			debounce-interval = <50>;
 			wakeup-source;
diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts
index 9f78803b2456..963ea890c87f 100644
--- a/arch/arm/boot/dts/gemini-nas4220b.dts
+++ b/arch/arm/boot/dts/gemini-nas4220b.dts
@@ -14,7 +14,7 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	memory { /* 128 MB */
+	memory at 0 { /* 128 MB */
 		device_type = "memory";
 		reg = <0x00000000 0x8000000>;
 	};
@@ -26,10 +26,8 @@
 
 	gpio_keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 
-		button at 29 {
+		button-setup {
 			debounce-interval = <50>;
 			wakeup-source;
 			linux,code = <KEY_SETUP>;
@@ -37,7 +35,7 @@
 			/* Conflict with TVC */
 			gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
 		};
-		button at 31 {
+		button-restart {
 			debounce-interval = <50>;
 			wakeup-source;
 			linux,code = <KEY_RESTART>;
@@ -49,13 +47,13 @@
 
 	leds {
 		compatible = "gpio-leds";
-		led at 28 {
+		led-orange-hdd {
 			label = "nas4220b:orange:hdd";
 			/* Conflict with TVC */
 			gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
 			default-state = "on";
 		};
-		led at 30 {
+		led-green-os {
 			label = "nas4220b:green:os";
 			/* Conflict with TVC */
 			gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/gemini-rut1xx.dts b/arch/arm/boot/dts/gemini-rut1xx.dts
index a2f14ee37599..eb4f0bf074da 100644
--- a/arch/arm/boot/dts/gemini-rut1xx.dts
+++ b/arch/arm/boot/dts/gemini-rut1xx.dts
@@ -14,7 +14,7 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	memory { /* 128 MB */
+	memory at 0 { /* 128 MB */
 		device_type = "memory";
 		reg = <0x00000000 0x8000000>;
 	};
@@ -26,10 +26,8 @@
 
 	gpio_keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 
-		button at 28 {
+		button-setup {
 			debounce-interval = <50>;
 			wakeup-source;
 			linux,code = <KEY_SETUP>;
@@ -41,14 +39,14 @@
 
 	leds {
 		compatible = "gpio-leds";
-		led at 7 {
+		led-gsm {
 			/* FIXME: add the LED color */
 			label = "rut1xx::gsm";
 			/* Conflict with ICE */
 			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
 			default-state = "on";
 		};
-		led at 31 {
+		led-power {
 			/* FIXME: add the LED color */
 			label = "rut1xx::power";
 			/* Conflict with NAND CE0 */
diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts
index 229c0267617a..e5cf9d1a98cd 100644
--- a/arch/arm/boot/dts/gemini-sq201.dts
+++ b/arch/arm/boot/dts/gemini-sq201.dts
@@ -14,7 +14,7 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	memory { /* 128 MB */
+	memory at 0 { /* 128 MB */
 		device_type = "memory";
 		reg = <0x00000000 0x8000000>;
 	};
@@ -26,10 +26,8 @@
 
 	gpio_keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 
-		button at 18 {
+		button-setup {
 			debounce-interval = <50>;
 			wakeup-source;
 			linux,code = <KEY_SETUP>;
@@ -41,14 +39,14 @@
 
 	leds {
 		compatible = "gpio-leds";
-		led at 20 {
+		led-green-info {
 			label = "sq201:green:info";
 			/* Conflict with parallel flash */
 			gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
 			default-state = "on";
 			linux,default-trigger = "heartbeat";
 		};
-		led at 31 {
+		led-green-usb {
 			label = "sq201:green:usb";
 			/* Conflict with parallel and NAND flash */
 			gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/gemini-wbd111.dts b/arch/arm/boot/dts/gemini-wbd111.dts
index b31a9189083f..29af86cd10f7 100644
--- a/arch/arm/boot/dts/gemini-wbd111.dts
+++ b/arch/arm/boot/dts/gemini-wbd111.dts
@@ -14,7 +14,8 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	memory { /* 128 MB */
+	memory at 0 {
+		/* 128 MB */
 		device_type = "memory";
 		reg = <0x00000000 0x8000000>;
 	};
@@ -26,10 +27,8 @@
 
 	gpio_keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 
-		button at 5 {
+		button-setup {
 			debounce-interval = <50>;
 			wakeup-source;
 			linux,code = <KEY_SETUP>;
@@ -42,25 +41,25 @@
 	leds {
 		compatible = "gpio-leds";
 
-		led at 1 {
+		led-red-l3 {
 			label = "wbd111:red:L3";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
-		led at 2 {
+		led-green-l4 {
 			label = "wbd111:green:L4";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
-		led at 3 {
+		led-red-l4 {
 			label = "wbd111:red:L4";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
-		led at 5 {
+		led-greeb-l3 {
 			label = "wbd111:green:L3";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/gemini-wbd222.dts b/arch/arm/boot/dts/gemini-wbd222.dts
index 0be867fbfc69..24e6ae3616f7 100644
--- a/arch/arm/boot/dts/gemini-wbd222.dts
+++ b/arch/arm/boot/dts/gemini-wbd222.dts
@@ -14,7 +14,7 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	memory { /* 128 MB */
+	memory at 0 { /* 128 MB */
 		device_type = "memory";
 		reg = <0x00000000 0x8000000>;
 	};
@@ -26,10 +26,8 @@
 
 	gpio_keys {
 		compatible = "gpio-keys";
-		#address-cells = <1>;
-		#size-cells = <0>;
 
-		button at 5 {
+		button-setup {
 			debounce-interval = <50>;
 			wakeup-source;
 			linux,code = <KEY_SETUP>;
@@ -42,25 +40,25 @@
 	leds {
 		compatible = "gpio-leds";
 
-		led at 1 {
+		led-red-l3 {
 			label = "wbd111:red:L3";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
-		led at 2 {
+		led-green-l4 {
 			label = "wbd111:green:L4";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
-		led at 3 {
+		led-red-l4 {
 			label = "wbd111:red:L4";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
-		led at 5 {
+		led-green-l3 {
 			label = "wbd111:green:L3";
 			/* Conflict with TVC and extended parallel flash */
 			gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi
index 0568baca500a..eb752e9495de 100644
--- a/arch/arm/boot/dts/gemini.dtsi
+++ b/arch/arm/boot/dts/gemini.dtsi
@@ -3,8 +3,6 @@
  * Device Tree file for Cortina systems Gemini SoC
  */
 
-/include/ "skeleton.dtsi"
-
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/clock/cortina,gemini-clock.h>
 #include <dt-bindings/reset/cortina,gemini-reset.h>
-- 
2.17.0

^ permalink raw reply related

* [PATCH v6 3/6] kernel/reboot.c: export pm_power_off_prepare
From: Rafael J. Wysocki @ 2018-05-12 11:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180504185052.bjhfkvpgrblc7tfc@pengutronix.de>

On Friday, May 4, 2018 8:50:52 PM CEST Oleksij Rempel wrote:
> Hallo Andrew,
> I need your ACK or NACK for this patch.
> 
> This function is used to configure external PMIC to interpret
> signal which will be triggered by pm_power_off as power off.
> Since same signal can be used for stand by, I linked PMIC configuration
> with pm_power_off_prepare to avoid possible conflicts.
> 
> On Mon, Mar 05, 2018 at 11:25:20AM +0100, Oleksij Rempel wrote:
> > Export pm_power_off_prepare. It is needed to implement power off on
> > Freescale/NXP iMX6 based boards with external power management
> > integrated circuit (PMIC).
> > 
> > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> > ---
> >  kernel/reboot.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/kernel/reboot.c b/kernel/reboot.c
> > index e4ced883d8de..350be6baa60d 100644
> > --- a/kernel/reboot.c
> > +++ b/kernel/reboot.c
> > @@ -49,6 +49,7 @@ int reboot_force;
> >   */
> >  
> >  void (*pm_power_off_prepare)(void);
> > +EXPORT_SYMBOL(pm_power_off_prepare);

Why not EXPORT_SYMBOL_GPL() ?

> >  
> >  /**
> >   *	emergency_restart - reboot the system
> 
> 

^ permalink raw reply

* [PATCH] edac: altera: Add Stratix10 SDRAM Uncorrectable Errors
From: Borislav Petkov @ 2018-05-12 10:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526079610-5527-1-git-send-email-thor.thayer@linux.intel.com>

On Fri, May 11, 2018 at 06:00:10PM -0500, thor.thayer at linux.intel.com wrote:
> From: Thor Thayer <thor.thayer@linux.intel.com>
> 
> On Stratix10, uncorrectable errors are routed to the SError
> exception instead of the IRQ exceptions. In Stratix10,
> uncorrectable SErrors must be treated as fatal and will cause
> a panic.
> Older Altera/Intel parts printed out a message for UE so do
> that here using the notifier framework.
> 
> Record the UE in sticky registers that retain the state
> through a reset. Check these registers on probe and printout the
> error on startup.
> 
> Depends on previous patch:
> commit 2a4ff60626b0 ("arm64: dts: stratix10: add sdram ecc")
> 
> Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
> ---
>  drivers/edac/altera_edac.c | 67 +++++++++++++++++++++++++++++++++++++++-------
>  drivers/edac/altera_edac.h |  8 +++++-
>  2 files changed, 64 insertions(+), 11 deletions(-)

Ok, I think I have collected everything. Pls double-check me I haven't missed
anything:

https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=for-next

Thx.

-- 
Regards/Gruss,
    Boris.

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

^ permalink raw reply

* [PATCH v9 11/12] ACPI: Add PPTT to injectable table list
From: Rafael J. Wysocki @ 2018-05-12 10:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180511235807.30834-12-jeremy.linton@arm.com>

On Sat, May 12, 2018 at 1:58 AM, Jeremy Linton <jeremy.linton@arm.com> wrote:
> Add ACPI_SIG_PPTT to the table so initrd's can override the
> system topology.
>
> Signed-off-by: Geoffrey Blake <geoffrey.blake@arm.com>
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Vijaya Kumar K <vkilari@codeaurora.org>
> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> Tested-by: Tomasz Nowicki <Tomasz.Nowicki@cavium.com>
> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

I'm assuming that this will be routed along with the rest of the series, so

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/tables.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index 849c4fb19b03..30d93bf7c6a2 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -457,7 +457,7 @@ static const char * const table_sigs[] = {
>         ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
>         ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
>         ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_IORT,
> -       ACPI_SIG_NFIT, ACPI_SIG_HMAT, NULL };
> +       ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT, NULL };
>
>  #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
>
> --
> 2.13.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v9 05/12] ACPI/PPTT: Add Processor Properties Topology Table parsing
From: Rafael J. Wysocki @ 2018-05-12 10:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180511235807.30834-6-jeremy.linton@arm.com>

On Sat, May 12, 2018 at 1:58 AM, Jeremy Linton <jeremy.linton@arm.com> wrote:
> ACPI 6.2 adds a new table, which describes how processing units
> are related to each other in tree like fashion. Caches are
> also sprinkled throughout the tree and describe the properties
> of the caches in relation to other caches and processing units.
>
> Add the code to parse the cache hierarchy and report the total
> number of levels of cache for a given core using
> acpi_find_last_cache_level() as well as fill out the individual
> cores cache information with cache_setup_acpi() once the
> cpu_cacheinfo structure has been populated by the arch specific
> code.
>
> An additional patch later in the set adds the ability to report
> peers in the topology using find_acpi_cpu_topology()
> to report a unique ID for each processing unit at a given level
> in the tree. These unique id's can then be used to match related
> processing units which exist as threads, within a given
> package, etc.
>
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Vijaya Kumar K <vkilari@codeaurora.org>
> Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> Tested-by: Tomasz Nowicki <Tomasz.Nowicki@cavium.com>
> Acked-by: Sudeep Holla <sudeep.holla@arm.com>
> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  drivers/acpi/pptt.c  | 655 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h |   4 +
>  2 files changed, 659 insertions(+)
>  create mode 100644 drivers/acpi/pptt.c
>
> diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
> new file mode 100644
> index 000000000000..e5ea1974d1e3
> --- /dev/null
> +++ b/drivers/acpi/pptt.c
> @@ -0,0 +1,655 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * pptt.c - parsing of Processor Properties Topology Table (PPTT)
> + *
> + * Copyright (C) 2018, ARM
> + *
> + * This file implements parsing of the Processor Properties Topology Table
> + * which is optionally used to describe the processor and cache topology.
> + * Due to the relative pointers used throughout the table, this doesn't
> + * leverage the existing subtable parsing in the kernel.
> + *
> + * The PPTT structure is an inverted tree, with each node potentially
> + * holding one or two inverted tree data structures describing
> + * the caches available at that level. Each cache structure optionally
> + * contains properties describing the cache at a given level which can be
> + * used to override hardware probed values.
> + */
> +#define pr_fmt(fmt) "ACPI PPTT: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/cacheinfo.h>
> +#include <acpi/processor.h>
> +
> +static struct acpi_subtable_header *fetch_pptt_subtable(struct acpi_table_header *table_hdr,
> +                                                       u32 pptt_ref)
> +{
> +       struct acpi_subtable_header *entry;
> +
> +       /* there isn't a subtable at reference 0 */
> +       if (pptt_ref < sizeof(struct acpi_subtable_header))
> +               return NULL;
> +
> +       if (pptt_ref + sizeof(struct acpi_subtable_header) > table_hdr->length)
> +               return NULL;
> +
> +       entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, pptt_ref);
> +
> +       if (entry->length == 0)
> +               return NULL;
> +
> +       if (pptt_ref + entry->length > table_hdr->length)
> +               return NULL;
> +
> +       return entry;
> +}
> +
> +static struct acpi_pptt_processor *fetch_pptt_node(struct acpi_table_header *table_hdr,
> +                                                  u32 pptt_ref)
> +{
> +       return (struct acpi_pptt_processor *)fetch_pptt_subtable(table_hdr, pptt_ref);
> +}
> +
> +static struct acpi_pptt_cache *fetch_pptt_cache(struct acpi_table_header *table_hdr,
> +                                               u32 pptt_ref)
> +{
> +       return (struct acpi_pptt_cache *)fetch_pptt_subtable(table_hdr, pptt_ref);

I don't think you really need the explicit type cast here and above,
but that's very minor.

> +}

Please feel free to add

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

to the patch and route it through the arch tree as needed.

Thanks,
Rafael

^ permalink raw reply

* [PATCH] iio: adc: stm32-dfsdm: Add support for stm32mp1
From: Jonathan Cameron @ 2018-05-12  9:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180507205151.GA25321@rob-hp-laptop>

On Mon, 7 May 2018 15:51:51 -0500
Rob Herring <robh@kernel.org> wrote:

> On Wed, May 02, 2018 at 03:05:23PM +0200, Fabrice Gasnier wrote:
> > Add support for DFSDM (Digital Filter For Sigma Delta Modulators)
> > to STM32MP1. This variant is close to STM32H7 DFSDM, it implements
> > 6 filter instances. Registers map is also increased.
> > 
> > Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> > ---
> >  .../bindings/iio/adc/st,stm32-dfsdm-adc.txt         |  7 +++++--
> >  drivers/iio/adc/stm32-dfsdm-core.c                  | 21 +++++++++++++++++++++
> >  2 files changed, 26 insertions(+), 2 deletions(-)  
> 
> Reviewed-by: Rob Herring <robh@kernel.org>
Applied.   Whilst doing this I note that I'm getting a few sparse
warnings for this driver that would be nice to clean up...

  CHECK   drivers/iio/adc/stm32-dfsdm-adc.c
drivers/iio/adc/stm32-dfsdm-adc.c:503:21: warning: expression using sizeof(void)
drivers/iio/adc/stm32-dfsdm-adc.c:503:21: warning: expression using sizeof(void)

Which is mystifying at first glance... Something deep and dirty in the min macro
but I can't see what..

drivers/iio/adc/stm32-dfsdm-adc.c:680:5: warning: symbol 'stm32_dfsdm_get_buff_cb' was not declared. Should it be static?
drivers/iio/adc/stm32-dfsdm-adc.c:703:5: warning: symbol 'stm32_dfsdm_release_buff_cb' was not declared. Should it be static?

Are rather more obvious

^ permalink raw reply

* [PATCH] arm64: defconfig: Increase CMA size for VC4
From: Stefan Wahren @ 2018-05-12  9:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87bmdwo2qd.fsf@anholt.net>

Hi Florian,

> Eric Anholt <eric@anholt.net> hat am 3. Mai 2018 um 23:20 geschrieben:
> 
> 
> Stefan Wahren <stefan.wahren@i2se.com> writes:
> 
> > The VC4 needs more memory than the default setting (16 MB):
> >
> >   vc4-drm soc:gpu: swiotlb: coherent allocation failed, size=16777216
> >   [drm:vc4_bo_create [vc4]] *ERROR* Failed to allocate from CMA:
> >   vc4_v3d 3fc00000.v3d: Failed to allocate memory for tile binning: -12.
> >     You may need to enable CMA or give it more memory.
> >   vc4-drm soc:gpu: failed to bind 3fc00000.v3d (ops vc4_v3d_ops [vc4]): -12
> >   vc4-drm soc:gpu: master bind failed: -12
> >   vc4-drm: probe of soc:gpu failed with error -12
> >
> > So increase the value to 32 MB and fix this issue.
> >
> > Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> 
> If there was a way to check how big the CMA pool is, then we could
> probably have V3D disable itself when the pool was too small.  It's not
> like V3D rendering is going to actually *work* with just a 32mb pool to
> play in.
> 
> That said, I'd also be fine with this patch.

should i rebase my patch?

^ permalink raw reply

* [BUGFIX PATCH v3 0/4] arm: kprobes: Fix to prohibit probing on unsafe functions
From: Russell King - ARM Linux @ 2018-05-12  9:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180512094221.e911fa262d8ca9a70ab8869e@kernel.org>

On Sat, May 12, 2018 at 09:42:21AM +0900, Masami Hiramatsu wrote:
> Hi Greg,
> 
> Could you pick this series to stable?

You've added the Cc for stable, so when they get committed to mainline,
they will be automatically picked up without further need to ask.

However, they do _first_ need to end up in mainline before they can go
anywhere near stable trees as per stable tree rules.  For more
information on stable trees and their rules, please see:

  Documentation/process/stable-kernel-rules.rst

> 
> Thank you,
> 
> On Tue, 8 May 2018 12:25:03 +0100
> Russell King - ARM Linux <linux@armlinux.org.uk> wrote:
> 
> > On Fri, May 04, 2018 at 01:14:31PM +0900, Masami Hiramatsu wrote:
> > > Hi,
> > > 
> > > This is the 3rd version of bugfix series for kprobes on arm.
> > > This series fixes 4 different issues which I found.
> > > 
> > >  - Fix to use smp_processor_id() after disabling preemption.
> > >  - Prohibit probing on optimized_callback() for avoiding
> > >    recursive probe.
> > >  - Prohibit kprobes on do_undefinstr() by same reason.
> > >  - Prohibit kprobes on get_user() by same reason.
> > > 
> > > >From v2, I included another 2 bugfixes (1/4 and 2/4)
> > > which are not merged yet, and added "Cc: stable at vger.kernel.org",
> > > since there are obvious bugs.
> > 
> > Please submit them to the patch system, thanks.
> > 
> > > 
> > > Thanks,
> > > 
> > > ---
> > > 
> > > Masami Hiramatsu (4):
> > >       arm: kprobes: Fix to use get_kprobe_ctlblk after irq-disabed
> > >       arm: kprobes: Prohibit probing on optimized_callback
> > >       arm: kprobes: Prohibit kprobes on do_undefinstr
> > >       arm: kprobes: Prohibit kprobes on get_user functions
> > > 
> > > 
> > >  arch/arm/include/asm/assembler.h  |   10 ++++++++++
> > >  arch/arm/kernel/traps.c           |    5 ++++-
> > >  arch/arm/lib/getuser.S            |   10 ++++++++++
> > >  arch/arm/probes/kprobes/opt-arm.c |    4 +++-
> > >  4 files changed, 27 insertions(+), 2 deletions(-)
> > > 
> > > --
> > > Masami Hiramatsu (Linaro) <mhiramat@kernel.org>
> > 
> > -- 
> > RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> > FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
> > According to speedtest.net: 8.21Mbps down 510kbps up
> 
> 
> -- 
> Masami Hiramatsu <mhiramat@kernel.org>

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

^ permalink raw reply

* [PATCH v2 03/12] arm: dts: mt7623: fix invalid memory node being generated
From: Sean Wang @ 2018-05-12  5:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4dcb0435-1f98-0753-0feb-d17ad02077ae@gmail.com>

On Fri, 2018-05-11 at 17:03 +0200, Matthias Brugger wrote:
> 
> On 04/11/2018 10:53 AM, sean.wang at mediatek.com wrote:
> > From: Sean Wang <sean.wang@mediatek.com>
> > 
> > Below two wrong nodes in existing DTS files would cause a fail boot since
> > in fact the address 0 is not the correct place the memory device locates
> > at.
> > 
> > memory {
> >         device_type = "memory";
> >         reg = <0x0 0x0 0x0 0x0>;
> > };
> > 
> > memory at 80000000 {
> >         reg = <0x0 0x80000000 0x0 0x40000000>;
> > };
> > 
> > In order to avoid having a memory node starting at address 0, we can't
> > include file skeleton64.dtsi and instead need to explicitly manually
> > define a few of properties the DTS relies on such as #address-cells
> > and #size-cells in root node and device_type in the node memory at 80000000.
> > 
> > Cc: stable at vger.kernel.org
> > Fixes: 31ac0d69a1d4 ("ARM: dts: mediatek: add MT7623 basic support")
> > Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > ---
> >  arch/arm/boot/dts/mt7623.dtsi                 | 3 ++-
> >  arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 1 +
> >  arch/arm/boot/dts/mt7623n-rfb.dtsi            | 1 +
> >  3 files changed, 4 insertions(+), 1 deletion(-)
> > 
> 
> merged. We would need this at least for mt2701 as well, correct?
> Would you mind to provide a patch.
> 
> Regards,
> Matthias
> 

Thanks! I totally think the same problem could happen on mt2701, so I'm 
happy to come up with a patch for that.

	Sean

> > diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
> > index fec4715..406a9f3 100644
> > --- a/arch/arm/boot/dts/mt7623.dtsi
> > +++ b/arch/arm/boot/dts/mt7623.dtsi
> > @@ -15,11 +15,12 @@
> >  #include <dt-bindings/phy/phy.h>
> >  #include <dt-bindings/reset/mt2701-resets.h>
> >  #include <dt-bindings/thermal/thermal.h>
> > -#include "skeleton64.dtsi"
> >  
> >  / {
> >  	compatible = "mediatek,mt7623";
> >  	interrupt-parent = <&sysirq>;
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> >  
> >  	cpu_opp_table: opp-table {
> >  		compatible = "operating-points-v2";
> > diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
> > index bbf56f8..5938e4c 100644
> > --- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
> > +++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
> > @@ -109,6 +109,7 @@
> >  	};
> >  
> >  	memory at 80000000 {
> > +		device_type = "memory";
> >  		reg = <0 0x80000000 0 0x40000000>;
> >  	};
> >  };
> > diff --git a/arch/arm/boot/dts/mt7623n-rfb.dtsi b/arch/arm/boot/dts/mt7623n-rfb.dtsi
> > index a199ae7..343e8ef 100644
> > --- a/arch/arm/boot/dts/mt7623n-rfb.dtsi
> > +++ b/arch/arm/boot/dts/mt7623n-rfb.dtsi
> > @@ -40,6 +40,7 @@
> >  	};
> >  
> >  	memory at 80000000 {
> > +		device_type = "memory";
> >  		reg = <0 0x80000000 0 0x40000000>;
> >  	};
> >  
> > 

^ permalink raw reply

* [BUGFIX PATCH v3 0/4] arm: kprobes: Fix to prohibit probing on unsafe functions
From: Greg KH @ 2018-05-12  4:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180512094221.e911fa262d8ca9a70ab8869e@kernel.org>

On Sat, May 12, 2018 at 09:42:21AM +0900, Masami Hiramatsu wrote:
> Hi Greg,
> 
> Could you pick this series to stable?

<formletter>

This is not the correct way to submit patches for inclusion in the
stable kernel tree.  Please read:
    https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.

</formletter>

thanks,

greg k-h

^ permalink raw reply

* [PATCH v3 2/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-05-12  2:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1526088081.git.collinsd@codeaurora.org>

Add the QCOM RPMh regulator driver to manage PMIC regulators
which are controlled via RPMh on some Qualcomm Technologies, Inc.
SoCs.  RPMh is a hardware block which contains several
accelerators which are used to manage various hardware resources
that are shared between the processors of the SoC.  The final
hardware state of a regulator is determined within RPMh by
performing max aggregation of the requests made by all of the
processors.

Add support for PMIC regulator control via the voltage regulator
manager (VRM) and oscillator buffer (XOB) RPMh accelerators.  VRM
supports manipulation of enable state, voltage, mode, and
headroom voltage.  XOB supports manipulation of enable state.

Signed-off-by: David Collins <collinsd@codeaurora.org>
---
 drivers/regulator/Kconfig               |   9 +
 drivers/regulator/Makefile              |   1 +
 drivers/regulator/qcom-rpmh-regulator.c | 925 ++++++++++++++++++++++++++++++++
 3 files changed, 935 insertions(+)
 create mode 100644 drivers/regulator/qcom-rpmh-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 4efae3b..1a69bdc 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -671,6 +671,15 @@ config REGULATOR_QCOM_RPM
 	  Qualcomm RPM as a module. The module will be named
 	  "qcom_rpm-regulator".
 
+config REGULATOR_QCOM_RPMH
+	tristate "Qualcomm Technologies, Inc. RPMh regulator driver"
+	depends on QCOM_RPMH || COMPILE_TEST
+	help
+	  This driver supports control of PMIC regulators via the RPMh hardware
+	  block found on Qualcomm Technologies Inc. SoCs.  RPMh regulator
+	  control allows for voting on regulator state between multiple
+	  processors within the SoC.
+
 config REGULATOR_QCOM_SMD_RPM
 	tristate "Qualcomm SMD based RPM regulator driver"
 	depends on QCOM_SMD_RPM
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d81fb02..906f048 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_REGULATOR_MT6323)	+= mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
+obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
 obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
new file mode 100644
index 0000000..991ecc1
--- /dev/null
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -0,0 +1,925 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+#include <soc/qcom/cmd-db.h>
+#include <soc/qcom/rpmh.h>
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+/**
+ * enum rpmh_regulator_type - supported RPMh accelerator types
+ * %VRM:	RPMh VRM accelerator which supports voting on enable, voltage,
+ *		mode, and headroom voltage of LDO, SMPS, and BOB type PMIC
+ *		regulators.
+ * %XOB:	RPMh XOB accelerator which supports voting on the enable state
+ *		of PMIC regulators.
+ */
+enum rpmh_regulator_type {
+	VRM,
+	XOB,
+};
+
+#define RPMH_VRM_HEADROOM_MAX_UV		511000
+
+#define RPMH_REGULATOR_REG_VRM_VOLTAGE		0x0
+#define RPMH_REGULATOR_REG_ENABLE		0x4
+#define RPMH_REGULATOR_REG_VRM_MODE		0x8
+#define RPMH_REGULATOR_REG_VRM_HEADROOM		0xC
+
+#define RPMH_REGULATOR_MODE_COUNT		4
+
+#define PMIC4_LDO_MODE_RETENTION		4
+#define PMIC4_LDO_MODE_LPM			5
+#define PMIC4_LDO_MODE_HPM			7
+
+#define PMIC4_SMPS_MODE_RETENTION		4
+#define PMIC4_SMPS_MODE_PFM			5
+#define PMIC4_SMPS_MODE_AUTO			6
+#define PMIC4_SMPS_MODE_PWM			7
+
+#define PMIC4_BOB_MODE_PASS			0
+#define PMIC4_BOB_MODE_PFM			1
+#define PMIC4_BOB_MODE_AUTO			2
+#define PMIC4_BOB_MODE_PWM			3
+
+/**
+ * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
+ * @regulator_type:		RPMh accelerator type used to manage this
+ *				regulator
+ * @ops:			Pointer to regulator ops callback structure
+ * @voltage_range:		The single range of voltages supported by this
+ *				PMIC regulator type
+ * @n_voltages:			The number of unique voltage set points defined
+ *				by voltage_range
+ * @pmic_mode_map:		Array indexed by regulator framework mode
+ *				containing PMIC hardware modes.  Must be large
+ *				enough to index all framework modes supported
+ *				by this regulator hardware type.
+ * @of_map_mode:		Maps an RPMH_REGULATOR_MODE_* mode value defined
+ *				in device tree to a regulator framework mode
+ */
+struct rpmh_vreg_hw_data {
+	enum rpmh_regulator_type		regulator_type;
+	const struct regulator_ops		*ops;
+	const struct regulator_linear_range	voltage_range;
+	int					n_voltages;
+	const int				*pmic_mode_map;
+	unsigned int			      (*of_map_mode)(unsigned int mode);
+};
+
+/**
+ * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a
+ *		single regulator device
+ * @dev:			Device pointer for the top-level PMIC RPMh
+ *				regulator parent device.  This is used as a
+ *				handle in RPMh write requests.
+ * @addr:			Base address of the regulator resource within
+ *				an RPMh accelerator
+ * @rdesc:			Regulator descriptor
+ * @hw_data:			PMIC regulator configuration data for this RPMh
+ *				regulator
+ * @always_wait_for_ack:	Boolean flag indicating if a request must always
+ *				wait for an ACK from RPMh before continuing even
+ *				if it corresponds to a strictly lower power
+ *				state (e.g. enabled --> disabled).
+ * @drms_modes:			Array of regulator framework modes which can
+ *				be configured dynamically for this regulator
+ *				via the set_load() callback.
+ * @drms_mode_max_uAs:		Array of maximum load currents in microamps
+ *				supported by the corresponding modes in
+ *				drms_mode.  Elements must be specified in
+ *				strictly increasing order.
+ * @drms_mode_count:		The number of elements in drms_mode array.
+ * @enabled:			Boolean indicating if the regulator is enabled
+ *				or not
+ * @bypassed:			Boolean indicating if the regulator is in
+ *				bypass (pass-through) mode or not.  This is
+ *				only used by BOB rpmh-regulator resources.
+ * @voltage_selector:		Selector used for get_voltage_sel() and
+ *				set_voltage_sel() callbacks
+ * @mode:			RPMh VRM regulator current framework mode
+ */
+struct rpmh_vreg {
+	struct device			*dev;
+	u32				addr;
+	struct regulator_desc		rdesc;
+	const struct rpmh_vreg_hw_data	*hw_data;
+	bool				always_wait_for_ack;
+	unsigned int			*drms_modes;
+	int				*drms_mode_max_uAs;
+	size_t				drms_mode_count;
+
+	bool				enabled;
+	bool				bypassed;
+	int				voltage_selector;
+	unsigned int			mode;
+};
+
+/**
+ * struct rpmh_vreg_init_data - initialization data for an RPMh regulator
+ * @name:			Name for the regulator which also corresponds
+ *				to the device tree subnode name of the regulator
+ * @resource_name:		RPMh regulator resource name format string.
+ *				This must include exactly one field: '%s' which
+ *				is filled at run-time with the PMIC ID provided
+ *				by device tree property qcom,pmic-id.  Example:
+ *				"ldo%s1" for RPMh resource "ldoa1".
+ * @supply_name:		Parent supply regulator name
+ * @hw_data:			Configuration data for this PMIC regulator type
+ */
+struct rpmh_vreg_init_data {
+	const char			*name;
+	const char			*resource_name;
+	const char			*supply_name;
+	const struct rpmh_vreg_hw_data	*hw_data;
+};
+
+/**
+ * rpmh_regulator_send_request() - send the request to RPMh
+ * @vreg:		Pointer to the RPMh regulator
+ * @cmd:		RPMh commands to send
+ * @count:		Size of cmd array
+ * @wait_for_ack:	Boolean indicating if execution must wait until the
+ *			request has been acknowledged as complete
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
+			struct tcs_cmd *cmd, int count, bool wait_for_ack)
+{
+	int ret;
+
+	if (wait_for_ack || vreg->always_wait_for_ack)
+		ret = rpmh_write(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd, count);
+	else
+		ret = rpmh_write_async(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd,
+					count);
+
+	return ret;
+}
+
+static int rpmh_regulator_is_enabled(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	return vreg->enabled;
+}
+
+static int rpmh_regulator_enable(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
+		.data = 1,
+	};
+	int ret;
+
+	ret = rpmh_regulator_send_request(vreg, &cmd, 1, true);
+
+	if (!ret)
+		vreg->enabled = true;
+
+	return ret;
+}
+
+static int rpmh_regulator_disable(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
+		.data = 0,
+	};
+	int ret;
+
+	ret = rpmh_regulator_send_request(vreg, &cmd, 1, false);
+
+	if (!ret)
+		vreg->enabled = false;
+
+	return ret;
+}
+
+static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
+				unsigned int selector)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
+	};
+	int ret;
+
+	/* VRM voltage control register is set with voltage in millivolts. */
+	cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
+							selector), 1000);
+
+	ret = rpmh_regulator_send_request(vreg, &cmd, 1,
+					  selector > vreg->voltage_selector);
+	if (!ret)
+		vreg->voltage_selector = selector;
+
+	return 0;
+}
+
+static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	return vreg->voltage_selector;
+}
+
+static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
+					unsigned int mode, bool bypassed)
+{
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
+	};
+	int pmic_mode;
+
+	if (mode > REGULATOR_MODE_STANDBY)
+		return -EINVAL;
+
+	pmic_mode = vreg->hw_data->pmic_mode_map[mode];
+	if (pmic_mode < 0)
+		return pmic_mode;
+
+	cmd.data = bypassed ? PMIC4_BOB_MODE_PASS : pmic_mode;
+
+	return rpmh_regulator_send_request(vreg, &cmd, 1, true);
+}
+
+static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
+					unsigned int mode)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (mode == vreg->mode)
+		return 0;
+
+	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
+	if (!ret)
+		vreg->mode = mode;
+
+	return ret;
+}
+
+static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	return vreg->mode;
+}
+
+/**
+ * rpmh_regulator_vrm_set_load() - set the regulator mode based upon the load
+ *		current requested
+ * @rdev:		Regulator device pointer for the rpmh-regulator
+ * @load_uA:		Aggregated load current in microamps
+ *
+ * This function is used in the regulator_ops for VRM type RPMh regulator
+ * devices.  It updates the mode of the regulator using a table of maximum
+ * load currents per mode specified in device tree properties.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_vrm_set_load(struct regulator_dev *rdev, int load_uA)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	int i;
+
+	for (i = 0; i < vreg->drms_mode_count - 1; i++)
+		if (vreg->drms_mode_max_uAs[i] >= load_uA)
+			break;
+	if (load_uA > vreg->drms_mode_max_uAs[vreg->drms_mode_count - 1])
+		dev_warn(vreg->dev, "%s: requested load=%d uA greater than max=%d uA\n",
+			vreg->rdesc.name, load_uA,
+			vreg->drms_mode_max_uAs[vreg->drms_mode_count - 1]);
+
+	return rpmh_regulator_vrm_set_mode(rdev, vreg->drms_modes[i]);
+}
+
+static int rpmh_regulator_vrm_set_bypass(struct regulator_dev *rdev,
+				bool enable)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (vreg->bypassed == enable)
+		return 0;
+
+	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, enable);
+	if (!ret)
+		vreg->bypassed = enable;
+
+	return ret;
+}
+
+static int rpmh_regulator_vrm_get_bypass(struct regulator_dev *rdev,
+				bool *enable)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	*enable = vreg->bypassed;
+
+	return 0;
+}
+
+static const struct regulator_ops rpmh_regulator_vrm_ops = {
+	.enable			= rpmh_regulator_enable,
+	.disable		= rpmh_regulator_disable,
+	.is_enabled		= rpmh_regulator_is_enabled,
+	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
+	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.set_mode		= rpmh_regulator_vrm_set_mode,
+	.get_mode		= rpmh_regulator_vrm_get_mode,
+	.set_load		= rpmh_regulator_vrm_set_load,
+};
+
+static const struct regulator_ops rpmh_regulator_vrm_bypass_ops = {
+	.enable			= rpmh_regulator_enable,
+	.disable		= rpmh_regulator_disable,
+	.is_enabled		= rpmh_regulator_is_enabled,
+	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
+	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.set_mode		= rpmh_regulator_vrm_set_mode,
+	.get_mode		= rpmh_regulator_vrm_get_mode,
+	.set_load		= rpmh_regulator_vrm_set_load,
+	.set_bypass		= rpmh_regulator_vrm_set_bypass,
+	.get_bypass		= rpmh_regulator_vrm_get_bypass,
+};
+
+static const struct regulator_ops rpmh_regulator_xob_ops = {
+	.enable			= rpmh_regulator_enable,
+	.disable		= rpmh_regulator_disable,
+	.is_enabled		= rpmh_regulator_is_enabled,
+};
+
+/**
+ * rpmh_regulator_parse_vrm_modes() - parse the supported mode configurations
+ *		for a VRM RPMh resource from device tree
+ * vreg:		Pointer to the individual rpmh-regulator resource
+ * dev:			Pointer to the top level rpmh-regulator PMIC device
+ * node:		Pointer to the individual rpmh-regulator resource
+ *			device node
+ *
+ * This function initializes the drms_modes[] and drms_mode_max_uAs[] arrays of
+ * vreg based upon the values of optional device tree properties.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_parse_vrm_modes(struct rpmh_vreg *vreg,
+				struct device *dev, struct device_node *node)
+{
+	const char *prop;
+	int i, len, ret, mode;
+	u32 *buf;
+
+	/* qcom,allowed-drms-modes is optional */
+	prop = "qcom,allowed-drms-modes";
+	len = of_property_count_elems_of_size(node, prop, sizeof(u32));
+	if (len < 0)
+		return 0;
+
+	vreg->drms_modes = devm_kcalloc(dev, len, sizeof(*vreg->drms_modes),
+					GFP_KERNEL);
+	vreg->drms_mode_max_uAs = devm_kcalloc(dev, len,
+					       sizeof(*vreg->drms_mode_max_uAs),
+					       GFP_KERNEL);
+	if (!vreg->drms_modes || !vreg->drms_mode_max_uAs)
+		return -ENOMEM;
+	vreg->drms_mode_count = len;
+
+	buf = kcalloc(len, sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = of_property_read_u32_array(node, prop, buf, len);
+	if (ret < 0) {
+		dev_err(dev, "%s: unable to read %s, ret=%d\n",
+			node->name, prop, ret);
+		goto done;
+	}
+
+	for (i = 0; i < len; i++) {
+		mode = vreg->hw_data->of_map_mode(buf[i]);
+		if (mode == REGULATOR_MODE_INVALID) {
+			dev_err(dev, "%s: element %d of %s = %u is invalid for this regulator\n",
+				node->name, i, prop, buf[i]);
+			ret = -EINVAL;
+			goto done;
+		}
+
+		vreg->drms_modes[i] = mode;
+	}
+
+	prop = "qcom,drms-mode-max-microamps";
+	len = of_property_count_elems_of_size(node, prop, sizeof(u32));
+	if (len != vreg->drms_mode_count) {
+		dev_err(dev, "%s: invalid element count=%d for %s\n",
+			node->name, len, prop);
+		ret = -EINVAL;
+		goto done;
+	}
+
+	ret = of_property_read_u32_array(node, prop, buf, len);
+	if (ret < 0) {
+		dev_err(dev, "%s: unable to read %s, ret=%d\n",
+			node->name, prop, ret);
+		goto done;
+	}
+
+	for (i = 0; i < len; i++) {
+		vreg->drms_mode_max_uAs[i] = buf[i];
+
+		if (i > 0 && vreg->drms_mode_max_uAs[i]
+				<= vreg->drms_mode_max_uAs[i - 1]) {
+			dev_err(dev, "%s: %s elements are not in ascending order\n",
+				node->name, prop);
+			ret = -EINVAL;
+			goto done;
+		}
+	}
+
+done:
+	kfree(buf);
+	return ret;
+}
+
+/**
+ * rpmh_regulator_load_default_parameters() - initialize the RPMh resource
+ *		request for this regulator based on optional device tree
+ *		properties
+ * vreg:		Pointer to the individual rpmh-regulator resource
+ * dev:			Pointer to the top level rpmh-regulator PMIC device
+ * node:		Pointer to the individual rpmh-regulator resource
+ *			device node
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_load_default_parameters(struct rpmh_vreg *vreg,
+				struct device *dev, struct device_node *node)
+{
+	struct tcs_cmd cmd[2] = {};
+	const struct regulator_linear_range *range;
+	const char *prop;
+	int cmd_count = 0;
+	int ret, selector;
+	u32 uV;
+
+	if (vreg->hw_data->regulator_type == VRM) {
+		/*
+		 * This will be set when devm_regulator_register() is called
+		 * if regulator-initial-mode is specified in device tree.
+		 */
+		vreg->mode = REGULATOR_MODE_INVALID;
+
+		prop = "qcom,headroom-microvolt";
+		ret = of_property_read_u32(node, prop, &uV);
+		if (!ret) {
+			if (uV > RPMH_VRM_HEADROOM_MAX_UV) {
+				dev_err(dev, "%s: %s=%u is invalid\n",
+					node->name, prop, uV);
+				return -EINVAL;
+			}
+
+			cmd[cmd_count].addr
+				= vreg->addr + RPMH_REGULATOR_REG_VRM_HEADROOM;
+			cmd[cmd_count++].data = DIV_ROUND_UP(uV, 1000);
+		}
+
+		prop = "qcom,regulator-initial-microvolt";
+		ret = of_property_read_u32(node, prop, &uV);
+		if (!ret) {
+			range = &vreg->hw_data->voltage_range;
+			selector = DIV_ROUND_UP(uV - range->min_uV,
+					range->uV_step) + range->min_sel;
+			if (uV < range->min_uV || selector > range->max_sel) {
+				dev_err(dev, "%s: %s=%u is invalid\n",
+					node->name, prop, uV);
+				return -EINVAL;
+			}
+
+			vreg->voltage_selector = selector;
+
+			cmd[cmd_count].addr
+				= vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE;
+			cmd[cmd_count++].data
+				= DIV_ROUND_UP(selector * range->uV_step
+						+ range->min_uV, 1000);
+		} else {
+			/*
+			 * Default the voltage selector to an error value in the
+			 * case that qcom,regulator-initial-microvolt is not
+			 * specified in device tree since the true voltage is
+			 * not known.  Note that this value causes
+			 * devm_regulator_register() to fail in the case that
+			 * regulator-min-microvolt and regulator-max-microvolt
+			 * are specified in device tree due to
+			 * machine_constraints_voltage() bailing when the
+			 * get_voltage_sel() callback returns this error value.
+			 */
+			vreg->voltage_selector = -EINVAL;
+		}
+	}
+
+	if (cmd_count) {
+		ret = rpmh_regulator_send_request(vreg, cmd, cmd_count, true);
+		if (ret < 0) {
+			dev_err(dev, "%s: could not send default config, ret=%d\n",
+				node->name, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
+ * vreg:		Pointer to the individual rpmh-regulator resource
+ * dev:			Pointer to the top level rpmh-regulator PMIC device
+ * node:		Pointer to the individual rpmh-regulator resource
+ *			device node
+ * pmic_id:		String used to identify the top level rpmh-regulator
+ *			PMIC device on the board
+ * rpmh_data:		Pointer to a null-terminated array of rpmh-regulator
+ *			resources defined for the top level PMIC device
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
+				struct device_node *node, const char *pmic_id,
+				const struct rpmh_vreg_init_data *rpmh_data)
+{
+	struct regulator_config reg_config = {};
+	char rpmh_resource_name[20] = "";
+	struct regulator_dev *rdev;
+	enum rpmh_regulator_type type;
+	struct regulator_init_data *init_data;
+	int ret;
+
+	vreg->dev = dev;
+
+	for (; rpmh_data->name; rpmh_data++)
+		if (!strcmp(rpmh_data->name, node->name))
+			break;
+
+	if (!rpmh_data->name) {
+		dev_err(dev, "Unknown regulator %s\n", node->name);
+		return -EINVAL;
+	}
+
+	scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name),
+		rpmh_data->resource_name, pmic_id);
+
+	vreg->addr = cmd_db_read_addr(rpmh_resource_name);
+	if (!vreg->addr) {
+		dev_err(dev, "%s: could not find RPMh address for resource %s\n",
+			node->name, rpmh_resource_name);
+		return -ENODEV;
+	}
+
+	vreg->rdesc.name = rpmh_data->name;
+	vreg->rdesc.supply_name = rpmh_data->supply_name;
+	vreg->hw_data = rpmh_data->hw_data;
+
+	if (rpmh_data->hw_data->n_voltages) {
+		vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
+		vreg->rdesc.n_linear_ranges = 1;
+		vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
+	}
+
+	type = rpmh_data->hw_data->regulator_type;
+	if (type == VRM) {
+		ret = rpmh_regulator_parse_vrm_modes(vreg, dev, node);
+		if (ret < 0)
+			return ret;
+	}
+
+	vreg->always_wait_for_ack = of_property_read_bool(node,
+						"qcom,always-wait-for-ack");
+
+	vreg->rdesc.owner	= THIS_MODULE;
+	vreg->rdesc.type	= REGULATOR_VOLTAGE;
+	vreg->rdesc.ops		= vreg->hw_data->ops;
+	vreg->rdesc.of_map_mode	= vreg->hw_data->of_map_mode;
+
+	init_data = of_get_regulator_init_data(dev, node, &vreg->rdesc);
+	if (!init_data)
+		return -ENOMEM;
+
+	if (type == XOB && init_data->constraints.min_uV &&
+	    init_data->constraints.min_uV == init_data->constraints.max_uV) {
+		vreg->rdesc.fixed_uV = init_data->constraints.min_uV;
+		vreg->rdesc.n_voltages = 1;
+	}
+
+	reg_config.dev		= dev;
+	reg_config.init_data	= init_data;
+	reg_config.of_node	= node;
+	reg_config.driver_data	= vreg;
+
+	ret = rpmh_regulator_load_default_parameters(vreg, dev, node);
+	if (ret < 0)
+		return ret;
+
+	rdev = devm_regulator_register(dev, &vreg->rdesc, &reg_config);
+	if (IS_ERR(rdev)) {
+		ret = PTR_ERR(rdev);
+		rdev = NULL;
+		dev_err(dev, "%s: devm_regulator_register() failed, ret=%d\n",
+			node->name, ret);
+		return ret;
+	}
+
+	dev_dbg(dev, "%s regulator registered for RPMh resource %s @ 0x%05X\n",
+		node->name, rpmh_resource_name, vreg->addr);
+
+	return ret;
+}
+
+static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
+	[REGULATOR_MODE_INVALID] = -EINVAL,
+	[REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
+	[REGULATOR_MODE_IDLE]    = PMIC4_LDO_MODE_LPM,
+	[REGULATOR_MODE_NORMAL]  = -EINVAL,
+	[REGULATOR_MODE_FAST]    = PMIC4_LDO_MODE_HPM,
+};
+
+static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int mode)
+{
+	static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+		[RPMH_REGULATOR_MODE_RET]  = REGULATOR_MODE_STANDBY,
+		[RPMH_REGULATOR_MODE_LPM]  = REGULATOR_MODE_IDLE,
+		[RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_INVALID,
+		[RPMH_REGULATOR_MODE_HPM]  = REGULATOR_MODE_FAST,
+	};
+
+	if (mode >= RPMH_REGULATOR_MODE_COUNT)
+		return -EINVAL;
+
+	return of_mode_map[mode];
+}
+
+static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
+	[REGULATOR_MODE_INVALID] = -EINVAL,
+	[REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION,
+	[REGULATOR_MODE_IDLE]    = PMIC4_SMPS_MODE_PFM,
+	[REGULATOR_MODE_NORMAL]  = PMIC4_SMPS_MODE_AUTO,
+	[REGULATOR_MODE_FAST]    = PMIC4_SMPS_MODE_PWM,
+};
+
+static unsigned int rpmh_regulator_pmic4_smps_of_map_mode(unsigned int mode)
+{
+	static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+		[RPMH_REGULATOR_MODE_RET]  = REGULATOR_MODE_STANDBY,
+		[RPMH_REGULATOR_MODE_LPM]  = REGULATOR_MODE_IDLE,
+		[RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_NORMAL,
+		[RPMH_REGULATOR_MODE_HPM]  = REGULATOR_MODE_FAST,
+	};
+
+	if (mode >= RPMH_REGULATOR_MODE_COUNT)
+		return -EINVAL;
+
+	return of_mode_map[mode];
+}
+
+static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
+	[REGULATOR_MODE_INVALID] = -EINVAL,
+	[REGULATOR_MODE_STANDBY] = -EINVAL,
+	[REGULATOR_MODE_IDLE]    = PMIC4_BOB_MODE_PFM,
+	[REGULATOR_MODE_NORMAL]  = PMIC4_BOB_MODE_AUTO,
+	[REGULATOR_MODE_FAST]    = PMIC4_BOB_MODE_PWM,
+};
+
+static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int mode)
+{
+	static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+		[RPMH_REGULATOR_MODE_RET]  = REGULATOR_MODE_INVALID,
+		[RPMH_REGULATOR_MODE_LPM]  = REGULATOR_MODE_IDLE,
+		[RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_NORMAL,
+		[RPMH_REGULATOR_MODE_HPM]  = REGULATOR_MODE_FAST,
+	};
+
+	if (mode >= RPMH_REGULATOR_MODE_COUNT)
+		return -EINVAL;
+
+	return of_mode_map[mode];
+}
+
+static const struct rpmh_vreg_hw_data pmic4_pldo = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
+	.n_voltages = 256,
+	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
+	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
+	.n_voltages = 128,
+	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
+	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_nldo = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
+	.n_voltages = 128,
+	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
+	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
+	.n_voltages = 216,
+	.pmic_mode_map = pmic_mode_map_pmic4_smps,
+	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
+	.n_voltages = 259,
+	.pmic_mode_map = pmic_mode_map_pmic4_smps,
+	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_bob = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_bypass_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
+	.n_voltages = 84,
+	.pmic_mode_map = pmic_mode_map_pmic4_bob,
+	.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_lvs = {
+	.regulator_type = XOB,
+	.ops = &rpmh_regulator_xob_ops,
+	/* LVS hardware does not support voltage or mode configuration. */
+};
+
+#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
+{ \
+	.name		= _name, \
+	.resource_name	= _resource_name, \
+	.hw_data	= _hw_data, \
+	.supply_name	= _supply_name, \
+}
+
+static const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
+	RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
+	RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
+	RPMH_VREG("smps3",  "smp%s3",  &pmic4_hfsmps3,   "vdd-s3"),
+	RPMH_VREG("smps4",  "smp%s4",  &pmic4_hfsmps3,   "vdd-s4"),
+	RPMH_VREG("smps5",  "smp%s5",  &pmic4_hfsmps3,   "vdd-s5"),
+	RPMH_VREG("smps6",  "smp%s6",  &pmic4_ftsmps426, "vdd-s6"),
+	RPMH_VREG("smps7",  "smp%s7",  &pmic4_ftsmps426, "vdd-s7"),
+	RPMH_VREG("smps8",  "smp%s8",  &pmic4_ftsmps426, "vdd-s8"),
+	RPMH_VREG("smps9",  "smp%s9",  &pmic4_ftsmps426, "vdd-s9"),
+	RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"),
+	RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"),
+	RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"),
+	RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"),
+	RPMH_VREG("ldo1",   "ldo%s1",  &pmic4_nldo,      "vdd-l1-l27"),
+	RPMH_VREG("ldo2",   "ldo%s2",  &pmic4_nldo,      "vdd-l2-l8-l17"),
+	RPMH_VREG("ldo3",   "ldo%s3",  &pmic4_nldo,      "vdd-l3-l11"),
+	RPMH_VREG("ldo4",   "ldo%s4",  &pmic4_nldo,      "vdd-l4-l5"),
+	RPMH_VREG("ldo5",   "ldo%s5",  &pmic4_nldo,      "vdd-l4-l5"),
+	RPMH_VREG("ldo6",   "ldo%s6",  &pmic4_pldo,      "vdd-l6"),
+	RPMH_VREG("ldo7",   "ldo%s7",  &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo8",   "ldo%s8",  &pmic4_nldo,      "vdd-l2-l8-l17"),
+	RPMH_VREG("ldo9",   "ldo%s9",  &pmic4_pldo,      "vdd-l9"),
+	RPMH_VREG("ldo10",  "ldo%s10", &pmic4_pldo,      "vdd-l10-l23-l25"),
+	RPMH_VREG("ldo11",  "ldo%s11", &pmic4_nldo,      "vdd-l3-l11"),
+	RPMH_VREG("ldo12",  "ldo%s12", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo13",  "ldo%s13", &pmic4_pldo,      "vdd-l13-l19-l21"),
+	RPMH_VREG("ldo14",  "ldo%s14", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo15",  "ldo%s15", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo16",  "ldo%s16", &pmic4_pldo,      "vdd-l16-l28"),
+	RPMH_VREG("ldo17",  "ldo%s17", &pmic4_nldo,      "vdd-l2-l8-l17"),
+	RPMH_VREG("ldo18",  "ldo%s18", &pmic4_pldo,      "vdd-l18-l22"),
+	RPMH_VREG("ldo19",  "ldo%s19", &pmic4_pldo,      "vdd-l13-l19-l21"),
+	RPMH_VREG("ldo20",  "ldo%s20", &pmic4_pldo,      "vdd-l20-l24"),
+	RPMH_VREG("ldo21",  "ldo%s21", &pmic4_pldo,      "vdd-l13-l19-l21"),
+	RPMH_VREG("ldo22",  "ldo%s22", &pmic4_pldo,      "vdd-l18-l22"),
+	RPMH_VREG("ldo23",  "ldo%s23", &pmic4_pldo,      "vdd-l10-l23-l25"),
+	RPMH_VREG("ldo24",  "ldo%s24", &pmic4_pldo,      "vdd-l20-l24"),
+	RPMH_VREG("ldo25",  "ldo%s25", &pmic4_pldo,      "vdd-l10-l23-l25"),
+	RPMH_VREG("ldo26",  "ldo%s26", &pmic4_nldo,      "vdd-l26"),
+	RPMH_VREG("ldo27",  "ldo%s27", &pmic4_nldo,      "vdd-l1-l27"),
+	RPMH_VREG("ldo28",  "ldo%s28", &pmic4_pldo,      "vdd-l16-l28"),
+	RPMH_VREG("lvs1",   "vs%s1",   &pmic4_lvs,       "vin-lvs-1-2"),
+	RPMH_VREG("lvs2",   "vs%s2",   &pmic4_lvs,       "vin-lvs-1-2"),
+	{},
+};
+
+static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
+	RPMH_VREG("bob",    "bob%s1",  &pmic4_bob,       "vdd-bob"),
+	{},
+};
+
+static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
+	RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
+	RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
+	RPMH_VREG("smps3",  "smp%s3",  &pmic4_ftsmps426, "vdd-s3"),
+	RPMH_VREG("smps4",  "smp%s4",  &pmic4_ftsmps426, "vdd-s4"),
+	{},
+};
+
+static int rpmh_regulator_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct rpmh_vreg_init_data *vreg_data;
+	struct device_node *node;
+	struct rpmh_vreg *vreg;
+	const char *pmic_id;
+	int ret;
+
+	ret = cmd_db_ready();
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Command DB not available, ret=%d\n", ret);
+		return ret;
+	}
+
+	vreg_data = of_device_get_match_data(dev);
+	if (!vreg_data)
+		return -ENODEV;
+
+	ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
+	if (ret < 0) {
+		dev_err(dev, "qcom,pmic-id missing in DT node\n");
+		return ret;
+	}
+
+	for_each_available_child_of_node(dev->of_node, node) {
+		vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
+		if (!vreg) {
+			of_node_put(node);
+			return -ENOMEM;
+		}
+
+		ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
+						vreg_data);
+		if (ret < 0) {
+			of_node_put(node);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct of_device_id rpmh_regulator_match_table[] = {
+	{
+		.compatible = "qcom,pm8998-rpmh-regulators",
+		.data = pm8998_vreg_data,
+	},
+	{
+		.compatible = "qcom,pmi8998-rpmh-regulators",
+		.data = pmi8998_vreg_data,
+	},
+	{
+		.compatible = "qcom,pm8005-rpmh-regulators",
+		.data = pm8005_vreg_data,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
+
+static struct platform_driver rpmh_regulator_driver = {
+	.driver = {
+		.name = "qcom-rpmh-regulator",
+		.of_match_table	= of_match_ptr(rpmh_regulator_match_table),
+	},
+	.probe = rpmh_regulator_probe,
+};
+module_platform_driver(rpmh_regulator_driver);
+
+MODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
+MODULE_LICENSE("GPL v2");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: David Collins @ 2018-05-12  2:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1526088081.git.collinsd@codeaurora.org>

Introduce bindings for RPMh regulator devices found on some
Qualcomm Technlogies, Inc. SoCs.  These devices allow a given
processor within the SoC to make PMIC regulator requests which
are aggregated within the RPMh hardware block along with requests
from other processors in the SoC to determine the final PMIC
regulator hardware state.

Signed-off-by: David Collins <collinsd@codeaurora.org>
---
 .../bindings/regulator/qcom,rpmh-regulator.txt     | 208 +++++++++++++++++++++
 .../dt-bindings/regulator/qcom,rpmh-regulator.h    |  36 ++++
 2 files changed, 244 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
 create mode 100644 include/dt-bindings/regulator/qcom,rpmh-regulator.h

diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
new file mode 100644
index 0000000..ad2185e
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
@@ -0,0 +1,208 @@
+Qualcomm Technologies, Inc. RPMh Regulators
+
+rpmh-regulator devices support PMIC regulator management via the Voltage
+Regulator Manager (VRM) and Oscillator Buffer (XOB) RPMh accelerators.  The APPS
+processor communicates with these hardware blocks via a Resource State
+Coordinator (RSC) using command packets.  The VRM allows changing four
+parameters for a given regulator: enable state, output voltage, operating mode,
+and minimum headroom voltage.  The XOB allows changing only a single parameter
+for a given regulator: its enable state.  Despite its name, the XOB is capable
+of controlling the enable state of any PMIC peripheral.  It is used for clock
+buffers, low-voltage switches, and LDO/SMPS regulators which have a fixed
+voltage and mode.
+
+=======================
+Required Node Structure
+=======================
+
+RPMh regulators must be described in two levels of device nodes.  The first
+level describes the PMIC containing the regulators and must reside within an
+RPMh device node.  The second level describes each regulator within the PMIC
+which is to be used on the board.  Each of these regulators maps to a single
+RPMh resource.
+
+The names used for regulator nodes must match those supported by a given PMIC.
+Supported regulator node names:
+	PM8998:		smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
+	PMI8998:	bob
+	PM8005:		smps1 - smps4
+
+========================
+First Level Nodes - PMIC
+========================
+
+- compatible
+	Usage:      required
+	Value type: <string>
+	Definition: Must be one of: "qcom,pm8998-rpmh-regulators",
+		    "qcom,pmi8998-rpmh-regulators" or
+		    "qcom,pm8005-rpmh-regulators".
+
+- qcom,pmic-id
+	Usage:      required
+	Value type: <string>
+	Definition: RPMh resource name suffix used for the regulators found on
+		    this PMIC.  Typical values: "a", "b", "c", "d", "e", "f".
+
+- vdd-s1-supply
+- vdd-s2-supply
+- vdd-s3-supply
+- vdd-s4-supply
+	Usage:      optional (PM8998 and PM8005 only)
+	Value type: <phandle>
+	Definition: phandle of the parent supply regulator of one or more of the
+		    regulators for this PMIC.
+
+- vdd-s5-supply
+- vdd-s6-supply
+- vdd-s7-supply
+- vdd-s8-supply
+- vdd-s9-supply
+- vdd-s10-supply
+- vdd-s11-supply
+- vdd-s12-supply
+- vdd-s13-supply
+- vdd-l1-l27-supply
+- vdd-l2-l8-l17-supply
+- vdd-l3-l11-supply
+- vdd-l4-l5-supply
+- vdd-l6-supply
+- vdd-l7-l12-l14-l15-supply
+- vdd-l9-supply
+- vdd-l10-l23-l25-supply
+- vdd-l13-l19-l21-supply
+- vdd-l16-l28-supply
+- vdd-l18-l22-supply
+- vdd-l20-l24-supply
+- vdd-l26-supply
+- vin-lvs-1-2-supply
+	Usage:      optional (PM8998 only)
+	Value type: <phandle>
+	Definition: phandle of the parent supply regulator of one or more of the
+		    regulators for this PMIC.
+
+- vdd-bob-supply
+	Usage:      optional (PMI8998 only)
+	Value type: <phandle>
+	Definition: BOB regulator parent supply phandle
+
+===============================
+Second Level Nodes - Regulators
+===============================
+
+- qcom,regulator-initial-microvolt
+	Usage:      optional; VRM regulators only
+	Value type: <u32>
+	Definition: Specifies the initial voltage in microvolts to request for a
+		    VRM regulator.
+
+- regulator-initial-mode
+	Usage:      optional; VRM regulators only
+	Value type: <u32>
+	Definition: Specifies the initial mode to request for a VRM regulator.
+		    Supported values are RPMH_REGULATOR_MODE_* which are defined
+		    in [1] (i.e. 0 to 3).  This property may be specified even
+		    if the regulator-allow-set-load property is not specified.
+
+- qcom,allowed-drms-modes
+	Usage:      required if regulator-allow-set-load is specified;
+		    VRM regulators only
+	Value type: <prop-encoded-array>
+	Definition: A list of integers specifying the PMIC regulator modes which
+		    can be configured at runtime based upon consumer load needs.
+		    Supported values are RPMH_REGULATOR_MODE_* which are defined
+		    in [1] (i.e. 0 to 3).
+
+- qcom,drms-mode-max-microamps
+	Usage:      required if regulator-allow-set-load is specified;
+		    VRM regulators only
+	Value type: <prop-encoded-array>
+	Definition: A list of integers specifying the maximum allowed load
+		    current in microamps for each of the modes listed in
+		    qcom,allowed-drms-modes (matched 1-to-1 in order).  Elements
+		    must be specified in order from lowest to highest value.
+
+- qcom,headroom-microvolt
+	Usage:      optional; VRM regulators only
+	Value type: <u32>
+	Definition: Specifies the headroom voltage in microvolts to request for
+		    a VRM regulator.  RPMh hardware automatically ensures that
+		    the parent of this regulator outputs a voltage high enough
+		    to satisfy the requested headroom.  Supported values are
+		    0 to 511000.
+
+- qcom,always-wait-for-ack
+	Usage:      optional
+	Value type: <empty>
+	Definition: Boolean flag which indicates that the application processor
+		    must wait for an ACK or a NACK from RPMh for every request
+		    sent for this regulator including those which are for a
+		    strictly lower power state.
+
+Other properties defined in Documentation/devicetree/bindings/regulator.txt
+may also be used.
+
+[1] include/dt-bindings/regulator/qcom,rpmh-regulator.h
+
+========
+Examples
+========
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+&apps_rsc {
+	pm8998-rpmh-regulators {
+		compatible = "qcom,pm8998-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vdd-l7-l12-l14-l15-supply = <&pm8998_s5>;
+
+		smps2 {
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,regulator-initial-microvolt = <1100000>;
+		};
+
+		pm8998_s5: smps5 {
+			regulator-min-microvolt = <1904000>;
+			regulator-max-microvolt = <2040000>;
+			qcom,regulator-initial-microvolt = <1904000>;
+		};
+
+		ldo7 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,regulator-initial-microvolt = <1800000>;
+			qcom,headroom-microvolt = <56000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allowed-modes =
+				<RPMH_REGULATOR_MODE_LPM
+				 RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			qcom,allowed-drms-modes =
+				<RPMH_REGULATOR_MODE_LPM
+				 RPMH_REGULATOR_MODE_HPM>;
+			qcom,drms-mode-max-microamps = <10000 1000000>;
+		};
+
+		lvs1 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+	};
+
+	pmi8998-rpmh-regulators {
+		compatible = "qcom,pmi8998-rpmh-regulators";
+		qcom,pmic-id = "b";
+
+		bob {
+			regulator-min-microvolt = <3312000>;
+			regulator-max-microvolt = <3600000>;
+			qcom,regulator-initial-microvolt = <3312000>;
+			regulator-allowed-modes =
+				<RPMH_REGULATOR_MODE_AUTO
+				 RPMH_REGULATOR_MODE_HPM>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+		};
+	};
+};
diff --git a/include/dt-bindings/regulator/qcom,rpmh-regulator.h b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
new file mode 100644
index 0000000..4378c4b
--- /dev/null
+++ b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#ifndef __QCOM_RPMH_REGULATOR_H
+#define __QCOM_RPMH_REGULATOR_H
+
+/*
+ * These mode constants may be used for regulator-initial-mode and
+ * qcom,allowed-drms-modes properties of an RPMh regulator device tree node.
+ * Each type of regulator supports a subset of the possible modes.
+ *
+ * %RPMH_REGULATOR_MODE_RET:	Retention mode in which only an extremely small
+ *				load current is allowed.  This mode is supported
+ *				by LDO and SMPS type regulators.
+ * %RPMH_REGULATOR_MODE_LPM:	Low power mode in which a small load current is
+ *				allowed.  This mode corresponds to PFM for SMPS
+ *				and BOB type regulators.  This mode is supported
+ *				by LDO, HFSMPS, BOB, and PMIC4 FTSMPS type
+ *				regulators.
+ * %RPMH_REGULATOR_MODE_AUTO:	Auto mode in which the regulator hardware
+ *				automatically switches between LPM and HPM based
+ *				upon the real-time load current.  This mode is
+ *				supported by HFSMPS, BOB, and PMIC4 FTSMPS type
+ *				regulators.
+ * %RPMH_REGULATOR_MODE_HPM:	High power mode in which the full rated current
+ *				of the regulator is allowed.  This mode
+ *				corresponds to PWM for SMPS and BOB type
+ *				regulators.  This mode is supported by all types
+ *				of regulators.
+ */
+#define RPMH_REGULATOR_MODE_RET		0
+#define RPMH_REGULATOR_MODE_LPM		1
+#define RPMH_REGULATOR_MODE_AUTO	2
+#define RPMH_REGULATOR_MODE_HPM		3
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH v3 0/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-05-12  2:28 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds a driver and device tree binding documentation for
PMIC regulator control via Resource Power Manager-hardened (RPMh) on some
Qualcomm Technologies, Inc. SoCs such as SDM845.  RPMh is a hardware block
which contains several accelerators which are used to manage various
hardware resources that are shared between the processors of the SoC.  The
final hardware state of a regulator is determined within RPMh by performing
max aggregation of the requests made by all of the processors.

The RPMh regulator driver depends upon the RPMh driver [1] and command DB
driver [2] which are both still undergoing review.  It also depends upon
two recent of_regulator changes: [3] and [4].

Changes since v2 [5]:
 - Replaced '_' with '-' in device tree supply property names
 - Renamed qcom_rpmh-regulator.c to be qcom-rpmh-regulator.c
 - Updated various DT property names to use "microvolt" and "microamp"
 - Moved allowed modes constraint specification out of the driver [4]
 - Replaced rpmh_client with device pointer to match new RPMh API [1]
 - Corrected drms mode threshold checking
 - Initialized voltage_selector to -EINVAL when not specified in DT
 - Added constants for PMIC regulator hardware modes
 - Corrected type sign of mode mapping tables
 - Made variable names for mode arrays plural
 - Simplified Kconfig depends on
 - Removed unnecessary constants and struct fields
 - Added some descriptive comments

Changes since v1 [6]:
 - Addressed review feedback from Doug, Mark, and Stephen
 - Replaced set_voltage()/get_voltage() callbacks with set_voltage_sel()/
   get_voltage_sel()
 - Added set_bypass()/get_bypass() callbacks for BOB pass-through mode
   control
 - Removed top-level PMIC data structures
 - Removed initialization variables from structs and passed them as
   function parameters
 - Removed various comments and error messages
 - Simplified mode handling
 - Refactored per-PMIC rpmh-regulator data specification
 - Simplified probe function
 - Moved header into DT patch
 - Removed redundant property listings from DT binding documentation

[1]: https://lkml.org/lkml/2018/5/9/729
[2]: https://lkml.org/lkml/2018/4/10/714
[3]: https://patchwork.kernel.org/patch/10348629
[4]: https://lkml.org/lkml/2018/5/11/696
[5]: https://lkml.org/lkml/2018/4/13/687
[6]: https://lkml.org/lkml/2018/3/16/1431

David Collins (2):
  regulator: dt-bindings: add QCOM RPMh regulator bindings
  regulator: add QCOM RPMh regulator driver

 .../bindings/regulator/qcom,rpmh-regulator.txt     | 208 +++++
 drivers/regulator/Kconfig                          |   9 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/qcom-rpmh-regulator.c            | 925 +++++++++++++++++++++
 .../dt-bindings/regulator/qcom,rpmh-regulator.h    |  36 +
 5 files changed, 1179 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
 create mode 100644 drivers/regulator/qcom-rpmh-regulator.c
 create mode 100644 include/dt-bindings/regulator/qcom,rpmh-regulator.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH]irqchip/irq-gic-v3:Avoid a waste of LPI resource
From: Zhang, Lei @ 2018-05-12  1:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <907eb976-7a26-2800-bf1a-563aca482235@arm.com>

Hi Marc
> -----Original Message-----
> From: linux-arm-kernel
> [mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf Of Marc
> Zyngier
> Sent: Thursday, May 10, 2018 11:12 PM
> To: Zhang, Lei/? ?; 'Mark Langsdorf'; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH]irqchip/irq-gic-v3:Avoid a waste of LPI resource
for device.
> 
> I do not believe this is required. nvec already describes the number of
> LPIs that are expected by the device. Why should we add a new parameter
> that looks to be the exact same thing?
yes. As you referred, it seems not really required. I will delete this parameter. 

> 
> Another problem is that this approach isn't really practical.
> msi_prepare is part of a generic structure, and changing it will impact
> all the others users of that structure. I'd rather you don't change its
> prototype for something that is implementation specific.
> 
> Instead, we have the msi_alloc_info_t structure, which is explicitly
> designed to collate information pertaining to the allocation
> requirements in an implementation agnostic way.
> At the moment, the ITS code only uses the first entry of the scratchpad
> area to store the DeviceID (and subsequently a pointer to the
> corresponding its_device).
> 
> You could use the second entry to encode the alignment requirement.
I think it is a good idea for compatibility. I accept your suggestion.
 

> The problem is that you now increase the footprint of the bitmap by a
> factor of 32:
> 
> - For a system with 16bit INTIDs, you go from 256 bytes to 8kB. That's
> bad, but OK, fine.
> 
> - For a system with 32bit INTIDs, you go from 16MB (which was already
> horrible) to 512MB. That's unacceptable.
> 
> At that point, using a simple bitmap doesn't work anymore, and we're
> better off switching to a free list of some sort that would keep the
> memory overhead to a minimum (and actually radically reduce the
> footprint even in the smallest configurations).
I will reconsider how to management LPI with small
memory overhead as possible as I can. 

By the way I will finish my patch in the next week.

Regards,
Lei Zhang
--
Lei Zhang  e-mail: zhang.lei at jp.fujitsu.com FUJITSU LIMITED

^ permalink raw reply

* [PATCH 2/2] regulator: of: add support for allowed modes configuration
From: David Collins @ 2018-05-12  1:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1526088289.git.collinsd@codeaurora.org>

Add support for configuring the machine constraints
valid_modes_mask element based on a list of allowed modes
specified via a device tree property.

Signed-off-by: David Collins <collinsd@codeaurora.org>
---
 drivers/regulator/of_regulator.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 0d3f73e..d61fed2 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -32,7 +32,7 @@ static void of_get_regulation_constraints(struct device_node *np,
 	struct regulator_state *suspend_state;
 	struct device_node *suspend_np;
 	unsigned int mode;
-	int ret, i;
+	int ret, i, len;
 	u32 pval;
 
 	constraints->name = of_get_property(np, "regulator-name", NULL);
@@ -136,6 +136,33 @@ static void of_get_regulation_constraints(struct device_node *np,
 		}
 	}
 
+	len = of_property_count_elems_of_size(np, "regulator-allowed-modes",
+						sizeof(u32));
+	if (len > 0) {
+		if (desc && desc->of_map_mode) {
+			for (i = 0; i < len; i++) {
+				ret = of_property_read_u32_index(np,
+					"regulator-allowed-modes", i, &pval);
+				if (ret) {
+					pr_err("%s: couldn't read allowed modes index %d, ret=%d\n",
+						np->name, i, ret);
+					break;
+				}
+				mode = desc->of_map_mode(pval);
+				if (mode == REGULATOR_MODE_INVALID)
+					pr_err("%s: invalid regulator-allowed-modes element %u\n",
+						np->name, pval);
+				else
+					constraints->valid_modes_mask |= mode;
+			}
+			if (constraints->valid_modes_mask)
+				constraints->valid_ops_mask
+					|= REGULATOR_CHANGE_MODE;
+		} else {
+			pr_warn("%s: mode mapping not defined\n", np->name);
+		}
+	}
+
 	if (!of_property_read_u32(np, "regulator-system-load", &pval))
 		constraints->system_load = pval;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH 1/2] regulator: of: add property for allowed modes specification
From: David Collins @ 2018-05-12  1:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1526088289.git.collinsd@codeaurora.org>

Add a common device tree property for regulator nodes to support
the specification of allowed operating modes.

Signed-off-by: David Collins <collinsd@codeaurora.org>
---
 Documentation/devicetree/bindings/regulator/regulator.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 2babe15b..c627aa0 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -59,6 +59,11 @@ Optional properties:
 - regulator-initial-mode: initial operating mode. The set of possible operating
   modes depends on the capabilities of every hardware so each device binding
   documentation explains which values the regulator supports.
+- regulator-allowed-modes: list of operating modes that software is allowed to
+  configure for the regulator at run-time.  Elements may be specified in any
+  order.  The set of possible operating modes depends on the capabilities of
+  every hardware so each device binding document explains which values the
+  regulator supports.
 - regulator-system-load: Load in uA present on regulator that is not captured by
   any consumer request.
 - regulator-pull-down: Enable pull down resistor when the regulator is disabled.
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH 0/2] regulator: of: add device tree property for allowed modes
From: David Collins @ 2018-05-12  1:46 UTC (permalink / raw)
  To: linux-arm-kernel

There is currently no accepted way to configure constraints->valid_modes_mask
for regulators defined in device tree.  This patch series defines a new
common regulator device tree property, regulator-allowed-modes, which can be
used to specify the set of modes that the regulator is allowed to use.
It also implements parsing for this new property inside of the
of_get_regulation_constraints() function.

David Collins (2):
  regulator: of: add property for allowed modes specification
  regulator: of: add support for allowed modes configuration

 .../devicetree/bindings/regulator/regulator.txt    |  5 ++++
 drivers/regulator/of_regulator.c                   | 29 +++++++++++++++++++++-
 2 files changed, 33 insertions(+), 1 deletion(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH 2/2] clk: davinci: psc-dm365: fix few clocks
From: David Lechner @ 2018-05-12  1:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180511141037.25250-3-nsekhar@ti.com>

On 05/11/2018 09:10 AM, Sekhar Nori wrote:
> Fix parent of emac and voice codec PSC clocks. This now matches
> existing implementation in arch/arm/mach-davinci/dm365.c
> 
> Also, there is only one power domain on DM365. Fix the power
> domain of voice codec and vpss dac modules.
> 
> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> ---
>   drivers/clk/davinci/psc-dm365.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/davinci/psc-dm365.c b/drivers/clk/davinci/psc-dm365.c
> index 5b5b55b0b59a..beeda10fd2f0 100644
> --- a/drivers/clk/davinci/psc-dm365.c
> +++ b/drivers/clk/davinci/psc-dm365.c
> @@ -65,9 +65,9 @@ static const struct davinci_lpsc_clk_info dm365_psc_info[] = {
>   	LPSC(31, 0, arm,         pll2_sysclk2, NULL,               LPSC_ALWAYS_ENABLED),
>   	LPSC(38, 0, spi3,        pll1_sysclk4, spi3_clkdev,        0),
>   	LPSC(39, 0, spi4,        pll1_auxclk,  spi4_clkdev,        0),
> -	LPSC(40, 0, emac,        pll2_sysclk4, emac_clkdev,        0),
> -	LPSC(44, 1, voice_codec, pll1_sysclk3, voice_codec_clkdev, 0),
> -	LPSC(46, 1, vpss_dac,    pll1_sysclk3, vpss_dac_clkdev,    0),
> +	LPSC(40, 0, emac,        pll1_sysclk4, emac_clkdev,        0),
> +	LPSC(44, 0, voice_codec, pll2_sysclk4, voice_codec_clkdev, 0),
> +	LPSC(46, 0, vpss_dac,    pll1_sysclk3, vpss_dac_clkdev,    0),
>   	LPSC(47, 0, vpss_master, pll1_sysclk5, vpss_master_clkdev, 0),
>   	LPSC(50, 0, mjcp,        pll1_sysclk3, NULL,               0),
>   	{ }
> 

Slightly off topic...

Hmm... Looking at the TRM, I see that there are a bunch of mux clocks that we
have not implemented for the DM365 (all of the clocks in the VPSS_CLK_CTRL and
PERI_CLKCTL registers). I'm wondering if we should be creating drivers for
those like the DA8XX CFGCHIP clock driver.

Back on topic...

The emac fix here looks good.

The TRM (sprufg5a.pdf) shows that there is a DIV2 clock (part of the
PERI_CLKCTL register) between PLL2 SYSCLK4 and Voice Codec in Figure 5,
It also shows PLL1 SYSCLK4 as a second parent clock to Voice Codec, however
this dependency has probably gone unnoticed because so many other devices
also use that same clock, it will pretty much always be on. In Figure 38,
on the other hand, PLL1 SYSCLK4 is shown as the only parent of Voice Codec.

So, I am thinking that pll1_sysclk4 is the correct parent for the
voice_codec clock here since it is the only one listed in Figure 38
(which is in the PSC section of the TRM). The pll2_sysclk4 clock should
probably be used by the video codec device driver directly (well, the
DIV2 clock really, but we don't have a driver for that yet).

The vpss_dac clock in not very clear in the TRM. In Table 39, the name
for LPSC 46, which we are calling "vpss_dac", is "VDAC CLK". In Figure
37, however, there is not a node that matches exactly. There is "VIDEO
DAC", which I take to be the same clock though. This has parent clocks
of PLL1 SYSCLK6 and PLL1 AUXCLK. So, I am guessing that pll1_sysclk6
should be the parent here rather than pll1_sysclk3. According to Figure
5, PLL1 SYSCLK3 only feeds HDVPID and MJCP, which I don't think are the
same as the video DAC since they are also listed separately in Figure 5.

^ permalink raw reply

* [PATCH 1/2] clk: davinci: pll-dm646x: keep PLL2 SYSCLK1 always enabled
From: David Lechner @ 2018-05-12  1:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180511141037.25250-2-nsekhar@ti.com>

On 05/11/2018 09:10 AM, Sekhar Nori wrote:
> PLL2 SYSCLK1 on DM646x is connected to DDR2 PHY and cannot
> be disabled. Mark it so to prevent unused clock disable
> infrastructure from disabling it.
> 
> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> ---
>   drivers/clk/davinci/pll-dm646x.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/davinci/pll-dm646x.c b/drivers/clk/davinci/pll-dm646x.c
> index eb96dd72b6b7..5bdf1cb5fda8 100644
> --- a/drivers/clk/davinci/pll-dm646x.c
> +++ b/drivers/clk/davinci/pll-dm646x.c
> @@ -72,7 +72,7 @@ static const struct davinci_pll_clk_info dm646x_pll2_info = {
>   	.flags = 0,
>   };
>   
> -SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0);
> +SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, SYSCLK_ALWAYS_ENABLED);
>   
>   int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
>   {
> 

Reviewed-by: David Lechner <david@lechnology.com>

^ permalink raw reply

* 答复: [PATCH v3 2/2] arm64: dts: hi3660: Add pcie msi interrupt attribute
From: songxiaowei @ 2018-05-12  0:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5AF5A411.4010507@hisilicon.com>

Hi Wei,

Thanks a lot.

Xiaowei.

> -----????-----
> ???: xuwei (O)
> ????: 2018?5?11? 22:09
> ???: chenyao (F) <chenyao11@huawei.com>; songxiaowei
> <songxiaowei@hisilicon.com>; Wangbinghui <wangbinghui@hisilicon.com>;
> lorenzo.pieralisi at arm.com; bhelgaas at google.com; robh+dt at kernel.org;
> mark.rutland at arm.com; catalin.marinas at arm.com; will.deacon at arm.com;
> linux-pci at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org
> ??: dimitrysh at google.com; guodong.xu at linaro.org; Suzhuangluan
> <suzhuangluan@hisilicon.com>; Kongfei <kongfei@hisilicon.com>; xuwei (O)
> <xuwei5@huawei.com>
> ??: Re: [PATCH v3 2/2] arm64: dts: hi3660: Add pcie msi interrupt attribute
> 
> Hi Yao,
> 
> On 2018/5/11 10:15, Yao Chen wrote:
> > Add pcie msi interrupt attribute for hi3660 SOC.
> >
> > Signed-off-by: Yao Chen <chenyao11@huawei.com>
> 
> Applied patch 2 into the hisilicon dt tree.
> Thanks!
> 
> BR,
> Wei
> 
> > ---
> >  arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> > index ec3eb8e..2cef8f4 100644
> > --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> > +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> > @@ -872,6 +872,8 @@
> >  				  0x0 0x02000000>;
> >  			num-lanes = <1>;
> >  			#interrupt-cells = <1>;
> > +			interrupts = <0 283 4>;
> > +			interrupt-names = "msi";
> >  			interrupt-map-mask = <0xf800 0 0 7>;
> >  			interrupt-map = <0x0 0 0 1
> >  					 &gic GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
> >

^ 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