Merge tag 'qcom-2024.04-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-snapdragon

Qualcomm architecture changes:

* Move clock and pinctrl drivers out of mach-snapdragon
* Various clock driver improvements
* Convert PMIC power/reset key driver to use the button API
* Preparetory work for migrating to upstream DT
diff --git a/MAINTAINERS b/MAINTAINERS
index 4fec063..da477a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -575,9 +575,12 @@
 R:	Sumit Garg <sumit.garg@linaro.org>
 S:	Maintained
 F:	arch/arm/mach-snapdragon/
+F:	drivers/button/button-qcom-pmic.c
+F:	drivers/clk/qcom/
 F:	drivers/gpio/msm_gpio.c
 F:	drivers/mmc/msm_sdhci.c
 F:	drivers/phy/msm8916-usbh-phy.c
+F:	drivers/pinctrl/qcom/
 F:	drivers/serial/serial_msm.c
 F:	drivers/serial/serial_msm_geni.c
 F:	drivers/smem/msm_smem.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2d4458b..9e73b69 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -776,6 +776,8 @@
 	select CLK
 	select SMEM
 	select OF_CONTROL
+	select CLK_QCOM_IPQ4019
+	select PINCTRL_QCOM_IPQ4019
 	imply CMD_DM
 
 config ARCH_KEYSTONE
@@ -1076,6 +1078,7 @@
 	select DM
 	select DM_GPIO
 	select DM_SERIAL
+	select DM_RESET
 	select GPIO_EXTRA_HEADER
 	select MSM_SMEM
 	select OF_CONTROL
diff --git a/arch/arm/dts/dragonboard410c-uboot.dtsi b/arch/arm/dts/dragonboard410c-uboot.dtsi
index 3b0bd0e..cec64bf 100644
--- a/arch/arm/dts/dragonboard410c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard410c-uboot.dtsi
@@ -42,14 +42,3 @@
 		gpios = <&pm8916_gpios 3 0>;
 	};
 };
-
-
-&pm8916_pon {
-	key_vol_down {
-		gpios = <&pm8916_pon 1 0>;
-	};
-
-	key_power {
-		gpios = <&pm8916_pon 0 0>;
-	};
-};
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts
index 9230dd3..6a4e3cc 100644
--- a/arch/arm/dts/dragonboard410c.dts
+++ b/arch/arm/dts/dragonboard410c.dts
@@ -147,20 +147,31 @@
 				#address-cells = <0x1>;
 				#size-cells = <0x1>;
 
-				pm8916_pon: pm8916_pon@800 {
-					compatible = "qcom,pm8916-pwrkey";
-					reg = <0x800 0x96>;
-					#gpio-cells = <2>;
-					gpio-controller;
+				pon@800 {
+					compatible = "qcom,pm8916-pon";
+					reg = <0x800 0x100>;
+					mode-bootloader = <0x2>;
+					mode-recovery = <0x1>;
+
+					pwrkey {
+						compatible = "qcom,pm8941-pwrkey";
+						debounce = <15625>;
+						bias-pull-up;
+					};
+
+					pm8916_resin: resin {
+						compatible = "qcom,pm8941-resin";
+						debounce = <15625>;
+						bias-pull-up;
+					};
 				};
 
 				pm8916_gpios: pm8916_gpios@c000 {
 					compatible = "qcom,pm8916-gpio";
 					reg = <0xc000 0x400>;
 					gpio-controller;
-					gpio-count = <4>;
+					gpio-ranges = <&pm8916_gpios 0 0 4>;
 					#gpio-cells = <2>;
-					gpio-bank-name="pmic";
 				};
 			};
 
diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi
index 457728a..d93c7c1 100644
--- a/arch/arm/dts/dragonboard820c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard820c-uboot.dtsi
@@ -30,15 +30,3 @@
 		};
 	};
 };
-
-&pm8994_pon {
-	key_vol_down {
-		gpios = <&pm8994_pon 1 0>;
-		label = "key_vol_down";
-	};
-
-	key_power {
-		gpios = <&pm8994_pon 0 0>;
-		label = "key_power";
-	};
-};
diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts
index ad201d4..146a0af 100644
--- a/arch/arm/dts/dragonboard820c.dts
+++ b/arch/arm/dts/dragonboard820c.dts
@@ -109,21 +109,31 @@
 				#address-cells = <0x1>;
 				#size-cells = <0x1>;
 
-				pm8994_pon: pm8994_pon@800 {
-					compatible = "qcom,pm8994-pwrkey";
-					reg = <0x800 0x96>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					gpio-bank-name="pm8994_key.";
+				pm8994_pon: pon@800 {
+					compatible = "qcom,pm8916-pon";
+					reg = <0x800 0x100>;
+					mode-bootloader = <0x2>;
+					mode-recovery = <0x1>;
+
+					pwrkey {
+						compatible = "qcom,pm8941-pwrkey";
+						debounce = <15625>;
+						bias-pull-up;
+					};
+
+					pm8994_resin: resin {
+						compatible = "qcom,pm8941-resin";
+						debounce = <15625>;
+						bias-pull-up;
+					};
 				};
 
 				pm8994_gpios: pm8994_gpios@c000 {
 					compatible = "qcom,pm8994-gpio";
 					reg = <0xc000 0x400>;
 					gpio-controller;
-					gpio-count = <24>;
+					gpio-ranges = <&pm8994_gpios 0 0 22>;
 					#gpio-cells = <2>;
-					gpio-bank-name="pm8994.";
 				};
 			};
 
diff --git a/arch/arm/dts/dragonboard845c-uboot.dtsi b/arch/arm/dts/dragonboard845c-uboot.dtsi
index 7106db8..775f45c 100644
--- a/arch/arm/dts/dragonboard845c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard845c-uboot.dtsi
@@ -19,19 +19,8 @@
 			bootph-all;
 		};
 
-		pinctrl_north@3900000 {
+		pinctrl@3400000 {
 			bootph-all;
 		};
 	};
 };
-
-&pm8998_pon {
-	key_vol_down {
-		gpios = <&pm8998_pon 1 0>;
-		label = "key_vol_down";
-	};
-	key_power {
-		gpios = <&pm8998_pon 0 0>;
-		label = "key_power";
-	};
-};
diff --git a/arch/arm/dts/dragonboard845c.dts b/arch/arm/dts/dragonboard845c.dts
index b4f057a..054f253 100644
--- a/arch/arm/dts/dragonboard845c.dts
+++ b/arch/arm/dts/dragonboard845c.dts
@@ -41,4 +41,8 @@
 	};
 };
 
+&pm8998_resin {
+	status = "okay";
+};
+
 #include "dragonboard845c-uboot.dtsi"
diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi
index 0850ae5..f9489e4 100644
--- a/arch/arm/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/dts/qcom-ipq4019.dtsi
@@ -66,14 +66,6 @@
 			status = "disabled";
 		};
 
-		reset: gcc-reset@1800000 {
-			compatible = "qcom,gcc-reset-ipq4019";
-			reg = <0x1800000 0x60000>;
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-			bootph-all;
-		};
-
 		soc_gpios: pinctrl@1000000 {
 			compatible = "qcom,ipq4019-pinctrl";
 			reg = <0x1000000 0x300000>;
@@ -136,7 +128,7 @@
 			#phy-cells = <0>;
 			reg = <0x9a000 0x800>;
 			reg-names = "phy_base";
-			resets = <&reset USB3_UNIPHY_PHY_ARES>;
+			resets = <&gcc USB3_UNIPHY_PHY_ARES>;
 			reset-names = "por_rst";
 			status = "disabled";
 		};
@@ -146,7 +138,7 @@
 			#phy-cells = <0>;
 			reg = <0xa6000 0x40>;
 			reg-names = "phy_base";
-			resets = <&reset USB3_HSPHY_POR_ARES>, <&reset USB3_HSPHY_S_ARES>;
+			resets = <&gcc USB3_HSPHY_POR_ARES>, <&gcc USB3_HSPHY_S_ARES>;
 			reset-names = "por_rst", "srif_rst";
 			status = "disabled";
 		};
@@ -179,7 +171,7 @@
 			#phy-cells = <0>;
 			reg = <0xa8000 0x40>;
 			reg-names = "phy_base";
-			resets = <&reset USB2_HSPHY_POR_ARES>, <&reset USB2_HSPHY_S_ARES>;
+			resets = <&gcc USB2_HSPHY_POR_ARES>, <&gcc USB2_HSPHY_S_ARES>;
 			reset-names = "por_rst", "srif_rst";
 			status = "disabled";
 		};
diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts
index 8d7893c..07bf7dd 100644
--- a/arch/arm/dts/qcs404-evb.dts
+++ b/arch/arm/dts/qcs404-evb.dts
@@ -208,11 +208,6 @@
 			#address-cells = <0x1>;
 			#size-cells = <0x0>;
 			#clock-cells = <1>;
-		};
-
-		reset: gcc-reset@1800000 {
-			compatible = "qcom,gcc-reset-qcs404";
-			reg = <0x1800000 0x80000>;
 			#reset-cells = <1>;
 		};
 
@@ -245,8 +240,8 @@
 			clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>,
 				 <&gcc GCC_USB3_PHY_PIPE_CLK>;
 			clock-names = "ahb", "pipe";
-			resets = <&reset GCC_USB3_PHY_BCR>,
-				 <&reset GCC_USB3PHY_PHY_BCR>;
+			resets = <&gcc GCC_USB3_PHY_BCR>,
+				 <&gcc GCC_USB3PHY_PHY_BCR>;
 			reset-names = "com", "phy";
 		};
 
@@ -257,8 +252,8 @@
 			clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>,
 				 <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
 			clock-names = "ahb", "sleep";
-			resets = <&reset GCC_USB_HS_PHY_CFG_AHB_BCR>,
-				 <&reset GCC_USB2A_PHY_BCR>;
+			resets = <&gcc GCC_USB_HS_PHY_CFG_AHB_BCR>,
+				 <&gcc GCC_USB2A_PHY_BCR>;
 			reset-names = "phy", "por";
 		};
 
@@ -269,8 +264,8 @@
 			clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>,
 				 <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
 			clock-names = "ahb", "sleep";
-			resets = <&reset GCC_QUSB2_PHY_BCR>,
-				 <&reset GCC_USB2_HS_PHY_ONLY_BCR>;
+			resets = <&gcc GCC_QUSB2_PHY_BCR>,
+				 <&gcc GCC_USB2_HS_PHY_ONLY_BCR>;
 			reset-names = "phy", "por";
 		};
 
@@ -335,7 +330,7 @@
 				 <&gcc GCC_ETH_PTP_CLK>,
 				 <&gcc GCC_ETH_RGMII_CLK>;
 
-			resets = <&reset GCC_EMAC_BCR>;
+			resets = <&gcc GCC_EMAC_BCR>;
 			reset-names = "emac";
 
 			snps,tso;
@@ -367,9 +362,10 @@
 
 		spmi@200f000 {
 			compatible = "qcom,spmi-pmic-arb";
-			reg = <0x200f000 0x1000
-			       0x2400000 0x400000
-			       0x2c00000 0x400000>;
+			reg = <0x200f000 0x001000>,
+			      <0x2400000 0x800000>,
+			      <0x2c00000 0x800000>;
+			reg-names = "core", "chnls", "obsrvr";
 			#address-cells = <0x1>;
 			#size-cells = <0x1>;
 
@@ -383,9 +379,8 @@
 					compatible = "qcom,pms405-gpio";
 					reg = <0xc000 0x400>;
 					gpio-controller;
-					gpio-count = <12>;
+					gpio-ranges = <&pms405_gpios 0 0 12>;
 					#gpio-cells = <2>;
-					gpio-bank-name="pmic";
 				};
 			};
 		};
diff --git a/arch/arm/dts/sdm845.dtsi b/arch/arm/dts/sdm845.dtsi
index 3b86b93..96c9749 100644
--- a/arch/arm/dts/sdm845.dtsi
+++ b/arch/arm/dts/sdm845.dtsi
@@ -26,23 +26,13 @@
 			#power-domain-cells = <1>;
 		};
 
-		gpio_north: gpio_north@3900000 {
-			#gpio-cells = <2>;
-			compatible = "qcom,sdm845-pinctrl";
-			reg = <0x3900000 0x400000>;
-			gpio-count = <150>;
-			gpio-controller;
-			gpio-ranges = <&gpio_north 0 0 150>;
-			gpio-bank-name = "soc_north.";
-		};
-
-		tlmm_north: pinctrl_north@3900000 {
+		tlmm: pinctrl@3400000 {
 			compatible = "qcom,sdm845-pinctrl";
-			reg = <0x3900000 0x400000>;
+			reg = <0x3400000 0xc00000>;
 			gpio-count = <150>;
 			gpio-controller;
 			#gpio-cells = <2>;
-			gpio-ranges = <&tlmm_north 0 0 150>;
+			gpio-ranges = <&tlmm 0 0 150>;
 
 			/* DEBUG UART */
 			qup_uart9: qup-uart9-default {
@@ -73,7 +63,7 @@
 			reg = <0xc440000 0x1100>,
 			      <0xc600000 0x2000000>,
 			      <0xe600000 0x100000>;
-			reg-names = "cnfg", "core", "obsrvr";
+			reg-names = "core", "chnls", "obsrvr";
 			#address-cells = <0x1>;
 			#size-cells = <0x1>;
 
@@ -88,21 +78,33 @@
 				#address-cells = <0x1>;
 				#size-cells = <0x1>;
 
-				pm8998_pon: pm8998_pon@800 {
-					compatible = "qcom,pm8998-pwrkey";
+				pm8998_pon: pon@800 {
+					compatible = "qcom,pm8998-pon";
+
 					reg = <0x800 0x100>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					gpio-bank-name = "pm8998_key.";
+					mode-bootloader = <0x2>;
+					mode-recovery = <0x1>;
+
+					pm8998_pwrkey: pwrkey {
+						compatible = "qcom,pm8941-pwrkey";
+						debounce = <15625>;
+						bias-pull-up;
+					};
+
+					pm8998_resin: resin {
+						compatible = "qcom,pm8941-resin";
+						debounce = <15625>;
+						bias-pull-up;
+						status = "disabled";
+					};
 				};
 
 				pm8998_gpios: pm8998_gpios@c000 {
 					compatible = "qcom,pm8998-gpio";
 					reg = <0xc000 0x1a00>;
 					gpio-controller;
-					gpio-count = <21>;
+					gpio-ranges = <&pm8998_gpios 0 0 26>;
 					#gpio-cells = <2>;
-					gpio-bank-name = "pm8998.";
 				};
 			};
 
diff --git a/arch/arm/dts/starqltechn-uboot.dtsi b/arch/arm/dts/starqltechn-uboot.dtsi
index d81a22f..55c6d18 100644
--- a/arch/arm/dts/starqltechn-uboot.dtsi
+++ b/arch/arm/dts/starqltechn-uboot.dtsi
@@ -19,22 +19,9 @@
 		clock-controller@100000 {
 			bootph-all;
 		};
-		gpio_north@3900000 {
+		pinctrl@3400000 {
 			bootph-all;
 		};
-		pinctrl_north@3900000 {
-			bootph-all;
-		};
 	};
 };
 
-&pm8998_pon {
-	key_vol_down {
-		gpios = <&pm8998_pon 1 0>;
-		label = "key_vol_down";
-	};
-	key_power {
-		gpios = <&pm8998_pon 0 0>;
-		label = "key_power";
-	};
-};
diff --git a/arch/arm/dts/starqltechn.dts b/arch/arm/dts/starqltechn.dts
index eec51d1..0842e19 100644
--- a/arch/arm/dts/starqltechn.dts
+++ b/arch/arm/dts/starqltechn.dts
@@ -45,35 +45,23 @@
 		format = "a8r8g8b8";
 	};
 
-	gpio-keys {
-		compatible = "gpio-keys";
-
-		key-pwr {
-			label = "Power";
-			linux,code = <KEY_ENTER>;
-			gpios = <&pm8998_pon 0 GPIO_ACTIVE_LOW>;
-		};
-
-		key-vol-down {
-			label = "Volume Down";
-			linux,code = <KEY_DOWN>;
-			gpios = <&pm8998_pon 1 GPIO_ACTIVE_LOW>;
-		};
-	};
-
 	soc: soc {
 		serial@a84000 {
 			status = "okay";
 		};
+	};
+};
 
-		pinctrl_north@3900000 {
-			muic_i2c: muic_i2c {
-				pins = "GPIO_33", "GPIO_34";
-				drive-strength = <0x2>;
-				function = "gpio";
-				bias-disable;
-			};
-		};
+&pm8998_resin {
+	status = "okay";
+};
+
+&tlmm {
+	muic_i2c: muic-i2c-n {
+		pins = "GPIO_33", "GPIO_34";
+		drive-strength = <0x2>;
+		function = "gpio";
+		bias-disable;
 	};
 };
 
diff --git a/arch/arm/mach-ipq40xx/Makefile b/arch/arm/mach-ipq40xx/Makefile
deleted file mode 100644
index 08a65b8..0000000
--- a/arch/arm/mach-ipq40xx/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# Copyright (c) 2019 Sartura Ltd.
-#
-# Author: Robert Marko <robert.marko@sartura.hr>
-
-obj-y += clock-ipq4019.o
-obj-y += pinctrl-snapdragon.o
-obj-y += pinctrl-ipq4019.o
diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/arch/arm/mach-ipq40xx/clock-ipq4019.c
deleted file mode 100644
index c1d5c4e..0000000
--- a/arch/arm/mach-ipq40xx/clock-ipq4019.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Clock drivers for Qualcomm IPQ40xx
- *
- * Copyright (c) 2020 Sartura Ltd.
- *
- * Author: Robert Marko <robert.marko@sartura.hr>
- *
- */
-
-#include <clk-uclass.h>
-#include <common.h>
-#include <dm.h>
-#include <errno.h>
-
-#include <dt-bindings/clock/qcom,ipq4019-gcc.h>
-
-struct msm_clk_priv {
-	phys_addr_t base;
-};
-
-ulong msm_set_rate(struct clk *clk, ulong rate)
-{
-	switch (clk->id) {
-	case GCC_BLSP1_UART1_APPS_CLK: /*UART1*/
-		/* This clock is already initialized by SBL1 */
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-static int msm_clk_probe(struct udevice *dev)
-{
-	struct msm_clk_priv *priv = dev_get_priv(dev);
-
-	priv->base = dev_read_addr(dev);
-	if (priv->base == FDT_ADDR_T_NONE)
-		return -EINVAL;
-
-	return 0;
-}
-
-static ulong msm_clk_set_rate(struct clk *clk, ulong rate)
-{
-	return msm_set_rate(clk, rate);
-}
-
-static int msm_enable(struct clk *clk)
-{
-	switch (clk->id) {
-	case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/
-		/* This clock is already initialized by SBL1 */
-		return 0;
-	case GCC_PRNG_AHB_CLK: /*PRNG*/
-		/* This clock is already initialized by SBL1 */
-		return 0;
-	case GCC_USB3_MASTER_CLK:
-	case GCC_USB3_SLEEP_CLK:
-	case GCC_USB3_MOCK_UTMI_CLK:
-	case GCC_USB2_MASTER_CLK:
-	case GCC_USB2_SLEEP_CLK:
-	case GCC_USB2_MOCK_UTMI_CLK:
-		/* These clocks is already initialized by SBL1 */
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-static struct clk_ops msm_clk_ops = {
-	.set_rate = msm_clk_set_rate,
-	.enable = msm_enable,
-};
-
-static const struct udevice_id msm_clk_ids[] = {
-	{ .compatible = "qcom,gcc-ipq4019" },
-	{ }
-};
-
-U_BOOT_DRIVER(clk_msm) = {
-	.name		= "clk_msm",
-	.id		= UCLASS_CLK,
-	.of_match	= msm_clk_ids,
-	.ops		= &msm_clk_ops,
-	.priv_auto	= sizeof(struct msm_clk_priv),
-	.probe		= msm_clk_probe,
-};
diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c
deleted file mode 100644
index 036fec9..0000000
--- a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c
+++ /dev/null
@@ -1,166 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * TLMM driver for Qualcomm IPQ40xx
- *
- * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
- *
- * Copyright (c) 2020 Sartura Ltd.
- *
- * Author: Robert Marko <robert.marko@sartura.hr>
- *
- */
-
-#include <common.h>
-#include <dm.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <dm/device_compat.h>
-#include <dm/lists.h>
-#include <dm/pinctrl.h>
-#include <linux/bitops.h>
-#include "pinctrl-snapdragon.h"
-
-struct msm_pinctrl_priv {
-	phys_addr_t base;
-	struct msm_pinctrl_data *data;
-};
-
-#define GPIO_CONFIG_OFFSET(x)         ((x) * 0x1000)
-#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
-#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
-#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
-#define TLMM_GPIO_DISABLE BIT(9)
-
-static const struct pinconf_param msm_conf_params[] = {
-	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 2 },
-	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
-	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 2 },
-};
-
-static int msm_get_functions_count(struct udevice *dev)
-{
-	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
-
-	return priv->data->functions_count;
-}
-
-static int msm_get_pins_count(struct udevice *dev)
-{
-	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
-
-	return priv->data->pin_count;
-}
-
-static const char *msm_get_function_name(struct udevice *dev,
-					 unsigned int selector)
-{
-	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
-
-	return priv->data->get_function_name(dev, selector);
-}
-
-static int msm_pinctrl_probe(struct udevice *dev)
-{
-	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
-
-	priv->base = devfdt_get_addr(dev);
-	priv->data = (struct msm_pinctrl_data *)dev->driver_data;
-
-	return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
-}
-
-static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector)
-{
-	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
-
-	return priv->data->get_pin_name(dev, selector);
-}
-
-static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
-			  unsigned int func_selector)
-{
-	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
-
-	clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
-			TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
-			priv->data->get_function_mux(func_selector) << 2);
-	return 0;
-}
-
-static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
-			   unsigned int param, unsigned int argument)
-{
-	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
-
-	switch (param) {
-	case PIN_CONFIG_DRIVE_STRENGTH:
-		clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
-				TLMM_DRV_STRENGTH_MASK, argument << 6);
-		break;
-	case PIN_CONFIG_BIAS_DISABLE:
-		clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
-			     TLMM_GPIO_PULL_MASK);
-		break;
-	case PIN_CONFIG_BIAS_PULL_UP:
-		clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
-			     TLMM_GPIO_PULL_MASK, argument);
-		break;
-	default:
-		return 0;
-	}
-
-	return 0;
-}
-
-static int msm_pinctrl_bind(struct udevice *dev)
-{
-	ofnode node = dev_ofnode(dev);
-	const char *name;
-	int ret;
-
-	ofnode_get_property(node, "gpio-controller", &ret);
-	if (ret < 0)
-		return 0;
-
-	/* Get the name of gpio node */
-	name = ofnode_get_name(node);
-	if (!name)
-		return -EINVAL;
-
-	/* Bind gpio node */
-	ret = device_bind_driver_to_node(dev, "gpio_msm",
-					 name, node, NULL);
-	if (ret)
-		return ret;
-
-	dev_dbg(dev, "bind %s\n", name);
-
-	return 0;
-}
-
-static struct pinctrl_ops msm_pinctrl_ops = {
-	.get_pins_count = msm_get_pins_count,
-	.get_pin_name = msm_get_pin_name,
-	.set_state = pinctrl_generic_set_state,
-	.pinmux_set = msm_pinmux_set,
-	.pinconf_num_params = ARRAY_SIZE(msm_conf_params),
-	.pinconf_params = msm_conf_params,
-	.pinconf_set = msm_pinconf_set,
-	.get_functions_count = msm_get_functions_count,
-	.get_function_name = msm_get_function_name,
-};
-
-static const struct udevice_id msm_pinctrl_ids[] = {
-	{ .compatible = "qcom,ipq4019-pinctrl", .data = (ulong)&ipq4019_data },
-	{ }
-};
-
-U_BOOT_DRIVER(pinctrl_snapdraon) = {
-	.name		= "pinctrl_msm",
-	.id		= UCLASS_PINCTRL,
-	.of_match	= msm_pinctrl_ids,
-	.priv_auto	= sizeof(struct msm_pinctrl_priv),
-	.ops		= &msm_pinctrl_ops,
-	.probe		= msm_pinctrl_probe,
-	.bind		= msm_pinctrl_bind,
-};
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index 2fc1521..ad66710 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -15,6 +15,9 @@
 config SDM845
 	bool "Qualcomm Snapdragon 845 SoC"
 	select LINUX_KERNEL_IMAGE_HEADER
+	imply CLK_QCOM_SDM845
+	imply PINCTRL_QCOM_SDM845
+	imply BUTTON_QCOM_PMIC
 
 config LNX_KRNL_IMG_TEXT_OFFSET_BASE
 	default 0x80000000
@@ -26,6 +29,9 @@
 	bool "96Boards Dragonboard 410C"
 	select BOARD_LATE_INIT
 	select ENABLE_ARM_SOC_BOOT0_HOOK
+	imply CLK_QCOM_APQ8016
+	imply PINCTRL_QCOM_APQ8016
+	imply BUTTON_QCOM_PMIC
 	help
 	  Support for 96Boards Dragonboard 410C. This board complies with
 	  96Board Open Platform Specifications. Features:
@@ -39,6 +45,9 @@
 
 config TARGET_DRAGONBOARD820C
 	bool "96Boards Dragonboard 820C"
+	imply CLK_QCOM_APQ8096
+	imply PINCTRL_QCOM_APQ8096
+	imply BUTTON_QCOM_PMIC
 	help
 	  Support for 96Boards Dragonboard 820C. This board complies with
 	  96Board Open Platform Specifications. Features:
@@ -72,6 +81,8 @@
 config TARGET_QCS404EVB
 	bool "Qualcomm Technologies, Inc. QCS404 EVB"
 	select LINUX_KERNEL_IMAGE_HEADER
+	imply CLK_QCOM_QCS404
+	imply PINCTRL_QCOM_QCS404
 	help
 	  Support for Qualcomm Technologies, Inc. QCS404 evaluation board.
 	  Features:
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
index cbaaf23..3a3a297 100644
--- a/arch/arm/mach-snapdragon/Makefile
+++ b/arch/arm/mach-snapdragon/Makefile
@@ -2,20 +2,10 @@
 #
 # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
 
-obj-$(CONFIG_SDM845) += clock-sdm845.o
 obj-$(CONFIG_SDM845) += sysmap-sdm845.o
 obj-$(CONFIG_SDM845) += init_sdm845.o
-obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o
 obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o
-obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o
 obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o
 obj-y += misc.o
-obj-y += clock-snapdragon.o
 obj-y += dram.o
-obj-y += pinctrl-snapdragon.o
-obj-y += pinctrl-apq8016.o
-obj-y += pinctrl-apq8096.o
-obj-y += pinctrl-qcs404.o
-obj-y += pinctrl-sdm845.o
-obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o
 obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o
diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/arch/arm/mach-snapdragon/clock-qcs404.c
deleted file mode 100644
index 3357b54..0000000
--- a/arch/arm/mach-snapdragon/clock-qcs404.c
+++ /dev/null
@@ -1,237 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * Clock drivers for Qualcomm QCS404
- *
- * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org>
- */
-
-#include <common.h>
-#include <clk-uclass.h>
-#include <dm.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <linux/bitops.h>
-#include "clock-snapdragon.h"
-
-#include <dt-bindings/clock/qcom,gcc-qcs404.h>
-
-/* GPLL0 clock control registers */
-#define GPLL0_STATUS_ACTIVE BIT(31)
-
-#define CFG_CLK_SRC_GPLL1	BIT(8)
-#define GPLL1_STATUS_ACTIVE	BIT(31)
-
-static struct vote_clk gcc_blsp1_ahb_clk = {
-	.cbcr_reg = BLSP1_AHB_CBCR,
-	.ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
-	.vote_bit = BIT(10) | BIT(5) | BIT(4),
-};
-
-static const struct bcr_regs uart2_regs = {
-	.cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
-	.cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
-	.M = BLSP1_UART2_APPS_M,
-	.N = BLSP1_UART2_APPS_N,
-	.D = BLSP1_UART2_APPS_D,
-};
-
-static const struct bcr_regs sdc_regs = {
-	.cfg_rcgr = SDCC_CFG_RCGR(1),
-	.cmd_rcgr = SDCC_CMD_RCGR(1),
-	.M = SDCC_M(1),
-	.N = SDCC_N(1),
-	.D = SDCC_D(1),
-};
-
-static struct pll_vote_clk gpll0_vote_clk = {
-	.status = GPLL0_STATUS,
-	.status_bit = GPLL0_STATUS_ACTIVE,
-	.ena_vote = APCS_GPLL_ENA_VOTE,
-	.vote_bit = BIT(0),
-};
-
-static struct pll_vote_clk gpll1_vote_clk = {
-	.status = GPLL1_STATUS,
-	.status_bit = GPLL1_STATUS_ACTIVE,
-	.ena_vote = APCS_GPLL_ENA_VOTE,
-	.vote_bit = BIT(1),
-};
-
-static const struct bcr_regs usb30_master_regs = {
-	.cfg_rcgr = USB30_MASTER_CFG_RCGR,
-	.cmd_rcgr = USB30_MASTER_CMD_RCGR,
-	.M = USB30_MASTER_M,
-	.N = USB30_MASTER_N,
-	.D = USB30_MASTER_D,
-};
-
-static const struct bcr_regs emac_regs = {
-	.cfg_rcgr = EMAC_CFG_RCGR,
-	.cmd_rcgr = EMAC_CMD_RCGR,
-	.M = EMAC_M,
-	.N = EMAC_N,
-	.D = EMAC_D,
-};
-
-static const struct bcr_regs emac_ptp_regs = {
-	.cfg_rcgr = EMAC_PTP_CFG_RCGR,
-	.cmd_rcgr = EMAC_PTP_CMD_RCGR,
-	.M = EMAC_M,
-	.N = EMAC_N,
-	.D = EMAC_D,
-};
-
-static const struct bcr_regs blsp1_qup0_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP0_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP0_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup1_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP1_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup2_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP2_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup3_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP3_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup4_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP4_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-ulong msm_set_rate(struct clk *clk, ulong rate)
-{
-	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
-
-	switch (clk->id) {
-	case GCC_BLSP1_UART2_APPS_CLK:
-		/* UART: 115200 */
-		clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
-				     CFG_CLK_SRC_CXO);
-		clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
-		break;
-	case GCC_BLSP1_AHB_CLK:
-		clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
-		break;
-	case GCC_SDCC1_APPS_CLK:
-		/* SDCC1: 200MHz */
-		clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0,
-				     CFG_CLK_SRC_GPLL0);
-		clk_enable_gpll0(priv->base, &gpll0_vote_clk);
-		clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
-		break;
-	case GCC_SDCC1_AHB_CLK:
-		clk_enable_cbc(priv->base + SDCC_AHB_CBCR(1));
-		break;
-	case GCC_ETH_RGMII_CLK:
-		if (rate == 250000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
-					     CFG_CLK_SRC_GPLL1);
-		else if (rate == 125000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0,
-					     CFG_CLK_SRC_GPLL1);
-		else if (rate == 50000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0,
-					     CFG_CLK_SRC_GPLL1);
-		else if (rate == 5000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50,
-					     CFG_CLK_SRC_GPLL1);
-		break;
-	default:
-		return 0;
-	}
-
-	return 0;
-}
-
-int msm_enable(struct clk *clk)
-{
-	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
-
-	switch (clk->id) {
-	case GCC_USB30_MASTER_CLK:
-		clk_enable_cbc(priv->base + USB30_MASTER_CBCR);
-		clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0,
-				     CFG_CLK_SRC_GPLL0);
-		break;
-	case GCC_SYS_NOC_USB3_CLK:
-		clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
-		break;
-	case GCC_USB30_SLEEP_CLK:
-		clk_enable_cbc(priv->base + USB30_SLEEP_CBCR);
-		break;
-	case GCC_USB30_MOCK_UTMI_CLK:
-		clk_enable_cbc(priv->base + USB30_MOCK_UTMI_CBCR);
-		break;
-	case GCC_USB_HS_PHY_CFG_AHB_CLK:
-		clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR);
-		break;
-	case GCC_USB2A_PHY_SLEEP_CLK:
-		clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR);
-		break;
-	case GCC_ETH_PTP_CLK:
-		/* SPEED_1000: freq -> 250MHz */
-		clk_enable_cbc(priv->base + ETH_PTP_CBCR);
-		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
-		clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0,
-				     CFG_CLK_SRC_GPLL1);
-		break;
-	case GCC_ETH_RGMII_CLK:
-		/* SPEED_1000: freq -> 250MHz */
-		clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
-		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
-		clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
-				     CFG_CLK_SRC_GPLL1);
-		break;
-	case GCC_ETH_SLAVE_AHB_CLK:
-		clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
-		break;
-	case GCC_ETH_AXI_CLK:
-		clk_enable_cbc(priv->base + ETH_AXI_CBCR);
-		break;
-	case GCC_BLSP1_AHB_CLK:
-		clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
-		break;
-	case GCC_BLSP1_QUP0_I2C_APPS_CLK:
-		clk_enable_cbc(priv->base + BLSP1_QUP0_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup0_i2c_apps_regs, 0,
-				 CFG_CLK_SRC_CXO);
-		break;
-	case GCC_BLSP1_QUP1_I2C_APPS_CLK:
-		clk_enable_cbc(priv->base + BLSP1_QUP1_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup1_i2c_apps_regs, 0,
-				 CFG_CLK_SRC_CXO);
-		break;
-	case GCC_BLSP1_QUP2_I2C_APPS_CLK:
-		clk_enable_cbc(priv->base + BLSP1_QUP2_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup2_i2c_apps_regs, 0,
-				 CFG_CLK_SRC_CXO);
-		break;
-	case GCC_BLSP1_QUP3_I2C_APPS_CLK:
-		clk_enable_cbc(priv->base + BLSP1_QUP3_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup3_i2c_apps_regs, 0,
-				 CFG_CLK_SRC_CXO);
-		break;
-	case GCC_BLSP1_QUP4_I2C_APPS_CLK:
-		clk_enable_cbc(priv->base + BLSP1_QUP4_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup4_i2c_apps_regs, 0,
-				 CFG_CLK_SRC_CXO);
-		break;
-	default:
-		return 0;
-	}
-
-	return 0;
-}
diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/arch/arm/mach-snapdragon/clock-sdm845.c
deleted file mode 100644
index d6df036..0000000
--- a/arch/arm/mach-snapdragon/clock-sdm845.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * Clock drivers for Qualcomm SDM845
- *
- * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org>
- * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
- *
- * Based on Little Kernel driver, simplified
- */
-
-#include <common.h>
-#include <clk-uclass.h>
-#include <dm.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <linux/bitops.h>
-#include <dt-bindings/clock/qcom,gcc-sdm845.h>
-#include "clock-snapdragon.h"
-
-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
-struct freq_tbl {
-	uint freq;
-	uint src;
-	u8 pre_div;
-	u16 m;
-	u16 n;
-};
-
-static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
-	F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
-	F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
-	F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
-	F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
-	F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
-	F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
-	F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
-	F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
-	F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
-	F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
-	F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
-	F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
-	F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
-	F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
-	F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
-	{ }
-};
-
-static const struct bcr_regs uart2_regs = {
-	.cfg_rcgr = SE9_UART_APPS_CFG_RCGR,
-	.cmd_rcgr = SE9_UART_APPS_CMD_RCGR,
-	.M = SE9_UART_APPS_M,
-	.N = SE9_UART_APPS_N,
-	.D = SE9_UART_APPS_D,
-};
-
-const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)
-{
-	if (!f)
-		return NULL;
-
-	if (!f->freq)
-		return f;
-
-	for (; f->freq; f++)
-		if (rate <= f->freq)
-			return f;
-
-	/* Default to our fastest rate */
-	return f - 1;
-}
-
-static int clk_init_uart(struct msm_clk_priv *priv, uint rate)
-{
-	const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
-
-	clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
-						freq->pre_div, freq->m, freq->n, freq->src);
-
-	return 0;
-}
-
-ulong msm_set_rate(struct clk *clk, ulong rate)
-{
-	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
-
-	switch (clk->id) {
-	case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/
-		return clk_init_uart(priv, rate);
-	default:
-		return 0;
-	}
-}
-
-int msm_enable(struct clk *clk)
-{
-	return 0;
-}
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c
deleted file mode 100644
index 0ac45dc..0000000
--- a/arch/arm/mach-snapdragon/clock-snapdragon.c
+++ /dev/null
@@ -1,181 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * Clock drivers for Qualcomm APQ8016, APQ8096
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
- *
- * Based on Little Kernel driver, simplified
- */
-
-#include <common.h>
-#include <clk-uclass.h>
-#include <dm.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <linux/bitops.h>
-#include "clock-snapdragon.h"
-
-/* CBCR register fields */
-#define CBCR_BRANCH_ENABLE_BIT  BIT(0)
-#define CBCR_BRANCH_OFF_BIT     BIT(31)
-
-extern ulong msm_set_rate(struct clk *clk, ulong rate);
-extern int msm_enable(struct clk *clk);
-
-/* Enable clock controlled by CBC soft macro */
-void clk_enable_cbc(phys_addr_t cbcr)
-{
-	setbits_le32(cbcr, CBCR_BRANCH_ENABLE_BIT);
-
-	while (readl(cbcr) & CBCR_BRANCH_OFF_BIT)
-		;
-}
-
-void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0)
-{
-	if (readl(base + gpll0->status) & gpll0->status_bit)
-		return; /* clock already enabled */
-
-	setbits_le32(base + gpll0->ena_vote, gpll0->vote_bit);
-
-	while ((readl(base + gpll0->status) & gpll0->status_bit) == 0)
-		;
-}
-
-#define BRANCH_ON_VAL (0)
-#define BRANCH_NOC_FSM_ON_VAL BIT(29)
-#define BRANCH_CHECK_MASK GENMASK(31, 28)
-
-void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk)
-{
-	u32 val;
-
-	setbits_le32(base + vclk->ena_vote, vclk->vote_bit);
-	do {
-		val = readl(base + vclk->cbcr_reg);
-		val &= BRANCH_CHECK_MASK;
-	} while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL));
-}
-
-#define APPS_CMD_RCGR_UPDATE BIT(0)
-
-/* Update clock command via CMD_RCGR */
-void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
-{
-	setbits_le32(apps_cmd_rcgr, APPS_CMD_RCGR_UPDATE);
-
-	/* Wait for frequency to be updated. */
-	while (readl(apps_cmd_rcgr) & APPS_CMD_RCGR_UPDATE)
-		;
-}
-
-#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
-
-#define CFG_MASK 0x3FFF
-
-#define CFG_DIVIDER_MASK 0x1F
-
-/* root set rate for clocks with half integer and MND divider */
-void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
-			  int div, int m, int n, int source)
-{
-	u32 cfg;
-	/* M value for MND divider. */
-	u32 m_val = m;
-	/* NOT(N-M) value for MND divider. */
-	u32 n_val = ~((n) - (m)) * !!(n);
-	/* NOT 2D value for MND divider. */
-	u32 d_val = ~(n);
-
-	/* Program MND values */
-	writel(m_val, base + regs->M);
-	writel(n_val, base + regs->N);
-	writel(d_val, base + regs->D);
-
-	/* setup src select and divider */
-	cfg  = readl(base + regs->cfg_rcgr);
-	cfg &= ~CFG_MASK;
-	cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
-
-	/* Set the divider; HW permits fraction dividers (+0.5), but
-	   for simplicity, we will support integers only */
-	if (div)
-		cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
-
-	if (n_val)
-		cfg |= CFG_MODE_DUAL_EDGE;
-
-	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
-
-	/* Inform h/w to start using the new config. */
-	clk_bcr_update(base + regs->cmd_rcgr);
-}
-
-/* root set rate for clocks with half integer and mnd_width=0 */
-void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
-		      int source)
-{
-	u32 cfg;
-
-	/* setup src select and divider */
-	cfg  = readl(base + regs->cfg_rcgr);
-	cfg &= ~CFG_MASK;
-	cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
-
-	/*
-	 * Set the divider; HW permits fraction dividers (+0.5), but
-	 * for simplicity, we will support integers only
-	 */
-	if (div)
-		cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
-
-	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
-
-	/* Inform h/w to start using the new config. */
-	clk_bcr_update(base + regs->cmd_rcgr);
-}
-
-static int msm_clk_probe(struct udevice *dev)
-{
-	struct msm_clk_priv *priv = dev_get_priv(dev);
-
-	priv->base = dev_read_addr(dev);
-	if (priv->base == FDT_ADDR_T_NONE)
-		return -EINVAL;
-
-	return 0;
-}
-
-static ulong msm_clk_set_rate(struct clk *clk, ulong rate)
-{
-	return msm_set_rate(clk, rate);
-}
-
-static int msm_clk_enable(struct clk *clk)
-{
-	return msm_enable(clk);
-}
-
-static struct clk_ops msm_clk_ops = {
-	.set_rate = msm_clk_set_rate,
-	.enable = msm_clk_enable,
-};
-
-static const struct udevice_id msm_clk_ids[] = {
-	{ .compatible = "qcom,gcc-msm8916" },
-	{ .compatible = "qcom,gcc-apq8016" },
-	{ .compatible = "qcom,gcc-msm8996" },
-	{ .compatible = "qcom,gcc-apq8096" },
-	{ .compatible = "qcom,gcc-sdm845" },
-	{ .compatible = "qcom,gcc-qcs404" },
-	{ }
-};
-
-U_BOOT_DRIVER(clk_msm) = {
-	.name		= "clk_msm",
-	.id		= UCLASS_CLK,
-	.of_match	= msm_clk_ids,
-	.ops		= &msm_clk_ops,
-	.priv_auto	= sizeof(struct msm_clk_priv),
-	.probe		= msm_clk_probe,
-};
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/arch/arm/mach-snapdragon/clock-snapdragon.h
deleted file mode 100644
index c90bbef..0000000
--- a/arch/arm/mach-snapdragon/clock-snapdragon.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Qualcomm APQ8016, APQ8096, SDM845
- *
- * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
- */
-#ifndef _CLOCK_SNAPDRAGON_H
-#define _CLOCK_SNAPDRAGON_H
-
-#define CFG_CLK_SRC_CXO   (0 << 8)
-#define CFG_CLK_SRC_GPLL0 (1 << 8)
-#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
-#define CFG_CLK_SRC_MASK  (7 << 8)
-
-struct pll_vote_clk {
-	uintptr_t status;
-	int status_bit;
-	uintptr_t ena_vote;
-	int vote_bit;
-};
-
-struct vote_clk {
-	uintptr_t cbcr_reg;
-	uintptr_t ena_vote;
-	int vote_bit;
-};
-struct bcr_regs {
-	uintptr_t cfg_rcgr;
-	uintptr_t cmd_rcgr;
-	uintptr_t M;
-	uintptr_t N;
-	uintptr_t D;
-};
-
-struct msm_clk_priv {
-	phys_addr_t base;
-};
-
-void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0);
-void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
-void clk_enable_cbc(phys_addr_t cbcr);
-void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
-void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
-			  int div, int m, int n, int source);
-void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
-		      int source);
-
-#endif
diff --git a/arch/arm/mach-snapdragon/include/mach/gpio.h b/arch/arm/mach-snapdragon/include/mach/gpio.h
index bbc2bc1..8dac62f 100644
--- a/arch/arm/mach-snapdragon/include/mach/gpio.h
+++ b/arch/arm/mach-snapdragon/include/mach/gpio.h
@@ -1,8 +1,28 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
- * Empty gpio.h
+ * Qualcomm common pin control data.
  *
- * This file must stay as arch/arm/include/asm/gpio.h requires it.
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ * Copyright (C) 2023 Linaro Ltd.
  */
+#ifndef _QCOM_GPIO_H_
+#define _QCOM_GPIO_H_
+
+#include <asm/types.h>
+#include <stdbool.h>
+
+struct msm_pin_data {
+	int pin_count;
+	const unsigned int *pin_offsets;
+};
+
+static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selector)
+{
+	u32 out = (selector * 0x1000);
+
+	if (offs)
+		return out + offs[selector];
+
+	return out;
+}
+
+#endif /* _QCOM_GPIO_H_ */
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
deleted file mode 100644
index d9a3b1a..0000000
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Qualcomm APQ8916 sysmap
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
- */
-#ifndef _MACH_SYSMAP_APQ8016_H
-#define _MACH_SYSMAP_APQ8016_H
-
-#define GICD_BASE			(0x0b000000)
-#define GICC_BASE			(0x0b002000)
-
-/* Clocks: (from CLK_CTL_BASE)  */
-#define GPLL0_STATUS			(0x2101C)
-#define APCS_GPLL_ENA_VOTE		(0x45000)
-#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004)
-
-#define SDCC_BCR(n)			((n * 0x1000) + 0x41000)
-#define SDCC_CMD_RCGR(n)		((n * 0x1000) + 0x41004)
-#define SDCC_CFG_RCGR(n)		((n * 0x1000) + 0x41008)
-#define SDCC_M(n)			((n * 0x1000) + 0x4100C)
-#define SDCC_N(n)			((n * 0x1000) + 0x41010)
-#define SDCC_D(n)			((n * 0x1000) + 0x41014)
-#define SDCC_APPS_CBCR(n)		((n * 0x1000) + 0x41018)
-#define SDCC_AHB_CBCR(n)		((n * 0x1000) + 0x4101C)
-
-/* BLSP1 AHB clock (root clock for BLSP) */
-#define BLSP1_AHB_CBCR			0x1008
-
-/* Uart clock control registers */
-#define BLSP1_UART2_BCR			(0x3028)
-#define BLSP1_UART2_APPS_CBCR		(0x302C)
-#define BLSP1_UART2_APPS_CMD_RCGR	(0x3034)
-#define BLSP1_UART2_APPS_CFG_RCGR	(0x3038)
-#define BLSP1_UART2_APPS_M		(0x303C)
-#define BLSP1_UART2_APPS_N		(0x3040)
-#define BLSP1_UART2_APPS_D		(0x3044)
-
-#endif
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h
deleted file mode 100644
index 36a902b..0000000
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Qualcomm APQ8096 sysmap
- *
- * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
- */
-#ifndef _MACH_SYSMAP_APQ8096_H
-#define _MACH_SYSMAP_APQ8096_H
-
-#define TLMM_BASE_ADDR			(0x1010000)
-
-/* Strength (sdc1) */
-#define SDC1_HDRV_PULL_CTL_REG		(TLMM_BASE_ADDR + 0x0012D000)
-
-/* Clocks: (from CLK_CTL_BASE)  */
-#define GPLL0_STATUS			(0x0000)
-#define APCS_GPLL_ENA_VOTE		(0x52000)
-#define APCS_CLOCK_BRANCH_ENA_VOTE	(0x52004)
-
-#define SDCC2_BCR			(0x14000) /* block reset */
-#define SDCC2_APPS_CBCR			(0x14004) /* branch control */
-#define SDCC2_AHB_CBCR			(0x14008)
-#define SDCC2_CMD_RCGR			(0x14010)
-#define SDCC2_CFG_RCGR			(0x14014)
-#define SDCC2_M				(0x14018)
-#define SDCC2_N				(0x1401C)
-#define SDCC2_D				(0x14020)
-
-#define BLSP2_AHB_CBCR			(0x25004)
-#define BLSP2_UART2_APPS_CBCR		(0x29004)
-#define BLSP2_UART2_APPS_CMD_RCGR	(0x2900C)
-#define BLSP2_UART2_APPS_CFG_RCGR	(0x29010)
-#define BLSP2_UART2_APPS_M		(0x29014)
-#define BLSP2_UART2_APPS_N		(0x29018)
-#define BLSP2_UART2_APPS_D		(0x2901C)
-
-#endif
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h
deleted file mode 100644
index 5768fb1..0000000
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Qualcomm QCS404 sysmap
- *
- * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org>
- */
-#ifndef _MACH_SYSMAP_QCS404_H
-#define _MACH_SYSMAP_QCS404_H
-
-#define GICD_BASE			(0x0b000000)
-#define GICC_BASE			(0x0b002000)
-
-/* Clocks: (from CLK_CTL_BASE)  */
-#define GPLL0_STATUS			(0x21000)
-#define GPLL1_STATUS			(0x20000)
-#define APCS_GPLL_ENA_VOTE		(0x45000)
-#define APCS_CLOCK_BRANCH_ENA_VOTE	(0x45004)
-
-/* BLSP1 AHB clock (root clock for BLSP) */
-#define BLSP1_AHB_CBCR			0x1008
-
-/* Uart clock control registers */
-#define BLSP1_UART2_BCR			(0x3028)
-#define BLSP1_UART2_APPS_CBCR		(0x302C)
-#define BLSP1_UART2_APPS_CMD_RCGR	(0x3034)
-#define BLSP1_UART2_APPS_CFG_RCGR	(0x3038)
-#define BLSP1_UART2_APPS_M		(0x303C)
-#define BLSP1_UART2_APPS_N		(0x3040)
-#define BLSP1_UART2_APPS_D		(0x3044)
-
-/* I2C controller clock control registerss */
-#define BLSP1_QUP0_I2C_APPS_CBCR	(0x6028)
-#define BLSP1_QUP0_I2C_APPS_CMD_RCGR	(0x602C)
-#define BLSP1_QUP0_I2C_APPS_CFG_RCGR	(0x6030)
-#define BLSP1_QUP1_I2C_APPS_CBCR	(0x2008)
-#define BLSP1_QUP1_I2C_APPS_CMD_RCGR	(0x200C)
-#define BLSP1_QUP1_I2C_APPS_CFG_RCGR	(0x2010)
-#define BLSP1_QUP2_I2C_APPS_CBCR	(0x3010)
-#define BLSP1_QUP2_I2C_APPS_CMD_RCGR	(0x3000)
-#define BLSP1_QUP2_I2C_APPS_CFG_RCGR	(0x3004)
-#define BLSP1_QUP3_I2C_APPS_CBCR	(0x4020)
-#define BLSP1_QUP3_I2C_APPS_CMD_RCGR	(0x4000)
-#define BLSP1_QUP3_I2C_APPS_CFG_RCGR	(0x4004)
-#define BLSP1_QUP4_I2C_APPS_CBCR	(0x5020)
-#define BLSP1_QUP4_I2C_APPS_CMD_RCGR	(0x5000)
-#define BLSP1_QUP4_I2C_APPS_CFG_RCGR	(0x5004)
-
-/* SD controller clock control registers */
-#define SDCC_BCR(n)			(((n) * 0x1000) + 0x41000)
-#define SDCC_CMD_RCGR(n)		(((n) * 0x1000) + 0x41004)
-#define SDCC_CFG_RCGR(n)		(((n) * 0x1000) + 0x41008)
-#define SDCC_M(n)			(((n) * 0x1000) + 0x4100C)
-#define SDCC_N(n)			(((n) * 0x1000) + 0x41010)
-#define SDCC_D(n)			(((n) * 0x1000) + 0x41014)
-#define SDCC_APPS_CBCR(n)		(((n) * 0x1000) + 0x41018)
-#define SDCC_AHB_CBCR(n)		(((n) * 0x1000) + 0x4101C)
-
-/* USB-3.0 controller clock control registers */
-#define SYS_NOC_USB3_CBCR		(0x26014)
-#define USB30_BCR			(0x39000)
-#define USB3PHY_BCR			(0x39008)
-#define USB30_MASTER_CBCR		(0x3900C)
-#define USB30_SLEEP_CBCR		(0x39010)
-#define USB30_MOCK_UTMI_CBCR		(0x39014)
-#define USB30_MOCK_UTMI_CMD_RCGR	(0x3901C)
-#define USB30_MOCK_UTMI_CFG_RCGR	(0x39020)
-#define USB30_MASTER_CMD_RCGR		(0x39028)
-#define USB30_MASTER_CFG_RCGR		(0x3902C)
-#define USB30_MASTER_M			(0x39030)
-#define USB30_MASTER_N			(0x39034)
-#define USB30_MASTER_D			(0x39038)
-#define USB2A_PHY_SLEEP_CBCR		(0x4102C)
-#define USB_HS_PHY_CFG_AHB_CBCR		(0x41030)
-
-/* ETH controller clock control registers */
-#define ETH_PTP_CBCR			(0x4e004)
-#define ETH_RGMII_CBCR			(0x4e008)
-#define ETH_SLAVE_AHB_CBCR		(0x4e00c)
-#define ETH_AXI_CBCR			(0x4e010)
-#define EMAC_PTP_CMD_RCGR		(0x4e014)
-#define EMAC_PTP_CFG_RCGR		(0x4e018)
-#define EMAC_CMD_RCGR			(0x4e01c)
-#define EMAC_CFG_RCGR			(0x4e020)
-#define EMAC_M				(0x4e024)
-#define EMAC_N				(0x4e028)
-#define EMAC_D				(0x4e02c)
-
-#endif
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h
deleted file mode 100644
index 7165985..0000000
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Qualcomm SDM845 sysmap
- *
- * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
- */
-#ifndef _MACH_SYSMAP_SDM845_H
-#define _MACH_SYSMAP_SDM845_H
-
-#define TLMM_BASE_ADDR			(0x1010000)
-
-/* Strength (sdc1) */
-#define SDC1_HDRV_PULL_CTL_REG		(TLMM_BASE_ADDR + 0x0012D000)
-
-/* Clocks: (from CLK_CTL_BASE)  */
-#define GPLL0_STATUS			(0x0000)
-#define APCS_GPLL_ENA_VOTE		(0x52000)
-#define APCS_CLOCK_BRANCH_ENA_VOTE	(0x52004)
-
-#define SDCC2_BCR			(0x14000) /* block reset */
-#define SDCC2_APPS_CBCR			(0x14004) /* branch control */
-#define SDCC2_AHB_CBCR			(0x14008)
-#define SDCC2_CMD_RCGR			(0x1400c)
-#define SDCC2_CFG_RCGR			(0x14010)
-#define SDCC2_M				(0x14014)
-#define SDCC2_N				(0x14018)
-#define SDCC2_D				(0x1401C)
-
-#define RCG2_CFG_REG			0x4
-#define M_REG			0x8
-#define N_REG			0xc
-#define D_REG			0x10
-
-#define SE9_AHB_CBCR			(0x25004)
-#define SE9_UART_APPS_CBCR		(0x29004)
-#define SE9_UART_APPS_CMD_RCGR	(0x18148)
-#define SE9_UART_APPS_CFG_RCGR	(0x1814C)
-#define SE9_UART_APPS_M		(0x18150)
-#define SE9_UART_APPS_N		(0x18154)
-#define SE9_UART_APPS_D		(0x18158)
-
-#endif
diff --git a/arch/arm/mach-snapdragon/init_sdm845.c b/arch/arm/mach-snapdragon/init_sdm845.c
index 1f88502..067acc9 100644
--- a/arch/arm/mach-snapdragon/init_sdm845.c
+++ b/arch/arm/mach-snapdragon/init_sdm845.c
@@ -5,6 +5,7 @@
  * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
  */
 
+#include <button.h>
 #include <init.h>
 #include <env.h>
 #include <common.h>
@@ -32,46 +33,18 @@
 /* Check for vol- and power buttons */
 __weak int misc_init_r(void)
 {
-	struct udevice *pon;
-	struct gpio_desc resin;
-	int node, ret;
+	struct udevice *btn;
+	int ret;
+	enum button_state_t state;
 
-	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8998_pon@800", &pon);
+	ret = button_get_by_label("pwrkey", &btn);
 	if (ret < 0) {
-		printf("Failed to find PMIC pon node. Check device tree\n");
-		return 0;
+		printf("Couldn't find power button!\n");
+		return ret;
 	}
 
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_vol_down");
-	if (node < 0) {
-		printf("Failed to find key_vol_down node. Check device tree\n");
-		return 0;
-	}
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_vol_down button.\n");
-		return 0;
-	}
-	if (dm_gpio_get_value(&resin)) {
-		env_set("key_vol_down", "1");
-		printf("Volume down button pressed\n");
-	} else {
-		env_set("key_vol_down", "0");
-	}
-
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_power");
-	if (node < 0) {
-		printf("Failed to find key_power node. Check device tree\n");
-		return 0;
-	}
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_power button.\n");
-		return 0;
-	}
-	if (dm_gpio_get_value(&resin)) {
+	state = button_get_state(btn);
+	if (state == BUTTON_ON) {
 		env_set("key_power", "1");
 		printf("Power button pressed\n");
 	} else {
diff --git a/arch/arm/mach-snapdragon/pinctrl-sdm845.c b/arch/arm/mach-snapdragon/pinctrl-sdm845.c
deleted file mode 100644
index 40f2f01..0000000
--- a/arch/arm/mach-snapdragon/pinctrl-sdm845.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Qualcomm SDM845 pinctrl
- *
- * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
- *
- */
-
-#include "pinctrl-snapdragon.h"
-#include <common.h>
-
-#define MAX_PIN_NAME_LEN 32
-static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
-
-static const struct pinctrl_function msm_pinctrl_functions[] = {
-	{"qup9", 1},
-	{"gpio", 0},
-};
-
-static const char *sdm845_get_function_name(struct udevice *dev,
-					     unsigned int selector)
-{
-	return msm_pinctrl_functions[selector].name;
-}
-
-static const char *sdm845_get_pin_name(struct udevice *dev,
-					unsigned int selector)
-{
-	snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector);
-	return pin_name;
-}
-
-static unsigned int sdm845_get_function_mux(unsigned int selector)
-{
-	return msm_pinctrl_functions[selector].val;
-}
-
-struct msm_pinctrl_data sdm845_data = {
-	.pin_count = 150,
-	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
-	.get_function_name = sdm845_get_function_name,
-	.get_function_mux = sdm845_get_function_mux,
-	.get_pin_name = sdm845_get_pin_name,
-};
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
deleted file mode 100644
index 178ee01..0000000
--- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Qualcomm Pin control
- *
- * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
- *
- */
-#ifndef _PINCTRL_SNAPDRAGON_H
-#define _PINCTRL_SNAPDRAGON_H
-
-struct udevice;
-
-struct msm_pinctrl_data {
-	int pin_count;
-	int functions_count;
-	const char *(*get_function_name)(struct udevice *dev,
-					 unsigned int selector);
-	unsigned int (*get_function_mux)(unsigned int selector);
-	const char *(*get_pin_name)(struct udevice *dev,
-				    unsigned int selector);
-};
-
-struct pinctrl_function {
-	const char *name;
-	int val;
-};
-
-extern struct msm_pinctrl_data apq8016_data;
-extern struct msm_pinctrl_data apq8096_data;
-extern struct msm_pinctrl_data sdm845_data;
-extern struct msm_pinctrl_data qcs404_data;
-
-#endif
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 4fe7266..e264b29 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1544,10 +1544,10 @@
 			spmi_gpios: gpios@c000 {
 				compatible = "qcom,pm8916-gpio";
 				reg = <0xc000 0x400>;
+				gpio-ranges = <&spmi_gpios 0 0 4>;
 				gpio-controller;
 				gpio-count = <4>;
 				#gpio-cells = <2>;
-				gpio-bank-name="spmi";
 			};
 		};
 	};
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
index 371b326..350e0e9 100644
--- a/board/qualcomm/dragonboard410c/dragonboard410c.c
+++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
@@ -5,6 +5,7 @@
  * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
  */
 
+#include <button.h>
 #include <common.h>
 #include <cpu_func.h>
 #include <dm.h>
@@ -108,32 +109,20 @@
 /* Check for vol- button - if pressed - stop autoboot */
 int misc_init_r(void)
 {
-	struct udevice *pon;
-	struct gpio_desc resin;
-	int node, ret;
+	struct udevice *btn;
+	int ret;
+	enum button_state_t state;
 
-	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8916_pon@800", &pon);
+	ret = button_get_by_label("vol_down", &btn);
 	if (ret < 0) {
-		printf("Failed to find PMIC pon node. Check device tree\n");
-		return 0;
+		printf("Couldn't find power button!\n");
+		return ret;
 	}
 
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_vol_down");
-	if (node < 0) {
-		printf("Failed to find key_vol_down node. Check device tree\n");
-		return 0;
-	}
-
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_vol_down button.\n");
-		return 0;
-	}
-
-	if (dm_gpio_get_value(&resin)) {
+	state = button_get_state(btn);
+	if (state == BUTTON_ON) {
 		env_set("preboot", "setenv preboot; fastboot 0");
-		printf("key_vol_down pressed - Starting fastboot.\n");
+		printf("vol_down pressed - Starting fastboot.\n");
 	}
 
 	return 0;
diff --git a/board/qualcomm/dragonboard820c/dragonboard820c.c b/board/qualcomm/dragonboard820c/dragonboard820c.c
index f9cc762..2f0db62 100644
--- a/board/qualcomm/dragonboard820c/dragonboard820c.c
+++ b/board/qualcomm/dragonboard820c/dragonboard820c.c
@@ -5,9 +5,9 @@
  * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
  */
 
+#include <button.h>
 #include <cpu_func.h>
 #include <init.h>
-#include <asm/arch/sysmap-apq8096.h>
 #include <env.h>
 #include <asm/cache.h>
 #include <asm/global_data.h>
@@ -20,6 +20,11 @@
 #include <asm/psci.h>
 #include <asm/gpio.h>
 
+#define TLMM_BASE_ADDR                  (0x1010000)
+
+/* Strength (sdc1) */
+#define SDC1_HDRV_PULL_CTL_REG          (TLMM_BASE_ADDR + 0x0012D000)
+
 DECLARE_GLOBAL_DATA_PTR;
 
 int dram_init(void)
@@ -135,30 +140,18 @@
 /* Check for vol- button - if pressed - stop autoboot */
 int misc_init_r(void)
 {
-	struct udevice *pon;
-	struct gpio_desc resin;
-	int node, ret;
+	struct udevice *btn;
+	int ret;
+	enum button_state_t state;
 
-	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8994_pon@800", &pon);
+	ret = button_get_by_label("pwrkey", &btn);
 	if (ret < 0) {
-		printf("Failed to find PMIC pon node. Check device tree\n");
-		return 0;
-	}
-
-	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
-				  "key_vol_down");
-	if (node < 0) {
-		printf("Failed to find key_vol_down node. Check device tree\n");
-		return 0;
-	}
-
-	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
-				       &resin, 0)) {
-		printf("Failed to request key_vol_down button.\n");
-		return 0;
+		printf("Couldn't find power button!\n");
+		return ret;
 	}
 
-	if (dm_gpio_get_value(&resin)) {
+	state = button_get_state(btn);
+	if (state == BUTTON_ON) {
 		env_set("bootdelay", "-1");
 		printf("Power button pressed - dropping to console.\n");
 	}
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 1bd9109..36f384b 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -101,6 +101,9 @@
 CONFIG_SYS_ATA_REG_OFFSET=1
 CONFIG_SYS_ATA_ALT_OFFSET=2
 CONFIG_SYS_ATA_IDE0_OFFSET=0
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_CLK_K210=y
diff --git a/doc/device-tree-bindings/gpio/pm8916_gpio.txt b/doc/device-tree-bindings/gpio/pm8916_gpio.txt
deleted file mode 100644
index 58185b8..0000000
--- a/doc/device-tree-bindings/gpio/pm8916_gpio.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Driver for part of pm8916 PMIC - gpio and power/reset keys
-
-This device should be child of SPMI pmic.
-
-1) GPIO driver
-
-Required properties:
-- compatible: "qcom,pm8916-gpio"
-- reg: peripheral ID, size of register block
-- gpio-controller
-- gpio-count: number of GPIOs
-- #gpio-cells: 2
-
-Optional properties:
-- gpio-bank-name: name of bank (as default "pm8916" is used)
-
-Example:
-
-pmic_gpios: gpios@c000 {
-	compatible = "qcom,pm8916-gpio";
-	reg = <0xc000 0x400>;
-	gpio-controller;
-	gpio-count = <4>;
-	#gpio-cells = <2>;
-	gpio-bank-name="pmic";
-};
-
-
-2) Power/Reset key driver
-
-Required properties:
-- compatible: "qcom,pm8916-pwrkey"
-- reg: peripheral ID, size of register block
-- gpio-controller
-- #gpio-cells: 2
-
-Optional properties:
-- gpio-bank-name: name of bank (as default "pm8916_key" is used)
-
-
-Example:
-
-pmic_pon: pon@800 {
-	compatible = "qcom,pm8916-pwrkey";
-	reg = <0x800 0x96>;
-	#gpio-cells = <2>;
-	gpio-controller;
-};
diff --git a/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt b/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt
deleted file mode 100644
index eb78e3a..0000000
--- a/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-          Qualcomm SPMI PMICs multi-function device bindings
-
-The Qualcomm SPMI series presently includes PM8941, PM8841 and PMA8084
-PMICs.  These PMICs use a QPNP scheme through SPMI interface.
-QPNP is effectively a partitioning scheme for dividing the SPMI extended
-register space up into logical pieces, and set of fixed register
-locations/definitions within these regions, with some of these regions
-specifically used for interrupt handling.
-
-The QPNP PMICs are used with the Qualcomm Snapdragon series SoCs, and are
-interfaced to the chip via the SPMI (System Power Management Interface) bus.
-Support for multiple independent functions are implemented by splitting the
-16-bit SPMI slave address space into 256 smaller fixed-size regions, 256 bytes
-each. A function can consume one or more of these fixed-size register regions.
-
-Required properties:
-- compatible:      Should contain one of:
-                   "qcom,pm660",
-                   "qcom,pm660l",
-                   "qcom,pm7325",
-                   "qcom,pm8004",
-                   "qcom,pm8005",
-                   "qcom,pm8019",
-                   "qcom,pm8028",
-                   "qcom,pm8110",
-                   "qcom,pm8150",
-                   "qcom,pm8150b",
-                   "qcom,pm8150c",
-                   "qcom,pm8150l",
-                   "qcom,pm8226",
-                   "qcom,pm8350c",
-                   "qcom,pm8841",
-                   "qcom,pm8901",
-                   "qcom,pm8909",
-                   "qcom,pm8916",
-                   "qcom,pm8941",
-                   "qcom,pm8950",
-                   "qcom,pm8953",
-                   "qcom,pm8994",
-                   "qcom,pm8998",
-                   "qcom,pma8084",
-                   "qcom,pmd9635",
-                   "qcom,pmi8950",
-                   "qcom,pmi8962",
-                   "qcom,pmi8994",
-                   "qcom,pmi8998",
-                   "qcom,pmk8002",
-                   "qcom,pmk8350",
-                   "qcom,pmr735a",
-                   "qcom,smb2351",
-                   or generalized "qcom,spmi-pmic".
-- reg:             Specifies the SPMI USID slave address for this device.
-                   For more information see:
-                   Documentation/devicetree/bindings/spmi/spmi.yaml
-
-Required properties for peripheral child nodes:
-- compatible:      Should contain "qcom,xxx", where "xxx" is a peripheral name.
-
-Optional properties for peripheral child nodes:
-- interrupts:      Interrupts are specified as a 4-tuple. For more information
-                   see:
-                   Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
-- interrupt-names: Corresponding interrupt name to the interrupts property
-
-Each child node of SPMI slave id represents a function of the PMIC. In the
-example below the rtc device node represents a peripheral of pm8941
-SID = 0. The regulator device node represents a peripheral of pm8941 SID = 1.
-
-Example:
-
-	spmi {
-		compatible = "qcom,spmi-pmic-arb";
-
-		pm8941@0 {
-			compatible = "qcom,pm8941", "qcom,spmi-pmic";
-			reg = <0x0 SPMI_USID>;
-
-			rtc {
-				compatible = "qcom,rtc";
-				interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
-				interrupt-names = "alarm";
-			};
-		};
-
-		pm8941@1 {
-			compatible = "qcom,pm8941", "qcom,spmi-pmic";
-			reg = <0x1 SPMI_USID>;
-
-			regulator {
-				compatible = "qcom,regulator";
-				regulator-name = "8941_boost";
-			};
-		};
-	};
diff --git a/doc/device-tree-bindings/spmi/spmi-msm.txt b/doc/device-tree-bindings/spmi/spmi-msm.txt
deleted file mode 100644
index ae47673..0000000
--- a/doc/device-tree-bindings/spmi/spmi-msm.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Qualcomm SPMI arbiter/bus driver
-
-This is bus driver for Qualcomm chips that use SPMI to communicate with PMICs.
-
-Required properties:
-- compatible: "qcom,spmi-pmic-arb"
-- reg: Register block adresses and sizes for various parts of device:
-   1) PMIC arbiter channel mapping base (PMIC_ARB_REG_CHNLn)
-   2) SPMI write command (master) registers (PMIC_ARB_CORE_SW_DEC_CHANNELS)
-   3) SPMI read command (observer) registers (PMIC_ARB_CORE_REGISTERS_OBS)
-
-Optional properties (if not set by parent):
-- #address-cells: 0x1 - childs slave ID address
-- #size-cells: 0x1
-
-All PMICs should be placed as a child nodes of bus arbiter.
-Automatic detection of childs is currently not supported.
-
-Example:
-
-spmi@200f000 {
-	compatible = "qcom,spmi-pmic-arb";
-	reg = <0x200f800 0x200 0x2400000 0x400000 0x2c00000 0x400000>;
-	#address-cells = <0x1>;
-	#size-cells = <0x1>;
-};
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 8ce2de3..097b05f 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -27,4 +27,13 @@
 	  The GPIO driver must used driver model. Buttons are configured using
 	  the device tree.
 
+config BUTTON_QCOM_PMIC
+	bool "Qualcomm power button"
+	depends on BUTTON
+	depends on PMIC_QCOM
+	help
+	  Enable support for the power and "resin" (usually volume down) buttons
+	  on Qualcomm SoCs. These will be configured as the Enter and Down keys
+	  respectively, allowing navigation of bootmenu with buttons on device.
+
 endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index bbd18af..6855508 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_BUTTON) += button-uclass.o
 obj-$(CONFIG_BUTTON_ADC) += button-adc.o
 obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
+obj-$(CONFIG_BUTTON_QCOM_PMIC) += button-qcom-pmic.o
\ No newline at end of file
diff --git a/drivers/button/button-qcom-pmic.c b/drivers/button/button-qcom-pmic.c
new file mode 100644
index 0000000..34a976d
--- /dev/null
+++ b/drivers/button/button-qcom-pmic.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm generic pmic gpio driver
+ *
+ * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ * (C) Copyright 2023 Linaro Ltd.
+ */
+
+#include <button.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <log.h>
+#include <power/pmic.h>
+#include <spmi/spmi.h>
+#include <linux/bitops.h>
+
+#define REG_TYPE		0x4
+#define REG_SUBTYPE		0x5
+
+struct qcom_pmic_btn_priv {
+	u32 base;
+	u32 status_bit;
+	int code;
+	struct udevice *pmic;
+};
+
+#define PON_INT_RT_STS                        0x10
+#define KPDPWR_ON_INT_BIT                     0
+#define RESIN_ON_INT_BIT                      1
+
+#define NODE_IS_PWRKEY(node) (!strncmp(ofnode_get_name(node), "pwrkey", strlen("pwrkey")))
+#define NODE_IS_RESIN(node) (!strncmp(ofnode_get_name(node), "resin", strlen("resin")))
+
+static enum button_state_t qcom_pwrkey_get_state(struct udevice *dev)
+{
+	struct qcom_pmic_btn_priv *priv = dev_get_priv(dev);
+
+	int reg = pmic_reg_read(priv->pmic, priv->base + PON_INT_RT_STS);
+
+	if (reg < 0)
+		return 0;
+
+	return (reg & BIT(priv->status_bit)) != 0;
+}
+
+static int qcom_pwrkey_get_code(struct udevice *dev)
+{
+	struct qcom_pmic_btn_priv *priv = dev_get_priv(dev);
+
+	return priv->code;
+}
+
+static int qcom_pwrkey_probe(struct udevice *dev)
+{
+	struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+	struct qcom_pmic_btn_priv *priv = dev_get_priv(dev);
+	ofnode node = dev_ofnode(dev);
+	int ret;
+	u64 base;
+
+	/* Ignore the top-level pon node */
+	if (!uc_plat->label)
+		return 0;
+
+	/* the pwrkey and resin nodes are children of the "pon" node, get the
+	 * PMIC device to use in pmic_reg_* calls.
+	 */
+	priv->pmic = dev->parent->parent;
+
+	/* Get the address of the parent pon node */
+	base = dev_read_addr(dev->parent);
+	if (base == FDT_ADDR_T_NONE) {
+		printf("%s: Can't find address\n", dev->name);
+		return -EINVAL;
+	}
+
+	priv->base = base;
+
+	/* Do a sanity check */
+	ret = pmic_reg_read(priv->pmic, priv->base + REG_TYPE);
+	if (ret != 0x1 && ret != 0xb) {
+		printf("%s: unexpected PMIC function type %d\n", dev->name, ret);
+		return -ENXIO;
+	}
+
+	ret = pmic_reg_read(priv->pmic, priv->base + REG_SUBTYPE);
+	if ((ret & 0x7) == 0) {
+		printf("%s: unexpected PMCI function subtype %d\n", dev->name, ret);
+		return -ENXIO;
+	}
+
+	if (NODE_IS_PWRKEY(node)) {
+		priv->status_bit = 0;
+		priv->code = KEY_ENTER;
+	} else if (NODE_IS_RESIN(node)) {
+		priv->status_bit = 1;
+		priv->code = KEY_DOWN;
+	} else {
+		/* Should not get here! */
+		printf("Invalid pon node '%s' should be 'pwrkey' or 'resin'\n",
+		       ofnode_get_name(node));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int button_qcom_pmic_bind(struct udevice *parent)
+{
+	struct udevice *dev;
+	ofnode node;
+	int ret;
+
+	dev_for_each_subnode(node, parent) {
+		struct button_uc_plat *uc_plat;
+		const char *label;
+
+		if (!ofnode_is_enabled(node))
+			continue;
+
+		ret = device_bind_driver_to_node(parent, "qcom_pwrkey",
+						 ofnode_get_name(node),
+						 node, &dev);
+		if (ret) {
+			printf("Failed to bind %s! %d\n", label, ret);
+			return ret;
+		}
+		uc_plat = dev_get_uclass_plat(dev);
+		if (NODE_IS_PWRKEY(node)) {
+			uc_plat->label = "pwrkey";
+		} else if (NODE_IS_RESIN(node)) {
+			uc_plat->label = "vol_down";
+		} else {
+			printf("Unknown button node '%s' should be 'pwrkey' or 'resin'\n",
+			       ofnode_get_name(node));
+			device_unbind(dev);
+		}
+	}
+
+	return 0;
+}
+
+static const struct button_ops button_qcom_pmic_ops = {
+	.get_state	= qcom_pwrkey_get_state,
+	.get_code	= qcom_pwrkey_get_code,
+};
+
+static const struct udevice_id qcom_pwrkey_ids[] = {
+	{ .compatible = "qcom,pm8916-pon" },
+	{ .compatible = "qcom,pm8941-pon" },
+	{ .compatible = "qcom,pm8998-pon" },
+	{ }
+};
+
+U_BOOT_DRIVER(qcom_pwrkey) = {
+	.name = "qcom_pwrkey",
+	.id = UCLASS_BUTTON,
+	.of_match = qcom_pwrkey_ids,
+	.bind = button_qcom_pmic_bind,
+	.probe = qcom_pwrkey_probe,
+	.ops = &button_qcom_pmic_ops,
+	.priv_auto = sizeof(struct qcom_pmic_btn_priv),
+};
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index bfd23a9..017dd26 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -254,6 +254,7 @@
 source "drivers/clk/microchip/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/owl/Kconfig"
+source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/sunxi/Kconfig"
 source "drivers/clk/sifive/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index af27ceb..638ad04 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -39,6 +39,7 @@
 obj-$(CONFIG_CLK_MVEBU) += mvebu/
 obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
 obj-$(CONFIG_CLK_OWL) += owl/
+obj-$(CONFIG_CLK_QCOM) += qcom/
 obj-$(CONFIG_CLK_RENESAS) += renesas/
 obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o
 obj-$(CONFIG_CLK_SIFIVE) += sifive/
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
new file mode 100644
index 0000000..0df0d18
--- /dev/null
+++ b/drivers/clk/qcom/Kconfig
@@ -0,0 +1,52 @@
+if ARCH_SNAPDRAGON || ARCH_IPQ40XX
+
+config CLK_QCOM
+	bool
+	depends on CLK && DM_RESET
+	def_bool n
+
+menu "Qualcomm clock drivers"
+
+config CLK_QCOM_APQ8016
+	bool "Qualcomm APQ8016 GCC"
+	select CLK_QCOM
+	help
+	  Say Y here to enable support for the Global Clock Controller
+	  on the Snapdragon APQ8016 SoC. This driver supports the clocks
+	  and resets exposed by the GCC hardware block.
+
+config CLK_QCOM_APQ8096
+	bool "Qualcomm APQ8096 GCC"
+	select CLK_QCOM
+	help
+	  Say Y here to enable support for the Global Clock Controller
+	  on the Snapdragon APQ8096 SoC. This driver supports the clocks
+	  and resets exposed by the GCC hardware block.
+
+config CLK_QCOM_IPQ4019
+	bool "Qualcomm IPQ4019 GCC"
+	select CLK_QCOM
+	help
+	  Say Y here to enable support for the Global Clock Controller
+	  on the Snapdragon IPQ4019 SoC. This driver supports the clocks
+	  and resets exposed by the GCC hardware block.
+
+config CLK_QCOM_QCS404
+	bool "Qualcomm QCS404 GCC"
+	select CLK_QCOM
+	help
+	  Say Y here to enable support for the Global Clock Controller
+	  on the Snapdragon QCS404 SoC. This driver supports the clocks
+	  and resets exposed by the GCC hardware block.
+
+config CLK_QCOM_SDM845
+	bool "Qualcomm SDM845 GCC"
+	select CLK_QCOM
+	help
+	  Say Y here to enable support for the Global Clock Controller
+	  on the Snapdragon 845 SoC. This driver supports the clocks
+	  and resets exposed by the GCC hardware block.
+
+endmenu
+
+endif
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
new file mode 100644
index 0000000..cb179fd
--- /dev/null
+++ b/drivers/clk/qcom/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2023 Linaro
+
+obj-y += clock-qcom.o
+obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o
+obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
+obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
+obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
+obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c
similarity index 60%
rename from arch/arm/mach-snapdragon/clock-apq8016.c
rename to drivers/clk/qcom/clock-apq8016.c
index 23a37a1..c0ce570 100644
--- a/arch/arm/mach-snapdragon/clock-apq8016.c
+++ b/drivers/clk/qcom/clock-apq8016.c
@@ -13,7 +13,34 @@
 #include <errno.h>
 #include <asm/io.h>
 #include <linux/bitops.h>
-#include "clock-snapdragon.h"
+
+#include "clock-qcom.h"
+
+/* Clocks: (from CLK_CTL_BASE)  */
+#define GPLL0_STATUS			(0x2101C)
+#define APCS_GPLL_ENA_VOTE		(0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004)
+
+#define SDCC_BCR(n)			((n * 0x1000) + 0x41000)
+#define SDCC_CMD_RCGR(n)		((n * 0x1000) + 0x41004)
+#define SDCC_CFG_RCGR(n)		((n * 0x1000) + 0x41008)
+#define SDCC_M(n)			((n * 0x1000) + 0x4100C)
+#define SDCC_N(n)			((n * 0x1000) + 0x41010)
+#define SDCC_D(n)			((n * 0x1000) + 0x41014)
+#define SDCC_APPS_CBCR(n)		((n * 0x1000) + 0x41018)
+#define SDCC_AHB_CBCR(n)		((n * 0x1000) + 0x4101C)
+
+/* BLSP1 AHB clock (root clock for BLSP) */
+#define BLSP1_AHB_CBCR			0x1008
+
+/* Uart clock control registers */
+#define BLSP1_UART2_BCR			(0x3028)
+#define BLSP1_UART2_APPS_CBCR		(0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR	(0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR	(0x3038)
+#define BLSP1_UART2_APPS_M		(0x303C)
+#define BLSP1_UART2_APPS_N		(0x3040)
+#define BLSP1_UART2_APPS_D		(0x3044)
 
 /* GPLL0 clock control registers */
 #define GPLL0_STATUS_ACTIVE BIT(17)
@@ -51,7 +78,7 @@
 /* SDHCI */
 static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
 {
-	int div = 8; /* 100MHz default */
+	int div = 15; /* 100MHz default */
 
 	if (rate == 200000000)
 		div = 4;
@@ -59,7 +86,7 @@
 	clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
 	/* 800Mhz/div, gpll0 */
 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 8);
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
 
@@ -82,7 +109,7 @@
 
 	/* 7372800 uart block clock @ GPLL0 */
 	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 16);
 
 	/* Vote for gpll0 clock */
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
@@ -93,7 +120,7 @@
 	return 0;
 }
 
-ulong msm_set_rate(struct clk *clk, ulong rate)
+static ulong apq8016_clk_set_rate(struct clk *clk, ulong rate)
 {
 	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
 
@@ -112,7 +139,22 @@
 	}
 }
 
-int msm_enable(struct clk *clk)
-{
-	return 0;
-}
+static struct msm_clk_data apq8016_clk_data = {
+	.set_rate = apq8016_clk_set_rate,
+};
+
+static const struct udevice_id gcc_apq8016_of_match[] = {
+	{
+		.compatible = "qcom,gcc-apq8016",
+		.data = (ulong)&apq8016_clk_data,
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(gcc_apq8016) = {
+	.name		= "gcc_apq8016",
+	.id		= UCLASS_NOP,
+	.of_match	= gcc_apq8016_of_match,
+	.bind		= qcom_cc_bind,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c
similarity index 61%
rename from arch/arm/mach-snapdragon/clock-apq8096.c
rename to drivers/clk/qcom/clock-apq8096.c
index 6618459..cf1a347 100644
--- a/arch/arm/mach-snapdragon/clock-apq8096.c
+++ b/drivers/clk/qcom/clock-apq8096.c
@@ -13,7 +13,30 @@
 #include <errno.h>
 #include <asm/io.h>
 #include <linux/bitops.h>
-#include "clock-snapdragon.h"
+
+#include "clock-qcom.h"
+
+/* Clocks: (from CLK_CTL_BASE)  */
+#define GPLL0_STATUS			(0x0000)
+#define APCS_GPLL_ENA_VOTE		(0x52000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE	(0x52004)
+
+#define SDCC2_BCR			(0x14000) /* block reset */
+#define SDCC2_APPS_CBCR			(0x14004) /* branch control */
+#define SDCC2_AHB_CBCR			(0x14008)
+#define SDCC2_CMD_RCGR			(0x14010)
+#define SDCC2_CFG_RCGR			(0x14014)
+#define SDCC2_M				(0x14018)
+#define SDCC2_N				(0x1401C)
+#define SDCC2_D				(0x14020)
+
+#define BLSP2_AHB_CBCR			(0x25004)
+#define BLSP2_UART2_APPS_CBCR		(0x29004)
+#define BLSP2_UART2_APPS_CMD_RCGR	(0x2900C)
+#define BLSP2_UART2_APPS_CFG_RCGR	(0x29010)
+#define BLSP2_UART2_APPS_M		(0x29014)
+#define BLSP2_UART2_APPS_N		(0x29018)
+#define BLSP2_UART2_APPS_D		(0x2901C)
 
 /* GPLL0 clock control registers */
 #define GPLL0_STATUS_ACTIVE		BIT(30)
@@ -42,11 +65,11 @@
 
 static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
 {
-	int div = 3;
+	int div = 5;
 
 	clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 8);
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
 
@@ -68,7 +91,7 @@
 
 	/* 7372800 uart block clock @ GPLL0 */
 	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 16);
 
 	/* Vote for gpll0 clock */
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
@@ -79,7 +102,7 @@
 	return 0;
 }
 
-ulong msm_set_rate(struct clk *clk, ulong rate)
+static ulong apq8096_clk_set_rate(struct clk *clk, ulong rate)
 {
 	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
 
@@ -94,7 +117,22 @@
 	}
 }
 
-int msm_enable(struct clk *clk)
-{
-	return 0;
-}
+static struct msm_clk_data apq8096_clk_data = {
+	.set_rate = apq8096_clk_set_rate,
+};
+
+static const struct udevice_id gcc_apq8096_of_match[] = {
+	{
+		.compatible = "qcom,gcc-apq8096",
+		.data = (ulong)&apq8096_clk_data,
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(gcc_apq8096) = {
+	.name		= "gcc_apq8096",
+	.id		= UCLASS_NOP,
+	.of_match	= gcc_apq8096_of_match,
+	.bind		= qcom_cc_bind,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/qcom/clock-ipq4019.c b/drivers/clk/qcom/clock-ipq4019.c
new file mode 100644
index 0000000..d693776
--- /dev/null
+++ b/drivers/clk/qcom/clock-ipq4019.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Clock drivers for Qualcomm IPQ40xx
+ *
+ * Copyright (c) 2020 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko@sartura.hr>
+ *
+ */
+
+#include <clk-uclass.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
+
+#include "clock-qcom.h"
+
+static ulong ipq4019_clk_set_rate(struct clk *clk, ulong rate)
+{
+	switch (clk->id) {
+	case GCC_BLSP1_UART1_APPS_CLK: /*UART1*/
+		/* This clock is already initialized by SBL1 */
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ipq4019_clk_enable(struct clk *clk)
+{
+	switch (clk->id) {
+	case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/
+		/* This clock is already initialized by SBL1 */
+		return 0;
+	case GCC_PRNG_AHB_CLK: /*PRNG*/
+		/* This clock is already initialized by SBL1 */
+		return 0;
+	case GCC_USB3_MASTER_CLK:
+	case GCC_USB3_SLEEP_CLK:
+	case GCC_USB3_MOCK_UTMI_CLK:
+	case GCC_USB2_MASTER_CLK:
+	case GCC_USB2_SLEEP_CLK:
+	case GCC_USB2_MOCK_UTMI_CLK:
+		/* These clocks is already initialized by SBL1 */
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct qcom_reset_map gcc_ipq4019_resets[] = {
+	[WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
+	[WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
+	[WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
+	[WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
+	[WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
+	[WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
+	[WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
+	[WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
+	[WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
+	[WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
+	[WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
+	[WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
+	[USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
+	[USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
+	[USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
+	[USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
+	[USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
+	[PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
+	[PCIE_AHB_ARES] = { 0x1d010, 10 },
+	[PCIE_PWR_ARES] = { 0x1d010, 9 },
+	[PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
+	[PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
+	[PCIE_PHY_ARES] = { 0x1d010, 6 },
+	[PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
+	[PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
+	[PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
+	[PCIE_PIPE_ARES] = { 0x1d010, 2 },
+	[PCIE_AXI_S_ARES] = { 0x1d010, 1 },
+	[PCIE_AXI_M_ARES] = { 0x1d010, 0 },
+	[ESS_RESET] = { 0x12008, 0},
+	[GCC_BLSP1_BCR] = {0x01000, 0},
+	[GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
+	[GCC_BLSP1_UART1_BCR] = {0x02038, 0},
+	[GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
+	[GCC_BLSP1_UART2_BCR] = {0x03028, 0},
+	[GCC_BIMC_BCR] = {0x04000, 0},
+	[GCC_TLMM_BCR] = {0x05000, 0},
+	[GCC_IMEM_BCR] = {0x0E000, 0},
+	[GCC_ESS_BCR] = {0x12008, 0},
+	[GCC_PRNG_BCR] = {0x13000, 0},
+	[GCC_BOOT_ROM_BCR] = {0x13008, 0},
+	[GCC_CRYPTO_BCR] = {0x16000, 0},
+	[GCC_SDCC1_BCR] = {0x18000, 0},
+	[GCC_SEC_CTRL_BCR] = {0x1A000, 0},
+	[GCC_AUDIO_BCR] = {0x1B008, 0},
+	[GCC_QPIC_BCR] = {0x1C000, 0},
+	[GCC_PCIE_BCR] = {0x1D000, 0},
+	[GCC_USB2_BCR] = {0x1E008, 0},
+	[GCC_USB2_PHY_BCR] = {0x1E018, 0},
+	[GCC_USB3_BCR] = {0x1E024, 0},
+	[GCC_USB3_PHY_BCR] = {0x1E034, 0},
+	[GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
+	[GCC_PCNOC_BCR] = {0x2102C, 0},
+	[GCC_DCD_BCR] = {0x21038, 0},
+	[GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
+	[GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
+	[GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
+	[GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
+	[GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
+	[GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
+	[GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
+	[GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
+	[GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
+	[GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
+	[GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
+	[GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
+	[GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
+	[GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
+	[GCC_TCSR_BCR] = {0x22000, 0},
+	[GCC_MPM_BCR] = {0x24000, 0},
+	[GCC_SPDM_BCR] = {0x25000, 0},
+};
+
+static struct msm_clk_data ipq4019_clk_data = {
+	.enable = ipq4019_clk_enable,
+	.set_rate = ipq4019_clk_set_rate,
+	.resets = gcc_ipq4019_resets,
+	.num_resets = ARRAY_SIZE(gcc_ipq4019_resets),
+};
+
+static const struct udevice_id gcc_ipq4019_of_match[] = {
+	{
+		.compatible = "qcom,gcc-ipq4019",
+		.data = (ulong)&ipq4019_clk_data,
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(gcc_ipq4019) = {
+	.name		= "gcc_ipq4019",
+	.id		= UCLASS_NOP,
+	.of_match	= gcc_ipq4019_of_match,
+	.bind		= qcom_cc_bind,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
new file mode 100644
index 0000000..7c683e5
--- /dev/null
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: BSD-3-Clause AND GPL-2.0
+/*
+ * Clock and reset drivers for Qualcomm platforms Global Clock
+ * Controller (GCC).
+ *
+ * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ * (C) Copyright 2020 Sartura Ltd. (reset driver)
+ *     Author: Robert Marko <robert.marko@sartura.hr>
+ * (C) Copyright 2022 Linaro Ltd. (reset driver)
+ *     Author: Sumit Garg <sumit.garg@linaro.org>
+ *
+ * Based on Little Kernel driver, simplified
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <reset-uclass.h>
+
+#include "clock-qcom.h"
+
+/* CBCR register fields */
+#define CBCR_BRANCH_ENABLE_BIT  BIT(0)
+#define CBCR_BRANCH_OFF_BIT     BIT(31)
+
+/* Enable clock controlled by CBC soft macro */
+void clk_enable_cbc(phys_addr_t cbcr)
+{
+	setbits_le32(cbcr, CBCR_BRANCH_ENABLE_BIT);
+
+	while (readl(cbcr) & CBCR_BRANCH_OFF_BIT)
+		;
+}
+
+void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0)
+{
+	if (readl(base + gpll0->status) & gpll0->status_bit)
+		return; /* clock already enabled */
+
+	setbits_le32(base + gpll0->ena_vote, gpll0->vote_bit);
+
+	while ((readl(base + gpll0->status) & gpll0->status_bit) == 0)
+		;
+}
+
+#define BRANCH_ON_VAL (0)
+#define BRANCH_NOC_FSM_ON_VAL BIT(29)
+#define BRANCH_CHECK_MASK GENMASK(31, 28)
+
+void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk)
+{
+	u32 val;
+
+	setbits_le32(base + vclk->ena_vote, vclk->vote_bit);
+	do {
+		val = readl(base + vclk->cbcr_reg);
+		val &= BRANCH_CHECK_MASK;
+	} while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL));
+}
+
+#define APPS_CMD_RCGR_UPDATE BIT(0)
+
+/* Update clock command via CMD_RCGR */
+void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
+{
+	u32 count;
+	setbits_le32(apps_cmd_rcgr, APPS_CMD_RCGR_UPDATE);
+
+	/* Wait for frequency to be updated. */
+	for (count = 0; count < 50000; count++) {
+		if (!(readl(apps_cmd_rcgr) & APPS_CMD_RCGR_UPDATE))
+			break;
+		udelay(1);
+	}
+	WARN(count == 50000, "WARNING: RCG @ %#llx [%#010x] stuck at off\n",
+	     apps_cmd_rcgr, readl(apps_cmd_rcgr));
+}
+
+#define CFG_SRC_DIV_MASK	0b11111
+#define CFG_SRC_SEL_SHIFT	8
+#define CFG_SRC_SEL_MASK	(0x7 << CFG_SRC_SEL_SHIFT)
+#define CFG_MODE_SHIFT		12
+#define CFG_MODE_MASK		(0x3 << CFG_MODE_SHIFT)
+#define CFG_MODE_DUAL_EDGE	(0x2 << CFG_MODE_SHIFT)
+#define CFG_HW_CLK_CTRL_MASK	BIT(20)
+
+/*
+ * root set rate for clocks with half integer and MND divider
+ * div should be pre-calculated ((div * 2) - 1)
+ */
+void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
+			  int div, int m, int n, int source, u8 mnd_width)
+{
+	u32 cfg;
+	/* M value for MND divider. */
+	u32 m_val = m;
+	u32 n_minus_m = n - m;
+	/* NOT(N-M) value for MND divider. */
+	u32 n_val = ~n_minus_m * !!(n);
+	/* NOT 2D value for MND divider. */
+	u32 d_val = ~(clamp_t(u32, n, m, n_minus_m));
+	u32 mask = BIT(mnd_width) - 1;
+
+	debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask);
+
+	/* Program MND values */
+	writel(m_val & mask, base + regs->M);
+	writel(n_val & mask, base + regs->N);
+	writel(d_val & mask, base + regs->D);
+
+	/* setup src select and divider */
+	cfg  = readl(base + regs->cfg_rcgr);
+	cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK);
+	cfg |= source & CFG_SRC_SEL_MASK; /* Select clock source */
+
+	if (div)
+		cfg |= div & CFG_SRC_DIV_MASK;
+
+	if (n && n != m)
+		cfg |= CFG_MODE_DUAL_EDGE;
+
+	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
+
+	/* Inform h/w to start using the new config. */
+	clk_bcr_update(base + regs->cmd_rcgr);
+}
+
+/* root set rate for clocks with half integer and mnd_width=0 */
+void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
+		      int source)
+{
+	u32 cfg;
+
+	/* setup src select and divider */
+	cfg  = readl(base + regs->cfg_rcgr);
+	cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK);
+	cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
+
+	/*
+	 * Set the divider; HW permits fraction dividers (+0.5), but
+	 * for simplicity, we will support integers only
+	 */
+	if (div)
+		cfg |= (2 * div - 1) & CFG_SRC_DIV_MASK;
+
+	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
+
+	/* Inform h/w to start using the new config. */
+	clk_bcr_update(base + regs->cmd_rcgr);
+}
+
+const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)
+{
+	if (!f)
+		return NULL;
+
+	if (!f->freq)
+		return f;
+
+	for (; f->freq; f++)
+		if (rate <= f->freq)
+			return f;
+
+	/* Default to our fastest rate */
+	return f - 1;
+}
+
+static int msm_clk_probe(struct udevice *dev)
+{
+	struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev);
+	struct msm_clk_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr(dev);
+	if (priv->base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->data = data;
+
+	return 0;
+}
+
+static ulong msm_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(clk->dev);
+
+	if (data->set_rate)
+		return data->set_rate(clk, rate);
+
+	return 0;
+}
+
+static int msm_clk_enable(struct clk *clk)
+{
+	struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(clk->dev);
+
+	if (data->enable)
+		return data->enable(clk);
+
+	return 0;
+}
+
+static struct clk_ops msm_clk_ops = {
+	.set_rate = msm_clk_set_rate,
+	.enable = msm_clk_enable,
+};
+
+U_BOOT_DRIVER(qcom_clk) = {
+	.name		= "qcom_clk",
+	.id		= UCLASS_CLK,
+	.ops		= &msm_clk_ops,
+	.priv_auto	= sizeof(struct msm_clk_priv),
+	.probe		= msm_clk_probe,
+};
+
+int qcom_cc_bind(struct udevice *parent)
+{
+	struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(parent);
+	struct udevice *clkdev, *rstdev;
+	struct driver *drv;
+	int ret;
+
+	/* Get a handle to the common clk handler */
+	drv = lists_driver_lookup_name("qcom_clk");
+	if (!drv)
+		return -ENOENT;
+
+	/* Register the clock controller */
+	ret = device_bind_with_driver_data(parent, drv, "qcom_clk", (ulong)data,
+					   dev_ofnode(parent), &clkdev);
+	if (ret)
+		return ret;
+
+	/* Bail out early if resets are not specified for this platform */
+	if (!data->resets)
+		return ret;
+
+	/* Get a handle to the common reset handler */
+	drv = lists_driver_lookup_name("qcom_reset");
+	if (!drv)
+		return -ENOENT;
+
+	/* Register the reset controller */
+	ret = device_bind_with_driver_data(parent, drv, "qcom_reset", (ulong)data,
+					   dev_ofnode(parent), &rstdev);
+	if (ret)
+		device_unbind(clkdev);
+
+	return ret;
+}
+
+static int qcom_reset_set(struct reset_ctl *rst, bool assert)
+{
+	struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(rst->dev);
+	void __iomem *base = dev_get_priv(rst->dev);
+	const struct qcom_reset_map *map;
+	u32 value;
+
+	map = &data->resets[rst->id];
+
+	value = readl(base + map->reg);
+
+	if (assert)
+		value |= BIT(map->bit);
+	else
+		value &= ~BIT(map->bit);
+
+	writel(value, base + map->reg);
+
+	return 0;
+}
+
+static int qcom_reset_assert(struct reset_ctl *rst)
+{
+	return qcom_reset_set(rst, true);
+}
+
+static int qcom_reset_deassert(struct reset_ctl *rst)
+{
+	return qcom_reset_set(rst, false);
+}
+
+static const struct reset_ops qcom_reset_ops = {
+	.rst_assert = qcom_reset_assert,
+	.rst_deassert = qcom_reset_deassert,
+};
+
+static int qcom_reset_probe(struct udevice *dev)
+{
+	/* Set our priv pointer to the base address */
+	dev_set_priv(dev, (void *)dev_read_addr(dev));
+
+	return 0;
+}
+
+U_BOOT_DRIVER(qcom_reset) = {
+	.name = "qcom_reset",
+	.id = UCLASS_RESET,
+	.ops = &qcom_reset_ops,
+	.probe = qcom_reset_probe,
+};
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
new file mode 100644
index 0000000..01088c1
--- /dev/null
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+ */
+#ifndef _CLOCK_QCOM_H
+#define _CLOCK_QCOM_H
+
+#include <asm/io.h>
+
+#define CFG_CLK_SRC_CXO   (0 << 8)
+#define CFG_CLK_SRC_GPLL0 (1 << 8)
+#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
+#define CFG_CLK_SRC_MASK  (7 << 8)
+
+struct pll_vote_clk {
+	uintptr_t status;
+	int status_bit;
+	uintptr_t ena_vote;
+	int vote_bit;
+};
+
+struct vote_clk {
+	uintptr_t cbcr_reg;
+	uintptr_t ena_vote;
+	int vote_bit;
+};
+struct bcr_regs {
+	uintptr_t cfg_rcgr;
+	uintptr_t cmd_rcgr;
+	uintptr_t M;
+	uintptr_t N;
+	uintptr_t D;
+};
+
+struct freq_tbl {
+	uint freq;
+	uint src;
+	u8 pre_div;
+	u16 m;
+	u16 n;
+};
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+struct gate_clk {
+	uintptr_t reg;
+	u32 en_val;
+	const char *name;
+};
+
+#ifdef DEBUG
+#define GATE_CLK(clk, reg, val) [clk] = { reg, val, #clk }
+#else
+#define GATE_CLK(clk, reg, val) [clk] = { reg, val, NULL }
+#endif
+
+struct qcom_reset_map {
+	unsigned int reg;
+	u8 bit;
+};
+
+struct clk;
+
+struct msm_clk_data {
+	const struct qcom_reset_map	*resets;
+	unsigned long			num_resets;
+	const struct gate_clk		*clks;
+	unsigned long			num_clks;
+
+	int (*enable)(struct clk *clk);
+	unsigned long (*set_rate)(struct clk *clk, unsigned long rate);
+};
+
+struct msm_clk_priv {
+	phys_addr_t		base;
+	struct msm_clk_data	*data;
+};
+
+int qcom_cc_bind(struct udevice *parent);
+void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0);
+void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
+void clk_enable_cbc(phys_addr_t cbcr);
+void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
+const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate);
+void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
+			  int div, int m, int n, int source, u8 mnd_width);
+void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
+		      int source);
+
+static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
+{
+	u32 val;
+	if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0)
+		return;
+
+	val = readl(priv->base + priv->data->clks[id].reg);
+	writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg);
+}
+
+#endif
diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
new file mode 100644
index 0000000..f5b3528
--- /dev/null
+++ b/drivers/clk/qcom/clock-qcs404.c
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm QCS404
+ *
+ * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <dt-bindings/clock/qcom,gcc-qcs404.h>
+
+#include "clock-qcom.h"
+
+/* Clocks: (from CLK_CTL_BASE)  */
+#define GPLL0_STATUS			(0x21000)
+#define GPLL1_STATUS			(0x20000)
+#define APCS_GPLL_ENA_VOTE		(0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE	(0x45004)
+
+/* BLSP1 AHB clock (root clock for BLSP) */
+#define BLSP1_AHB_CBCR			0x1008
+
+/* Uart clock control registers */
+#define BLSP1_UART2_BCR			(0x3028)
+#define BLSP1_UART2_APPS_CBCR		(0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR	(0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR	(0x3038)
+#define BLSP1_UART2_APPS_M		(0x303C)
+#define BLSP1_UART2_APPS_N		(0x3040)
+#define BLSP1_UART2_APPS_D		(0x3044)
+
+/* I2C controller clock control registerss */
+#define BLSP1_QUP0_I2C_APPS_CBCR	(0x6028)
+#define BLSP1_QUP0_I2C_APPS_CMD_RCGR	(0x602C)
+#define BLSP1_QUP0_I2C_APPS_CFG_RCGR	(0x6030)
+#define BLSP1_QUP1_I2C_APPS_CBCR	(0x2008)
+#define BLSP1_QUP1_I2C_APPS_CMD_RCGR	(0x200C)
+#define BLSP1_QUP1_I2C_APPS_CFG_RCGR	(0x2010)
+#define BLSP1_QUP2_I2C_APPS_CBCR	(0x3010)
+#define BLSP1_QUP2_I2C_APPS_CMD_RCGR	(0x3000)
+#define BLSP1_QUP2_I2C_APPS_CFG_RCGR	(0x3004)
+#define BLSP1_QUP3_I2C_APPS_CBCR	(0x4020)
+#define BLSP1_QUP3_I2C_APPS_CMD_RCGR	(0x4000)
+#define BLSP1_QUP3_I2C_APPS_CFG_RCGR	(0x4004)
+#define BLSP1_QUP4_I2C_APPS_CBCR	(0x5020)
+#define BLSP1_QUP4_I2C_APPS_CMD_RCGR	(0x5000)
+#define BLSP1_QUP4_I2C_APPS_CFG_RCGR	(0x5004)
+
+/* SD controller clock control registers */
+#define SDCC_BCR(n)			(((n) * 0x1000) + 0x41000)
+#define SDCC_CMD_RCGR(n)		(((n) * 0x1000) + 0x41004)
+#define SDCC_CFG_RCGR(n)		(((n) * 0x1000) + 0x41008)
+#define SDCC_M(n)			(((n) * 0x1000) + 0x4100C)
+#define SDCC_N(n)			(((n) * 0x1000) + 0x41010)
+#define SDCC_D(n)			(((n) * 0x1000) + 0x41014)
+#define SDCC_APPS_CBCR(n)		(((n) * 0x1000) + 0x41018)
+#define SDCC_AHB_CBCR(n)		(((n) * 0x1000) + 0x4101C)
+
+/* USB-3.0 controller clock control registers */
+#define SYS_NOC_USB3_CBCR		(0x26014)
+#define USB30_BCR			(0x39000)
+#define USB3PHY_BCR			(0x39008)
+#define USB30_MASTER_CBCR		(0x3900C)
+#define USB30_SLEEP_CBCR		(0x39010)
+#define USB30_MOCK_UTMI_CBCR		(0x39014)
+#define USB30_MOCK_UTMI_CMD_RCGR	(0x3901C)
+#define USB30_MOCK_UTMI_CFG_RCGR	(0x39020)
+#define USB30_MASTER_CMD_RCGR		(0x39028)
+#define USB30_MASTER_CFG_RCGR		(0x3902C)
+#define USB30_MASTER_M			(0x39030)
+#define USB30_MASTER_N			(0x39034)
+#define USB30_MASTER_D			(0x39038)
+#define USB2A_PHY_SLEEP_CBCR		(0x4102C)
+#define USB_HS_PHY_CFG_AHB_CBCR		(0x41030)
+
+/* ETH controller clock control registers */
+#define ETH_PTP_CBCR			(0x4e004)
+#define ETH_RGMII_CBCR			(0x4e008)
+#define ETH_SLAVE_AHB_CBCR		(0x4e00c)
+#define ETH_AXI_CBCR			(0x4e010)
+#define EMAC_PTP_CMD_RCGR		(0x4e014)
+#define EMAC_PTP_CFG_RCGR		(0x4e018)
+#define EMAC_CMD_RCGR			(0x4e01c)
+#define EMAC_CFG_RCGR			(0x4e020)
+#define EMAC_M				(0x4e024)
+#define EMAC_N				(0x4e028)
+#define EMAC_D				(0x4e02c)
+
+
+/* GPLL0 clock control registers */
+#define GPLL0_STATUS_ACTIVE BIT(31)
+
+#define CFG_CLK_SRC_GPLL1	BIT(8)
+#define GPLL1_STATUS_ACTIVE	BIT(31)
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg = BLSP1_AHB_CBCR,
+	.ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.vote_bit = BIT(10) | BIT(5) | BIT(4),
+};
+
+static const struct bcr_regs uart2_regs = {
+	.cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
+	.cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
+	.M = BLSP1_UART2_APPS_M,
+	.N = BLSP1_UART2_APPS_N,
+	.D = BLSP1_UART2_APPS_D,
+};
+
+static const struct bcr_regs sdc_regs = {
+	.cfg_rcgr = SDCC_CFG_RCGR(1),
+	.cmd_rcgr = SDCC_CMD_RCGR(1),
+	.M = SDCC_M(1),
+	.N = SDCC_N(1),
+	.D = SDCC_D(1),
+};
+
+static struct pll_vote_clk gpll0_vote_clk = {
+	.status = GPLL0_STATUS,
+	.status_bit = GPLL0_STATUS_ACTIVE,
+	.ena_vote = APCS_GPLL_ENA_VOTE,
+	.vote_bit = BIT(0),
+};
+
+static struct pll_vote_clk gpll1_vote_clk = {
+	.status = GPLL1_STATUS,
+	.status_bit = GPLL1_STATUS_ACTIVE,
+	.ena_vote = APCS_GPLL_ENA_VOTE,
+	.vote_bit = BIT(1),
+};
+
+static const struct bcr_regs usb30_master_regs = {
+	.cfg_rcgr = USB30_MASTER_CFG_RCGR,
+	.cmd_rcgr = USB30_MASTER_CMD_RCGR,
+	.M = USB30_MASTER_M,
+	.N = USB30_MASTER_N,
+	.D = USB30_MASTER_D,
+};
+
+static const struct bcr_regs emac_regs = {
+	.cfg_rcgr = EMAC_CFG_RCGR,
+	.cmd_rcgr = EMAC_CMD_RCGR,
+	.M = EMAC_M,
+	.N = EMAC_N,
+	.D = EMAC_D,
+};
+
+static const struct bcr_regs emac_ptp_regs = {
+	.cfg_rcgr = EMAC_PTP_CFG_RCGR,
+	.cmd_rcgr = EMAC_PTP_CMD_RCGR,
+	.M = EMAC_M,
+	.N = EMAC_N,
+	.D = EMAC_D,
+};
+
+static const struct bcr_regs blsp1_qup0_i2c_apps_regs = {
+	.cmd_rcgr = BLSP1_QUP0_I2C_APPS_CMD_RCGR,
+	.cfg_rcgr = BLSP1_QUP0_I2C_APPS_CFG_RCGR,
+	/* mnd_width = 0 */
+};
+
+static const struct bcr_regs blsp1_qup1_i2c_apps_regs = {
+	.cmd_rcgr = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
+	.cfg_rcgr = BLSP1_QUP1_I2C_APPS_CFG_RCGR,
+	/* mnd_width = 0 */
+};
+
+static const struct bcr_regs blsp1_qup2_i2c_apps_regs = {
+	.cmd_rcgr = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
+	.cfg_rcgr = BLSP1_QUP2_I2C_APPS_CFG_RCGR,
+	/* mnd_width = 0 */
+};
+
+static const struct bcr_regs blsp1_qup3_i2c_apps_regs = {
+	.cmd_rcgr = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
+	.cfg_rcgr = BLSP1_QUP3_I2C_APPS_CFG_RCGR,
+	/* mnd_width = 0 */
+};
+
+static const struct bcr_regs blsp1_qup4_i2c_apps_regs = {
+	.cmd_rcgr = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
+	.cfg_rcgr = BLSP1_QUP4_I2C_APPS_CFG_RCGR,
+	/* mnd_width = 0 */
+};
+
+static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case GCC_BLSP1_UART2_APPS_CLK:
+		/* UART: 115200 */
+		clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
+				     CFG_CLK_SRC_CXO, 16);
+		clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
+		break;
+	case GCC_BLSP1_AHB_CLK:
+		clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
+		break;
+	case GCC_SDCC1_APPS_CLK:
+		/* SDCC1: 200MHz */
+		clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 7, 0, 0,
+				     CFG_CLK_SRC_GPLL0, 8);
+		clk_enable_gpll0(priv->base, &gpll0_vote_clk);
+		clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
+		break;
+	case GCC_SDCC1_AHB_CLK:
+		clk_enable_cbc(priv->base + SDCC_AHB_CBCR(1));
+		break;
+	case GCC_ETH_RGMII_CLK:
+		if (rate == 250000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0,
+					     CFG_CLK_SRC_GPLL1, 8);
+		else if (rate == 125000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 7, 0, 0,
+					     CFG_CLK_SRC_GPLL1, 8);
+		else if (rate == 50000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 19, 0, 0,
+					     CFG_CLK_SRC_GPLL1, 8);
+		else if (rate == 5000000)
+			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 1, 50,
+					     CFG_CLK_SRC_GPLL1, 8);
+		break;
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+static int qcs404_clk_enable(struct clk *clk)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case GCC_USB30_MASTER_CLK:
+		clk_enable_cbc(priv->base + USB30_MASTER_CBCR);
+		clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 7, 0, 0,
+				     CFG_CLK_SRC_GPLL0, 8);
+		break;
+	case GCC_SYS_NOC_USB3_CLK:
+		clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
+		break;
+	case GCC_USB30_SLEEP_CLK:
+		clk_enable_cbc(priv->base + USB30_SLEEP_CBCR);
+		break;
+	case GCC_USB30_MOCK_UTMI_CLK:
+		clk_enable_cbc(priv->base + USB30_MOCK_UTMI_CBCR);
+		break;
+	case GCC_USB_HS_PHY_CFG_AHB_CLK:
+		clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR);
+		break;
+	case GCC_USB2A_PHY_SLEEP_CLK:
+		clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR);
+		break;
+	case GCC_ETH_PTP_CLK:
+		/* SPEED_1000: freq -> 250MHz */
+		clk_enable_cbc(priv->base + ETH_PTP_CBCR);
+		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
+		clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 3, 0, 0,
+				     CFG_CLK_SRC_GPLL1, 8);
+		break;
+	case GCC_ETH_RGMII_CLK:
+		/* SPEED_1000: freq -> 250MHz */
+		clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
+		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
+		clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0,
+				     CFG_CLK_SRC_GPLL1, 8);
+		break;
+	case GCC_ETH_SLAVE_AHB_CLK:
+		clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
+		break;
+	case GCC_ETH_AXI_CLK:
+		clk_enable_cbc(priv->base + ETH_AXI_CBCR);
+		break;
+	case GCC_BLSP1_AHB_CLK:
+		clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
+		break;
+	case GCC_BLSP1_QUP0_I2C_APPS_CLK:
+		clk_enable_cbc(priv->base + BLSP1_QUP0_I2C_APPS_CBCR);
+		clk_rcg_set_rate(priv->base, &blsp1_qup0_i2c_apps_regs, 0,
+				 CFG_CLK_SRC_CXO);
+		break;
+	case GCC_BLSP1_QUP1_I2C_APPS_CLK:
+		clk_enable_cbc(priv->base + BLSP1_QUP1_I2C_APPS_CBCR);
+		clk_rcg_set_rate(priv->base, &blsp1_qup1_i2c_apps_regs, 0,
+				 CFG_CLK_SRC_CXO);
+		break;
+	case GCC_BLSP1_QUP2_I2C_APPS_CLK:
+		clk_enable_cbc(priv->base + BLSP1_QUP2_I2C_APPS_CBCR);
+		clk_rcg_set_rate(priv->base, &blsp1_qup2_i2c_apps_regs, 0,
+				 CFG_CLK_SRC_CXO);
+		break;
+	case GCC_BLSP1_QUP3_I2C_APPS_CLK:
+		clk_enable_cbc(priv->base + BLSP1_QUP3_I2C_APPS_CBCR);
+		clk_rcg_set_rate(priv->base, &blsp1_qup3_i2c_apps_regs, 0,
+				 CFG_CLK_SRC_CXO);
+		break;
+	case GCC_BLSP1_QUP4_I2C_APPS_CLK:
+		clk_enable_cbc(priv->base + BLSP1_QUP4_I2C_APPS_CBCR);
+		clk_rcg_set_rate(priv->base, &blsp1_qup4_i2c_apps_regs, 0,
+				 CFG_CLK_SRC_CXO);
+		break;
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+static const struct qcom_reset_map qcs404_gcc_resets[] = {
+	[GCC_GENI_IR_BCR] = { 0x0F000 },
+	[GCC_CDSP_RESTART] = { 0x18000 },
+	[GCC_USB_HS_BCR] = { 0x41000 },
+	[GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 },
+	[GCC_QUSB2_PHY_BCR] = { 0x4103c },
+	[GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 },
+	[GCC_USB2A_PHY_BCR] = { 0x0000c, 0 },
+	[GCC_USB3_PHY_BCR] = { 0x39004 },
+	[GCC_USB_30_BCR] = { 0x39000 },
+	[GCC_USB3PHY_PHY_BCR] = { 0x39008 },
+	[GCC_PCIE_0_BCR] = { 0x3e000 },
+	[GCC_PCIE_0_PHY_BCR] = { 0x3e004 },
+	[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 },
+	[GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c },
+	[GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6},
+	[GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 },
+	[GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 },
+	[GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 },
+	[GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 },
+	[GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 },
+	[GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 },
+	[GCC_EMAC_BCR] = { 0x4e000 },
+	[GCC_WDSP_RESTART] = {0x19000},
+};
+
+static const struct msm_clk_data qcs404_clk_gcc_data = {
+	.resets = qcs404_gcc_resets,
+	.num_resets = ARRAY_SIZE(qcs404_gcc_resets),
+	.enable = qcs404_clk_enable,
+	.set_rate = qcs404_clk_set_rate,
+};
+
+static const struct udevice_id gcc_qcs404_of_match[] = {
+	{
+		.compatible = "qcom,gcc-qcs404",
+		.data = (ulong)&qcs404_clk_gcc_data
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(gcc_qcs404) = {
+	.name		= "gcc_qcs404",
+	.id		= UCLASS_NOP,
+	.of_match	= gcc_qcs404_of_match,
+	.bind		= qcom_cc_bind,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
new file mode 100644
index 0000000..36ffee7
--- /dev/null
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm SDM845
+ *
+ * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org>
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ * Based on Little Kernel driver, simplified
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+
+#include "clock-qcom.h"
+
+#define SE9_AHB_CBCR		0x25004
+#define SE9_UART_APPS_CBCR	0x29004
+#define SE9_UART_APPS_CMD_RCGR	0x18148
+#define SE9_UART_APPS_CFG_RCGR	0x1814C
+#define SE9_UART_APPS_M		0x18150
+#define SE9_UART_APPS_N		0x18154
+#define SE9_UART_APPS_D		0x18158
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+	F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
+	F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
+	F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+	F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
+	F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
+	F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
+	F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
+	F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
+	F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
+	F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
+	F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
+	F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
+	F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
+	F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
+	F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
+	{ }
+};
+
+static const struct bcr_regs uart2_regs = {
+	.cfg_rcgr = SE9_UART_APPS_CFG_RCGR,
+	.cmd_rcgr = SE9_UART_APPS_CMD_RCGR,
+	.M = SE9_UART_APPS_M,
+	.N = SE9_UART_APPS_N,
+	.D = SE9_UART_APPS_D,
+};
+
+static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+	const struct freq_tbl *freq;
+
+	switch (clk->id) {
+	case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */
+		freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
+		clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
+				     freq->pre_div, freq->m, freq->n, freq->src, 16);
+		return freq->freq;
+	default:
+		return 0;
+	}
+}
+
+static const struct gate_clk sdm845_clks[] = {
+	GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK,		0x5200c, 0x00000400),
+	GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK,		0x5200c, 0x00000800),
+	GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK,		0x5200c, 0x00001000),
+	GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK,		0x5200c, 0x00002000),
+	GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK,		0x5200c, 0x00004000),
+	GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK,		0x5200c, 0x00008000),
+	GATE_CLK(GCC_QUPV3_WRAP0_S6_CLK,		0x5200c, 0x00010000),
+	GATE_CLK(GCC_QUPV3_WRAP0_S7_CLK,		0x5200c, 0x00020000),
+	GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK,		0x5200c, 0x00400000),
+	GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK,		0x5200c, 0x00800000),
+	GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK,		0x5200c, 0x02000000),
+	GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK,		0x5200c, 0x04000000),
+	GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK,		0x5200c, 0x08000000),
+	GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK,		0x5200c, 0x10000000),
+	GATE_CLK(GCC_QUPV3_WRAP1_S7_CLK,		0x5200c, 0x20000000),
+	GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK,		0x5200c, 0x00000040),
+	GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK,		0x5200c, 0x00000080),
+	GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK,		0x5200c, 0x00100000),
+	GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK,		0x5200c, 0x00200000),
+	GATE_CLK(GCC_SDCC2_AHB_CLK,			0x14008, 0x00000001),
+	GATE_CLK(GCC_SDCC2_APPS_CLK,			0x14004, 0x00000001),
+	GATE_CLK(GCC_SDCC4_AHB_CLK,			0x16008, 0x00000001),
+	GATE_CLK(GCC_SDCC4_APPS_CLK,			0x16004, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_AHB_CLK,			0x75010, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_AXI_CLK,			0x7500c, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_CLKREF_CLK,		0x8c004, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_ICE_CORE_CLK,		0x75058, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_PHY_AUX_CLK,		0x7508c, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_0_CLK,		0x75018, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_1_CLK,		0x750a8, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK,		0x75014, 0x00000001),
+	GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK,		0x75054, 0x00000001),
+	GATE_CLK(GCC_UFS_MEM_CLKREF_CLK,		0x8c000, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_AHB_CLK,			0x77010, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_AXI_CLK,			0x7700c, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK,		0x77058, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK,		0x7708c, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK,		0x77018, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK,		0x770a8, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK,		0x77014, 0x00000001),
+	GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK,		0x77054, 0x00000001),
+	GATE_CLK(GCC_USB30_PRIM_MASTER_CLK,		0x0f00c, 0x00000001),
+	GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK,		0x0f014, 0x00000001),
+	GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK,		0x0f010, 0x00000001),
+	GATE_CLK(GCC_USB30_SEC_MASTER_CLK,		0x1000c, 0x00000001),
+	GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK,		0x10014, 0x00000001),
+	GATE_CLK(GCC_USB30_SEC_SLEEP_CLK,		0x10010, 0x00000001),
+	GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK,		0x8c008, 0x00000001),
+	GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK,		0x0f04c, 0x00000001),
+	GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK,		0x0f050, 0x00000001),
+	GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK,		0x0f054, 0x00000001),
+	GATE_CLK(GCC_USB3_SEC_CLKREF_CLK,		0x8c028, 0x00000001),
+	GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK,		0x1004c, 0x00000001),
+	GATE_CLK(GCC_USB3_SEC_PHY_PIPE_CLK,		0x10054, 0x00000001),
+	GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK,		0x10050, 0x00000001),
+	GATE_CLK(GCC_USB_PHY_CFG_AHB2PHY_CLK,		0x6a004, 0x00000001),
+};
+
+static int sdm845_clk_enable(struct clk *clk)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	debug("%s: clk %s\n", __func__, sdm845_clks[clk->id].name);
+
+	qcom_gate_clk_en(priv, clk->id);
+
+	return 0;
+}
+
+static const struct qcom_reset_map sdm845_gcc_resets[] = {
+	[GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 },
+	[GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
+	[GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
+	[GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
+	[GCC_SDCC2_BCR] = { 0x14000 },
+	[GCC_SDCC4_BCR] = { 0x16000 },
+	[GCC_UFS_CARD_BCR] = { 0x75000 },
+	[GCC_UFS_PHY_BCR] = { 0x77000 },
+	[GCC_USB30_PRIM_BCR] = { 0xf000 },
+	[GCC_USB30_SEC_BCR] = { 0x10000 },
+	[GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
+	[GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 },
+	[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
+	[GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
+	[GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
+	[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
+	[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
+};
+
+static struct msm_clk_data sdm845_clk_data = {
+	.resets = sdm845_gcc_resets,
+	.num_resets = ARRAY_SIZE(sdm845_gcc_resets),
+	.clks = sdm845_clks,
+	.num_clks = ARRAY_SIZE(sdm845_clks),
+
+	.enable = sdm845_clk_enable,
+	.set_rate = sdm845_clk_set_rate,
+};
+
+static const struct udevice_id gcc_sdm845_of_match[] = {
+	{
+		.compatible = "qcom,gcc-sdm845",
+		.data = (ulong)&sdm845_clk_data,
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(gcc_sdm845) = {
+	.name		= "gcc_sdm845",
+	.id		= UCLASS_NOP,
+	.of_match	= gcc_sdm845_of_match,
+	.bind		= qcom_cc_bind,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 63e62e1..27df5d8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -318,12 +318,11 @@
 config QCOM_PMIC_GPIO
 	bool "Qualcomm generic PMIC GPIO/keypad driver"
 	depends on DM_GPIO && PMIC_QCOM
+	select BUTTON
 	help
 	  Support for GPIO pins and power/reset buttons found on
 	  Qualcomm SoCs PMIC.
-	  Default name for GPIO bank is "pm8916".
-	  Power and reset buttons are placed in "pwkey_qcom" bank and
-          have gpio numbers 0 and 1 respectively.
+	  The GPIO bank is called "pmic"
 
 config PCF8575_GPIO
 	bool "PCF8575 I2C GPIO Expander driver"
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index 51670f2..80cd28b 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -11,13 +11,10 @@
 #include <asm/global_data.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <mach/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Register offsets */
-#define GPIO_CONFIG_OFF(no)         ((no) * 0x1000)
-#define GPIO_IN_OUT_OFF(no)         ((no) * 0x1000 + 0x4)
-
 /* OE */
 #define GPIO_OE_DISABLE  (0x0 << 9)
 #define GPIO_OE_ENABLE   (0x1 << 9)
@@ -29,57 +26,64 @@
 
 struct msm_gpio_bank {
 	phys_addr_t base;
+	const struct msm_pin_data *pin_data;
 };
 
+#define GPIO_CONFIG_REG(dev, x) \
+	(qcom_pin_offset(((struct msm_gpio_bank *)dev_get_priv(dev))->pin_data->pin_offsets, x))
+
+#define GPIO_IN_OUT_REG(dev, x) \
+	(GPIO_CONFIG_REG(dev, x) + 0x4)
+
 static int msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
 {
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
-	phys_addr_t reg = priv->base + GPIO_CONFIG_OFF(gpio);
 
 	/* Disable OE bit */
-	clrsetbits_le32(reg, GPIO_OE_MASK, GPIO_OE_DISABLE);
+	clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
+			GPIO_OE_MASK, GPIO_OE_DISABLE);
 
 	return 0;
 }
 
-static int msm_gpio_set_value(struct udevice *dev, unsigned gpio, int value)
+static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
 {
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
 
 	value = !!value;
 	/* set value */
-	writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_OFF(gpio));
+	writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
 
 	return 0;
 }
 
-static int msm_gpio_direction_output(struct udevice *dev, unsigned gpio,
+static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
 				     int value)
 {
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
-	phys_addr_t reg = priv->base + GPIO_CONFIG_OFF(gpio);
 
 	value = !!value;
 	/* set value */
-	writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_OFF(gpio));
+	writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
 	/* switch direction */
-	clrsetbits_le32(reg, GPIO_OE_MASK, GPIO_OE_ENABLE);
+	clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
+			GPIO_OE_MASK, GPIO_OE_ENABLE);
 
 	return 0;
 }
 
-static int msm_gpio_get_value(struct udevice *dev, unsigned gpio)
+static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
 {
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
 
-	return !!(readl(priv->base + GPIO_IN_OUT_OFF(gpio)) >> GPIO_IN);
+	return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
 }
 
-static int msm_gpio_get_function(struct udevice *dev, unsigned offset)
+static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
 {
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
 
-	if (readl(priv->base + GPIO_CONFIG_OFF(offset)) & GPIO_OE_ENABLE)
+	if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
 		return GPIOF_OUTPUT;
 
 	return GPIOF_INPUT;
@@ -98,6 +102,7 @@
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
 
 	priv->base = dev_read_addr(dev);
+	priv->pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);
 
 	return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
 }
@@ -105,9 +110,10 @@
 static int msm_gpio_of_to_plat(struct udevice *dev)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	const struct msm_pin_data *pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					     "gpio-count", 0);
+	/* Get the pin count from the pinctrl driver */
+	uc_priv->gpio_count = pin_data->pin_count;
 	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 					 "gpio-bank-name", NULL);
 	if (uc_priv->bank_name == NULL)
diff --git a/drivers/gpio/qcom_pmic_gpio.c b/drivers/gpio/qcom_pmic_gpio.c
index 65feb45..6167c84 100644
--- a/drivers/gpio/qcom_pmic_gpio.c
+++ b/drivers/gpio/qcom_pmic_gpio.c
@@ -221,11 +221,14 @@
 {
 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
 	int reg;
+	u64 pid;
 
-	priv->pid = dev_read_addr(dev);
-	if (priv->pid == FDT_ADDR_T_NONE)
+	pid = dev_read_addr(dev);
+	if (pid == FDT_ADDR_T_NONE)
 		return log_msg_ret("bad address", -EINVAL);
 
+	priv->pid = pid;
+
 	/* Do a sanity check */
 	reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
 	if (reg != REG_TYPE_VAL)
@@ -242,14 +245,36 @@
 	return 0;
 }
 
+/*
+ * Parse basic GPIO count specified via the gpio-ranges property
+ * as specified in Linux devicetrees
+ * Returns < 0 on error, otherwise gpio count
+ */
+static int qcom_gpio_of_parse_ranges(struct udevice *dev)
+{
+	int ret;
+	struct ofnode_phandle_args args;
+
+	ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "gpio-ranges",
+					     NULL, 3, 0, &args);
+	if (ret)
+		return log_msg_ret("gpio-ranges", ret);
+
+	return args.args[2];
+}
+
 static int qcom_gpio_of_to_plat(struct udevice *dev)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	int ret;
 
-	uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0);
-	uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
-	if (uc_priv->bank_name == NULL)
-		uc_priv->bank_name = "qcom_pmic";
+	ret = qcom_gpio_of_parse_ranges(dev);
+	if (ret > 0)
+		uc_priv->gpio_count = ret;
+	else
+		return ret;
+
+	uc_priv->bank_name = "pmic";
 
 	return 0;
 }
@@ -272,104 +297,3 @@
 	.priv_auto	= sizeof(struct qcom_gpio_bank),
 };
 
-
-/* Add pmic buttons as GPIO as well - there is no generic way for now */
-#define PON_INT_RT_STS                        0x10
-#define KPDPWR_ON_INT_BIT                     0
-#define RESIN_ON_INT_BIT                      1
-
-static int qcom_pwrkey_get_function(struct udevice *dev, unsigned offset)
-{
-	return GPIOF_INPUT;
-}
-
-static int qcom_pwrkey_get_value(struct udevice *dev, unsigned offset)
-{
-	struct qcom_gpio_bank *priv = dev_get_priv(dev);
-
-	int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS);
-
-	if (reg < 0)
-		return 0;
-
-	switch (offset) {
-	case 0: /* Power button */
-		return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0;
-		break;
-	case 1: /* Reset button */
-	default:
-		return (reg & BIT(RESIN_ON_INT_BIT)) != 0;
-		break;
-	}
-}
-
-/*
- * Since pmic buttons modelled as GPIO, we need empty direction functions
- * to trick u-boot button driver
- */
-static int qcom_pwrkey_direction_input(struct udevice *dev, unsigned int offset)
-{
-	return 0;
-}
-
-static int qcom_pwrkey_direction_output(struct udevice *dev, unsigned int offset, int value)
-{
-	return -EOPNOTSUPP;
-}
-
-static const struct dm_gpio_ops qcom_pwrkey_ops = {
-	.get_value		= qcom_pwrkey_get_value,
-	.get_function		= qcom_pwrkey_get_function,
-	.direction_input	= qcom_pwrkey_direction_input,
-	.direction_output	= qcom_pwrkey_direction_output,
-};
-
-static int qcom_pwrkey_probe(struct udevice *dev)
-{
-	struct qcom_gpio_bank *priv = dev_get_priv(dev);
-	int reg;
-
-	priv->pid = dev_read_addr(dev);
-	if (priv->pid == FDT_ADDR_T_NONE)
-		return log_msg_ret("bad address", -EINVAL);
-
-	/* Do a sanity check */
-	reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
-	if (reg != 0x1)
-		return log_msg_ret("bad type", -ENXIO);
-
-	reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
-	if ((reg & 0x5) == 0)
-		return log_msg_ret("bad subtype", -ENXIO);
-
-	return 0;
-}
-
-static int qcom_pwrkey_of_to_plat(struct udevice *dev)
-{
-	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
-
-	uc_priv->gpio_count = 2;
-	uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
-	if (uc_priv->bank_name == NULL)
-		uc_priv->bank_name = "pwkey_qcom";
-
-	return 0;
-}
-
-static const struct udevice_id qcom_pwrkey_ids[] = {
-	{ .compatible = "qcom,pm8916-pwrkey" },
-	{ .compatible = "qcom,pm8994-pwrkey" },
-	{ .compatible = "qcom,pm8998-pwrkey" },
-	{ }
-};
-
-U_BOOT_DRIVER(pwrkey_qcom) = {
-	.name	= "pwrkey_qcom",
-	.id	= UCLASS_GPIO,
-	.of_match = qcom_pwrkey_ids,
-	.of_to_plat = qcom_pwrkey_of_to_plat,
-	.probe	= qcom_pwrkey_probe,
-	.ops	= &qcom_pwrkey_ops,
-	.priv_auto	= sizeof(struct qcom_gpio_bank),
-};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e8e4400..e85a0dd 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -527,13 +527,6 @@
 	  legacy UART or other devices in the Winbond Super IO chips
 	  on X86 platforms.
 
-config QCOM_GENI_SE
-	bool "Qualcomm GENI Serial Engine Driver"
-	depends on ARCH_SNAPDRAGON
-	help
-	  The driver manages Generic Interface (GENI) firmware based
-	  Qualcomm Technologies, Inc. Universal Peripheral (QUP) Wrapper.
-
 config QFW
 	bool
 	help
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index cda701d..6bf1e79 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -60,7 +60,6 @@
 obj-$(CONFIG_P2SB) += p2sb-uclass.o
 obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
 obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
-obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
 ifdef CONFIG_QFW
 obj-y += qfw.o
 obj-$(CONFIG_QFW_ACPI) += qfw_acpi.o
diff --git a/drivers/misc/qcom-geni-se.c b/drivers/misc/qcom-geni-se.c
deleted file mode 100644
index 281a5ec..0000000
--- a/drivers/misc/qcom-geni-se.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Qualcomm Generic Interface (GENI) Serial Engine (SE) Wrapper
- *
- * Copyright (C) 2023 Linaro Ltd. <vladimir.zapolskiy@linaro.org>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <misc.h>
-#include <asm/io.h>
-
-static int geni_se_qup_read(struct udevice *dev, int offset,
-			    void *buf, int size)
-{
-	fdt_addr_t base = dev_read_addr(dev);
-
-	if (size != sizeof(u32))
-		return -EINVAL;
-
-	*(u32 *)buf = readl(base + offset);
-
-	return size;
-}
-
-static struct misc_ops geni_se_qup_ops = {
-	.read = geni_se_qup_read,
-};
-
-static const struct udevice_id geni_se_qup_ids[] = {
-	{ .compatible = "qcom,geni-se-qup" },
-	{}
-};
-
-U_BOOT_DRIVER(geni_se_qup) = {
-	.name = "geni_se_qup",
-	.id = UCLASS_MISC,
-	.of_match = geni_se_qup_ids,
-	.ops = &geni_se_qup_ops,
-	.flags  = DM_FLAG_PRE_RELOC,
-};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index fceafea..a1d53cf 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -355,6 +355,7 @@
 source "drivers/pinctrl/nexell/Kconfig"
 source "drivers/pinctrl/nuvoton/Kconfig"
 source "drivers/pinctrl/nxp/Kconfig"
+source "drivers/pinctrl/qcom/Kconfig"
 source "drivers/pinctrl/renesas/Kconfig"
 source "drivers/pinctrl/rockchip/Kconfig"
 source "drivers/pinctrl/sunxi/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 96a0516..0e929d8 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_PINCTRL_INTEL) += intel/
 obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
 obj-$(CONFIG_ARCH_NPCM)         += nuvoton/
+obj-$(CONFIG_PINCTRL_QCOM) += qcom/
 obj-$(CONFIG_ARCH_RMOBILE) += renesas/
 obj-$(CONFIG_ARCH_RZN1) += renesas/
 obj-$(CONFIG_PINCTRL_SANDBOX)	+= pinctrl-sandbox.o
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
new file mode 100644
index 0000000..2fe6398
--- /dev/null
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -0,0 +1,46 @@
+if ARCH_SNAPDRAGON
+
+config PINCTRL_QCOM
+	depends on PINCTRL_GENERIC
+	def_bool n
+
+menu "Qualcomm pinctrl drivers"
+
+config PINCTRL_QCOM_APQ8016
+	bool "Qualcomm APQ8016 GCC"
+	select PINCTRL_QCOM
+	help
+	  Say Y here to enable support for pinctrl on the MSM8916 / APQ8016
+	  Snapdragon 410 SoC, as well as the associated GPIO driver.
+
+config PINCTRL_QCOM_APQ8096
+	bool "Qualcomm APQ8096 GCC"
+	select PINCTRL_QCOM
+	help
+	  Say Y here to enable support for pinctrl on the MSM8996 / APQ8096
+	  Snapdragon 820 SoC, as well as the associated GPIO driver.
+
+config PINCTRL_QCOM_IPQ4019
+	bool "Qualcomm IPQ4019 GCC"
+	select PINCTRL_QCOM
+	help
+	  Say Y here to enable support for pinctrl on the IPQ4019 SoC,
+	  as well as the associated GPIO driver.
+
+config PINCTRL_QCOM_QCS404
+	bool "Qualcomm QCS404 GCC"
+	select PINCTRL_QCOM
+	help
+	  Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC,
+	  as well as the associated GPIO driver.
+
+config PINCTRL_QCOM_SDM845
+	bool "Qualcomm SDM845 GCC"
+	select PINCTRL_QCOM
+	help
+	  Say Y here to enable support for pinctrl on the Snapdragon 845 SoC,
+	  as well as the associated GPIO driver.
+
+endmenu
+
+endif
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
new file mode 100644
index 0000000..6d9aca6
--- /dev/null
+++ b/drivers/pinctrl/qcom/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2023 Linaro Ltd.
+
+obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o
+obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o
+obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
+obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
+obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
+obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
diff --git a/arch/arm/mach-snapdragon/pinctrl-apq8016.c b/drivers/pinctrl/qcom/pinctrl-apq8016.c
similarity index 73%
rename from arch/arm/mach-snapdragon/pinctrl-apq8016.c
rename to drivers/pinctrl/qcom/pinctrl-apq8016.c
index 70c0be0..8149ffd 100644
--- a/arch/arm/mach-snapdragon/pinctrl-apq8016.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8016.c
@@ -6,8 +6,10 @@
  *
  */
 
-#include "pinctrl-snapdragon.h"
 #include <common.h>
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
 
 #define MAX_PIN_NAME_LEN 32
 static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
@@ -52,10 +54,23 @@
 	return msm_pinctrl_functions[selector].val;
 }
 
-struct msm_pinctrl_data apq8016_data = {
-	.pin_count = 133,
+static const struct msm_pinctrl_data apq8016_data = {
+	.pin_data = { .pin_count = 133, },
 	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
 	.get_function_name = apq8016_get_function_name,
 	.get_function_mux = apq8016_get_function_mux,
 	.get_pin_name = apq8016_get_pin_name,
 };
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+	{ .compatible = "qcom,msm8916-pinctrl", .data = (ulong)&apq8016_data },
+	{ /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_apq8016) = {
+	.name		= "pinctrl_apq8016",
+	.id		= UCLASS_NOP,
+	.of_match	= msm_pinctrl_ids,
+	.ops		= &msm_pinctrl_ops,
+	.bind		= msm_pinctrl_bind,
+};
diff --git a/arch/arm/mach-snapdragon/pinctrl-apq8096.c b/drivers/pinctrl/qcom/pinctrl-apq8096.c
similarity index 72%
rename from arch/arm/mach-snapdragon/pinctrl-apq8096.c
rename to drivers/pinctrl/qcom/pinctrl-apq8096.c
index 45462f0..d64ab1f 100644
--- a/arch/arm/mach-snapdragon/pinctrl-apq8096.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8096.c
@@ -6,8 +6,10 @@
  *
  */
 
-#include "pinctrl-snapdragon.h"
 #include <common.h>
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
 
 #define MAX_PIN_NAME_LEN 32
 static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
@@ -47,10 +49,23 @@
 	return msm_pinctrl_functions[selector].val;
 }
 
-struct msm_pinctrl_data apq8096_data = {
-	.pin_count = 157,
+static const struct msm_pinctrl_data apq8096_data = {
+	.pin_data = { .pin_count = 157, },
 	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
 	.get_function_name = apq8096_get_function_name,
 	.get_function_mux = apq8096_get_function_mux,
 	.get_pin_name = apq8096_get_pin_name,
 };
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+	{ .compatible = "qcom,msm8996-pinctrl", .data = (ulong)&apq8096_data },
+	{ /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_apq8096) = {
+	.name		= "pinctrl_apq8096",
+	.id		= UCLASS_NOP,
+	.of_match	= msm_pinctrl_ids,
+	.ops		= &msm_pinctrl_ops,
+	.bind		= msm_pinctrl_bind,
+};
diff --git a/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
similarity index 71%
rename from arch/arm/mach-ipq40xx/pinctrl-ipq4019.c
rename to drivers/pinctrl/qcom/pinctrl-ipq4019.c
index 3e365f8..2d99f99 100644
--- a/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
@@ -7,12 +7,13 @@
  * Author: Robert Marko <robert.marko@sartura.hr>
  */
 
-#include "pinctrl-snapdragon.h"
 #include <common.h>
+#include <dm.h>
 
-#define MAX_PIN_NAME_LEN 32
-static char pin_name[MAX_PIN_NAME_LEN];
+#include "pinctrl-qcom.h"
 
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
 static const struct pinctrl_function msm_pinctrl_functions[] = {
 	{"gpio", 0},
 	{"blsp_uart0_0", 1}, /* Only for GPIO:16,17 */
@@ -26,7 +27,6 @@
 	{"mdc_0", 1}, /* Only for GPIO7 */
 	{"mdc_1", 2}, /* Only for GPIO52 */
 };
-
 static const char *ipq4019_get_function_name(struct udevice *dev,
 					     unsigned int selector)
 {
@@ -45,10 +45,23 @@
 	return msm_pinctrl_functions[selector].val;
 }
 
-struct msm_pinctrl_data ipq4019_data = {
-	.pin_count = 100,
+static const struct msm_pinctrl_data ipq4019_data = {
+	.pin_data = { .pin_count = 100, },
 	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
 	.get_function_name = ipq4019_get_function_name,
 	.get_function_mux = ipq4019_get_function_mux,
 	.get_pin_name = ipq4019_get_pin_name,
 };
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+	{ .compatible = "qcom,ipq4019-pinctrl", .data = (ulong)&ipq4019_data },
+	{ /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_ipq4019) = {
+	.name		= "pinctrl_ipq4019",
+	.id		= UCLASS_NOP,
+	.of_match	= msm_pinctrl_ids,
+	.ops		= &msm_pinctrl_ops,
+	.bind		= msm_pinctrl_bind,
+};
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/drivers/pinctrl/qcom/pinctrl-qcom.c
similarity index 68%
rename from arch/arm/mach-snapdragon/pinctrl-snapdragon.c
rename to drivers/pinctrl/qcom/pinctrl-qcom.c
index 826dc51..dc3d8c4 100644
--- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.c
@@ -11,17 +11,23 @@
 #include <errno.h>
 #include <asm/io.h>
 #include <dm/device_compat.h>
+#include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <asm/gpio.h>
 #include <dm/pinctrl.h>
 #include <linux/bitops.h>
-#include "pinctrl-snapdragon.h"
+#include <mach/gpio.h>
+
+#include "pinctrl-qcom.h"
 
 struct msm_pinctrl_priv {
 	phys_addr_t base;
 	struct msm_pinctrl_data *data;
 };
 
+#define GPIO_CONFIG_REG(priv, x) \
+	(qcom_pin_offset((priv)->data->pin_data.pin_offsets, x))
+
-#define GPIO_CONFIG_OFFSET(x)         ((x) * 0x1000)
 #define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
 #define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
 #define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
@@ -44,7 +50,7 @@
 {
 	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
 
-	return priv->data->pin_count;
+	return priv->data->pin_data.pin_count;
 }
 
 static const char *msm_get_function_name(struct udevice *dev,
@@ -60,7 +66,7 @@
 	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
 
 	priv->base = dev_read_addr(dev);
-	priv->data = (struct msm_pinctrl_data *)dev->driver_data;
+	priv->data = (struct msm_pinctrl_data *)dev_get_driver_data(dev);
 
 	return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
 }
@@ -77,7 +83,7 @@
 {
 	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
 
-	clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+	clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
 			TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
 			priv->data->get_function_mux(func_selector) << 2);
 	return 0;
@@ -91,15 +97,15 @@
 	switch (param) {
 	case PIN_CONFIG_DRIVE_STRENGTH:
 		argument = (argument / 2) - 1;
-		clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+		clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
 				TLMM_DRV_STRENGTH_MASK, argument << 6);
 		break;
 	case PIN_CONFIG_BIAS_DISABLE:
-		clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+		clrbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
 			     TLMM_GPIO_PULL_MASK);
 		break;
 	case PIN_CONFIG_BIAS_PULL_UP:
-		clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+		clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
 				TLMM_GPIO_PULL_MASK, argument);
 		break;
 	default:
@@ -109,7 +115,7 @@
 	return 0;
 }
 
-static struct pinctrl_ops msm_pinctrl_ops = {
+struct pinctrl_ops msm_pinctrl_ops = {
 	.get_pins_count = msm_get_pins_count,
 	.get_pin_name = msm_get_pin_name,
 	.set_state = pinctrl_generic_set_state,
@@ -121,12 +127,24 @@
 	.get_function_name = msm_get_function_name,
 };
 
-static int msm_pinctrl_bind(struct udevice *dev)
+int msm_pinctrl_bind(struct udevice *dev)
 {
 	ofnode node = dev_ofnode(dev);
+	struct msm_pinctrl_data *data = (struct msm_pinctrl_data *)dev_get_driver_data(dev);
+	struct driver *drv;
+	struct udevice *pinctrl_dev;
 	const char *name;
 	int ret;
 
+	drv = lists_driver_lookup_name("pinctrl_qcom");
+	if (!drv)
+		return -ENOENT;
+
+	ret = device_bind_with_driver_data(dev_get_parent(dev), drv, ofnode_get_name(node), (ulong)data,
+					   dev_ofnode(dev), &pinctrl_dev);
+	if (ret)
+		return ret;
+
 	ofnode_get_property(node, "gpio-controller", &ret);
 	if (ret < 0)
 		return 0;
@@ -136,31 +154,27 @@
 	if (!name)
 		return -EINVAL;
 
-	/* Bind gpio node */
-	ret = device_bind_driver_to_node(dev, "gpio_msm",
-					 name, node, NULL);
-	if (ret)
-		return ret;
+	drv = lists_driver_lookup_name("gpio_msm");
+	if (!drv) {
+		printf("Can't find gpio_msm driver\n");
+		return -ENODEV;
+	}
 
-	dev_dbg(dev, "bind %s\n", name);
+	/* Bind gpio device as a child of the pinctrl device */
+	ret = device_bind_with_driver_data(pinctrl_dev, drv,
+					   name, (ulong)&data->pin_data, node, NULL);
+	if (ret) {
+		device_unbind(pinctrl_dev);
+		return ret;
+	}
 
 	return 0;
 }
 
-static const struct udevice_id msm_pinctrl_ids[] = {
-	{ .compatible = "qcom,msm8916-pinctrl", .data = (ulong)&apq8016_data },
-	{ .compatible = "qcom,msm8996-pinctrl", .data = (ulong)&apq8096_data },
-	{ .compatible = "qcom,sdm845-pinctrl", .data = (ulong)&sdm845_data },
-	{ .compatible = "qcom,qcs404-pinctrl", .data = (ulong)&qcs404_data },
-	{ }
-};
-
-U_BOOT_DRIVER(pinctrl_snapdraon) = {
-	.name		= "pinctrl_msm",
+U_BOOT_DRIVER(pinctrl_qcom) = {
+	.name		= "pinctrl_qcom",
 	.id		= UCLASS_PINCTRL,
-	.of_match	= msm_pinctrl_ids,
 	.priv_auto	= sizeof(struct msm_pinctrl_priv),
 	.ops		= &msm_pinctrl_ops,
 	.probe		= msm_pinctrl_probe,
-	.bind		= msm_pinctrl_bind,
 };
diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h b/drivers/pinctrl/qcom/pinctrl-qcom.h
similarity index 66%
rename from arch/arm/mach-ipq40xx/pinctrl-snapdragon.h
rename to drivers/pinctrl/qcom/pinctrl-qcom.h
index b4823a3..07f2eae 100644
--- a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.h
@@ -5,11 +5,16 @@
  * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
  *
  */
-#ifndef _PINCTRL_SNAPDRAGON_H
-#define _PINCTRL_SNAPDRAGON_H
+#ifndef _PINCTRL_QCOM_H
+#define _PINCTRL_QCOM_H
+
+#include <asm/types.h>
+#include <mach/gpio.h>
+
+struct udevice;
 
 struct msm_pinctrl_data {
-	int pin_count;
+	struct msm_pin_data pin_data;
 	int functions_count;
 	const char *(*get_function_name)(struct udevice *dev,
 					 unsigned int selector);
@@ -23,6 +28,8 @@
 	int val;
 };
 
-extern struct msm_pinctrl_data ipq4019_data;
+extern struct pinctrl_ops msm_pinctrl_ops;
+
+int msm_pinctrl_bind(struct udevice *dev);
 
 #endif
diff --git a/arch/arm/mach-snapdragon/pinctrl-qcs404.c b/drivers/pinctrl/qcom/pinctrl-qcs404.c
similarity index 76%
rename from arch/arm/mach-snapdragon/pinctrl-qcs404.c
rename to drivers/pinctrl/qcom/pinctrl-qcs404.c
index a6e53c4..ac00afa 100644
--- a/arch/arm/mach-snapdragon/pinctrl-qcs404.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcs404.c
@@ -5,8 +5,10 @@
  * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org>
  */
 
-#include "pinctrl-snapdragon.h"
 #include <common.h>
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
 
 #define MAX_PIN_NAME_LEN 32
 static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
@@ -59,10 +61,23 @@
 	return msm_pinctrl_functions[selector].val;
 }
 
-struct msm_pinctrl_data qcs404_data = {
-	.pin_count = 126,
+static struct msm_pinctrl_data qcs404_data = {
+	.pin_data = { .pin_count = 126, },
 	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
 	.get_function_name = qcs404_get_function_name,
 	.get_function_mux = qcs404_get_function_mux,
 	.get_pin_name = qcs404_get_pin_name,
 };
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+	{ .compatible = "qcom,qcs404-pinctrl", .data = (ulong)&qcs404_data },
+	{ /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_qcs404) = {
+	.name		= "pinctrl_qcs404",
+	.id		= UCLASS_NOP,
+	.of_match	= msm_pinctrl_ids,
+	.ops		= &msm_pinctrl_ops,
+	.bind		= msm_pinctrl_bind,
+};
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c b/drivers/pinctrl/qcom/pinctrl-sdm845.c
new file mode 100644
index 0000000..9f0f408
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm SDM845 pinctrl
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ * (C) Copyright 2023 Linaro Ltd.
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define NORTH	0x00500000
+#define SOUTH	0x00900000
+#define EAST	0x00100000
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+	{"qup9", 1},
+	{"gpio", 0},
+};
+
+static const unsigned int sdm845_pin_offsets[] = {
+	[0] = EAST,    [1] = EAST,    [2] = EAST,    [3] = EAST,    [4] = NORTH,
+	[5] = NORTH,   [6] = NORTH,   [7] = NORTH,   [8] = EAST,    [9] = EAST,
+	[10] = EAST,   [11] = EAST,   [12] = SOUTH,  [13] = SOUTH,  [14] = SOUTH,
+	[15] = SOUTH,  [16] = SOUTH,  [17] = SOUTH,  [18] = SOUTH,  [19] = SOUTH,
+	[20] = SOUTH,  [21] = SOUTH,  [22] = SOUTH,  [23] = SOUTH,  [24] = SOUTH,
+	[25] = SOUTH,  [26] = SOUTH,  [27] = EAST,   [28] = EAST,   [29] = EAST,
+	[30] = EAST,   [31] = NORTH,  [32] = NORTH,  [33] = NORTH,  [34] = NORTH,
+	[35] = SOUTH,  [36] = SOUTH,  [37] = SOUTH,  [38] = NORTH,  [39] = EAST,
+	[40] = SOUTH,  [41] = EAST,   [42] = EAST,   [43] = EAST,   [44] = EAST,
+	[45] = EAST,   [46] = EAST,   [47] = EAST,   [48] = EAST,   [49] = NORTH,
+	[50] = NORTH,  [51] = NORTH,  [52] = NORTH,  [53] = NORTH,  [54] = NORTH,
+	[55] = NORTH,  [56] = NORTH,  [57] = NORTH,  [58] = NORTH,  [59] = NORTH,
+	[60] = NORTH,  [61] = NORTH,  [62] = NORTH,  [63] = NORTH,  [64] = NORTH,
+	[65] = NORTH,  [66] = NORTH,  [67] = NORTH,  [68] = NORTH,  [69] = EAST,
+	[70] = EAST,   [71] = EAST,   [72] = EAST,   [73] = EAST,   [74] = EAST,
+	[75] = EAST,   [76] = EAST,   [77] = EAST,   [78] = EAST,   [79] = NORTH,
+	[80] = NORTH,  [81] = NORTH,  [82] = NORTH,  [83] = NORTH,  [84] = NORTH,
+	[85] = EAST,   [86] = EAST,   [87] = EAST,   [88] = EAST,   [89] = SOUTH,
+	[90] = SOUTH,  [91] = SOUTH,  [92] = SOUTH,  [93] = SOUTH,  [94] = SOUTH,
+	[95] = SOUTH,  [96] = SOUTH,  [97] = NORTH,  [98] = NORTH,  [99] = NORTH,
+	[100] = NORTH, [101] = NORTH, [102] = NORTH, [103] = NORTH, [104] = NORTH,
+	[105] = NORTH, [106] = NORTH, [107] = NORTH, [108] = NORTH, [109] = NORTH,
+	[110] = NORTH, [111] = NORTH, [112] = NORTH, [113] = NORTH, [114] = NORTH,
+	[115] = NORTH, [116] = NORTH, [117] = NORTH, [118] = NORTH, [119] = NORTH,
+	[120] = NORTH, [121] = NORTH, [122] = EAST,  [123] = EAST,  [124] = EAST,
+	[125] = EAST,  [126] = EAST,  [127] = NORTH, [128] = NORTH, [129] = NORTH,
+	[130] = NORTH, [131] = NORTH, [132] = NORTH, [133] = NORTH, [134] = NORTH,
+	[135] = NORTH, [136] = NORTH, [137] = NORTH, [138] = NORTH, [139] = NORTH,
+	[140] = NORTH, [141] = NORTH, [142] = NORTH, [143] = NORTH, [144] = NORTH,
+	[145] = NORTH, [146] = NORTH, [147] = NORTH, [148] = NORTH, [149] = NORTH,
+};
+
+static const char *sdm845_get_function_name(struct udevice *dev,
+					     unsigned int selector)
+{
+	return msm_pinctrl_functions[selector].name;
+}
+
+static const char *sdm845_get_pin_name(struct udevice *dev,
+					unsigned int selector)
+{
+	snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+	return pin_name;
+}
+
+static unsigned int sdm845_get_function_mux(unsigned int selector)
+{
+	return msm_pinctrl_functions[selector].val;
+}
+
+static struct msm_pinctrl_data sdm845_data = {
+	.pin_data = {
+		.pin_offsets = sdm845_pin_offsets,
+		.pin_count = ARRAY_SIZE(sdm845_pin_offsets),
+	},
+	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+	.get_function_name = sdm845_get_function_name,
+	.get_function_mux = sdm845_get_function_mux,
+	.get_pin_name = sdm845_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+	{ .compatible = "qcom,sdm845-pinctrl", .data = (ulong)&sdm845_data },
+	{ /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_sdm845) = {
+	.name		= "pinctrl_sdm845",
+	.id		= UCLASS_NOP,
+	.of_match	= msm_pinctrl_ids,
+	.ops		= &msm_pinctrl_ops,
+	.bind		= msm_pinctrl_bind,
+};
diff --git a/drivers/power/pmic/pmic_qcom.c b/drivers/power/pmic/pmic_qcom.c
index ad8daf4..f2ac649 100644
--- a/drivers/power/pmic/pmic_qcom.c
+++ b/drivers/power/pmic/pmic_qcom.c
@@ -66,12 +66,19 @@
 static int pmic_qcom_probe(struct udevice *dev)
 {
 	struct pmic_qcom_priv *priv = dev_get_priv(dev);
+	int ret;
 
-	priv->usid = dev_read_addr(dev);
-
-	if (priv->usid == FDT_ADDR_T_NONE)
+	/*
+	 * dev_read_addr() can't be used here because the reg property actually
+	 * contains two discrete values, not a single 64-bit address.
+	 * The address is the first value.
+	 */
+	ret = ofnode_read_u32_index(dev_ofnode(dev), "reg", 0, &priv->usid);
+	if (ret < 0)
 		return -EINVAL;
 
+	debug("usid: %d\n", priv->usid);
+
 	return 0;
 }
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 73bbd30..88e04d9 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -156,13 +156,6 @@
 	help
 	  Support for reset controller on i.MX7/8 SoCs.
 
-config RESET_QCOM
-	bool "Reset driver for Qualcomm SoCs"
-	depends on DM_RESET && (ARCH_SNAPDRAGON || ARCH_IPQ40XX)
-	default y
-	help
-	  Support for reset controller on Qualcomm SoCs.
-
 config RESET_SIFIVE
 	bool "Reset Driver for SiFive SoC's"
 	depends on DM_RESET && CLK_SIFIVE_PRCI && (TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED)
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index e2239a2..7b0066f 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -24,7 +24,6 @@
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
-obj-$(CONFIG_RESET_QCOM) += reset-qcom.o
 obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o
 obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
 obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
diff --git a/drivers/reset/reset-qcom.c b/drivers/reset/reset-qcom.c
deleted file mode 100644
index 94315e7..0000000
--- a/drivers/reset/reset-qcom.c
+++ /dev/null
@@ -1,195 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2020 Sartura Ltd.
- * Copyright (c) 2022 Linaro Ltd.
- *
- * Author: Robert Marko <robert.marko@sartura.hr>
- *         Sumit Garg <sumit.garg@linaro.org>
- *
- * Based on Linux driver
- */
-
-#include <asm/io.h>
-#include <common.h>
-#include <dm.h>
-#include <reset-uclass.h>
-#include <linux/bitops.h>
-#include <malloc.h>
-
-struct qcom_reset_priv {
-	phys_addr_t base;
-};
-
-struct qcom_reset_map {
-	unsigned int reg;
-	u8 bit;
-};
-
-#ifdef CONFIG_ARCH_IPQ40XX
-#include <dt-bindings/reset/qcom,ipq4019-reset.h>
-static const struct qcom_reset_map gcc_qcom_resets[] = {
-	[WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
-	[WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
-	[WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
-	[WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
-	[WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
-	[WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
-	[WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
-	[WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
-	[WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
-	[WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
-	[WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
-	[WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
-	[USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
-	[USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
-	[USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
-	[USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
-	[USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
-	[PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
-	[PCIE_AHB_ARES] = { 0x1d010, 10 },
-	[PCIE_PWR_ARES] = { 0x1d010, 9 },
-	[PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
-	[PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
-	[PCIE_PHY_ARES] = { 0x1d010, 6 },
-	[PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
-	[PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
-	[PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
-	[PCIE_PIPE_ARES] = { 0x1d010, 2 },
-	[PCIE_AXI_S_ARES] = { 0x1d010, 1 },
-	[PCIE_AXI_M_ARES] = { 0x1d010, 0 },
-	[ESS_RESET] = { 0x12008, 0},
-	[GCC_BLSP1_BCR] = {0x01000, 0},
-	[GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
-	[GCC_BLSP1_UART1_BCR] = {0x02038, 0},
-	[GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
-	[GCC_BLSP1_UART2_BCR] = {0x03028, 0},
-	[GCC_BIMC_BCR] = {0x04000, 0},
-	[GCC_TLMM_BCR] = {0x05000, 0},
-	[GCC_IMEM_BCR] = {0x0E000, 0},
-	[GCC_ESS_BCR] = {0x12008, 0},
-	[GCC_PRNG_BCR] = {0x13000, 0},
-	[GCC_BOOT_ROM_BCR] = {0x13008, 0},
-	[GCC_CRYPTO_BCR] = {0x16000, 0},
-	[GCC_SDCC1_BCR] = {0x18000, 0},
-	[GCC_SEC_CTRL_BCR] = {0x1A000, 0},
-	[GCC_AUDIO_BCR] = {0x1B008, 0},
-	[GCC_QPIC_BCR] = {0x1C000, 0},
-	[GCC_PCIE_BCR] = {0x1D000, 0},
-	[GCC_USB2_BCR] = {0x1E008, 0},
-	[GCC_USB2_PHY_BCR] = {0x1E018, 0},
-	[GCC_USB3_BCR] = {0x1E024, 0},
-	[GCC_USB3_PHY_BCR] = {0x1E034, 0},
-	[GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
-	[GCC_PCNOC_BCR] = {0x2102C, 0},
-	[GCC_DCD_BCR] = {0x21038, 0},
-	[GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
-	[GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
-	[GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
-	[GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
-	[GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
-	[GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
-	[GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
-	[GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
-	[GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
-	[GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
-	[GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
-	[GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
-	[GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
-	[GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
-	[GCC_TCSR_BCR] = {0x22000, 0},
-	[GCC_MPM_BCR] = {0x24000, 0},
-	[GCC_SPDM_BCR] = {0x25000, 0},
-};
-#endif
-
-#ifdef CONFIG_TARGET_QCS404EVB
-#include <dt-bindings/clock/qcom,gcc-qcs404.h>
-static const struct qcom_reset_map gcc_qcom_resets[] = {
-	[GCC_GENI_IR_BCR] = { 0x0F000 },
-	[GCC_CDSP_RESTART] = { 0x18000 },
-	[GCC_USB_HS_BCR] = { 0x41000 },
-	[GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 },
-	[GCC_QUSB2_PHY_BCR] = { 0x4103c },
-	[GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 },
-	[GCC_USB2A_PHY_BCR] = { 0x0000c, 0 },
-	[GCC_USB3_PHY_BCR] = { 0x39004 },
-	[GCC_USB_30_BCR] = { 0x39000 },
-	[GCC_USB3PHY_PHY_BCR] = { 0x39008 },
-	[GCC_PCIE_0_BCR] = { 0x3e000 },
-	[GCC_PCIE_0_PHY_BCR] = { 0x3e004 },
-	[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 },
-	[GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c },
-	[GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6},
-	[GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 },
-	[GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 },
-	[GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 },
-	[GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 },
-	[GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 },
-	[GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 },
-	[GCC_EMAC_BCR] = { 0x4e000 },
-	[GCC_WDSP_RESTART] = {0x19000},
-};
-#endif
-
-static int qcom_reset_assert(struct reset_ctl *rst)
-{
-	struct qcom_reset_priv *priv = dev_get_priv(rst->dev);
-	const struct qcom_reset_map *reset_map = gcc_qcom_resets;
-	const struct qcom_reset_map *map;
-	u32 value;
-
-	map = &reset_map[rst->id];
-
-	value = readl(priv->base + map->reg);
-	value |= BIT(map->bit);
-	writel(value, priv->base + map->reg);
-
-	return 0;
-}
-
-static int qcom_reset_deassert(struct reset_ctl *rst)
-{
-	struct qcom_reset_priv *priv = dev_get_priv(rst->dev);
-	const struct qcom_reset_map *reset_map = gcc_qcom_resets;
-	const struct qcom_reset_map *map;
-	u32 value;
-
-	map = &reset_map[rst->id];
-
-	value = readl(priv->base + map->reg);
-	value &= ~BIT(map->bit);
-	writel(value, priv->base + map->reg);
-
-	return 0;
-}
-
-static const struct reset_ops qcom_reset_ops = {
-	.rst_assert = qcom_reset_assert,
-	.rst_deassert = qcom_reset_deassert,
-};
-
-static const struct udevice_id qcom_reset_ids[] = {
-	{ .compatible = "qcom,gcc-reset-ipq4019" },
-	{ .compatible = "qcom,gcc-reset-qcs404" },
-	{ }
-};
-
-static int qcom_reset_probe(struct udevice *dev)
-{
-	struct qcom_reset_priv *priv = dev_get_priv(dev);
-
-	priv->base = dev_read_addr(dev);
-	if (priv->base == FDT_ADDR_T_NONE)
-		return -EINVAL;
-
-	return 0;
-}
-
-U_BOOT_DRIVER(qcom_reset) = {
-	.name = "qcom_reset",
-	.id = UCLASS_RESET,
-	.of_match = qcom_reset_ids,
-	.ops = &qcom_reset_ops,
-	.probe = qcom_reset_probe,
-	.priv_auto = sizeof(struct qcom_reset_priv),
-};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6628a88..26460c4 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -972,8 +972,6 @@
 
 config MSM_GENI_SERIAL
 	bool "Qualcomm on-chip GENI UART"
-	select MISC
-	imply QCOM_GENI_SE
 	help
 	  Support UART based on Generic Interface (GENI) Serial Engine (SE),
 	  used on Qualcomm Snapdragon SoCs. Should support all qualcomm SOCs
diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
index b8bc614..e5c3dcf 100644
--- a/drivers/serial/serial_msm_geni.c
+++ b/drivers/serial/serial_msm_geni.c
@@ -188,8 +188,8 @@
 	int ret;
 
 	clk = devm_clk_get(dev, NULL);
-	if (!clk)
-		return -EINVAL;
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
 
 	ret = clk_set_rate(clk, rate);
 	return ret;
@@ -248,11 +248,16 @@
 	struct msm_serial_data *priv = dev_get_priv(dev);
 	u64 clk_rate;
 	u32 clk_div;
+	int ret;
 
 	priv->baud = baud;
 
 	clk_rate = get_clk_div_rate(baud, priv->oversampling, &clk_div);
-	geni_serial_set_clock_rate(dev, clk_rate);
+	ret = geni_serial_set_clock_rate(dev, clk_rate);
+	if (ret < 0) {
+		pr_err("%s: Couldn't set clock rate: %d\n", __func__, ret);
+		return ret;
+	}
 	geni_serial_baud(priv->base, clk_div, baud);
 
 	return 0;
@@ -485,12 +490,12 @@
 	.setbrg = msm_serial_setbrg,
 };
 
-static void geni_set_oversampling(struct udevice *dev)
+static int geni_set_oversampling(struct udevice *dev)
 {
 	struct msm_serial_data *priv = dev_get_priv(dev);
-	struct udevice *parent_dev = dev_get_parent(dev);
+	ofnode parent_node = ofnode_get_parent(dev_ofnode(dev));
 	u32 geni_se_version;
-	int ret;
+	fdt_addr_t addr;
 
 	priv->oversampling = UART_OVERSAMPLING;
 
@@ -498,16 +503,20 @@
 	 * It could happen that GENI SE IP is missing in the board's device
 	 * tree or GENI UART node is a direct child of SoC device tree node.
 	 */
-	if (device_get_uclass_id(parent_dev) != UCLASS_MISC)
-		return;
+	if (!ofnode_device_is_compatible(parent_node, "qcom,geni-se-qup")) {
+		pr_err("%s: UART node must be a child of geniqup node\n",
+		       __func__);
+		return -ENODEV;
+	}
 
-	ret = misc_read(parent_dev, QUP_HW_VER_REG,
-			&geni_se_version, sizeof(geni_se_version));
-	if (ret != sizeof(geni_se_version))
-		return;
+	/* Read the HW_VER register relative to the parents address space */
+	addr = ofnode_get_addr(parent_node);
+	geni_se_version = readl(addr + QUP_HW_VER_REG);
 
 	if (geni_se_version >= QUP_SE_VERSION_2_5)
 		priv->oversampling /= 2;
+
+	return 0;
 }
 
 static inline void geni_serial_init(struct udevice *dev)
@@ -552,8 +561,11 @@
 static int msm_serial_probe(struct udevice *dev)
 {
 	struct msm_serial_data *priv = dev_get_priv(dev);
+	int ret;
 
-	geni_set_oversampling(dev);
+	ret = geni_set_oversampling(dev);
+	if (ret < 0)
+		return ret;
 
 	/* No need to reinitialize the UART after relocation */
 	if (gd->flags & GD_FLG_RELOC)
diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
index 27a035c..5fe8a70 100644
--- a/drivers/spmi/spmi-msm.c
+++ b/drivers/spmi/spmi-msm.c
@@ -70,7 +70,7 @@
 
 struct msm_spmi_priv {
 	phys_addr_t arb_chnl;  /* ARB channel mapping base */
-	phys_addr_t spmi_core; /* SPMI core */
+	phys_addr_t spmi_chnls; /* SPMI channels */
 	phys_addr_t spmi_obs;  /* SPMI observer */
 	/* SPMI channel map */
 	uint8_t channel_map[SPMI_MAX_SLAVES][SPMI_MAX_PERIPH];
@@ -95,10 +95,10 @@
 
 	/* Disable IRQ mode for the current channel*/
 	writel(0x0,
-	       priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG);
+	       priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG);
 
 	/* Write single byte */
-	writel(val, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_WDATA);
+	writel(val, priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_WDATA);
 
 	/* Prepare write command */
 	reg |= SPMI_CMD_EXT_REG_WRITE_LONG << SPMI_CMD_OPCODE_SHIFT;
@@ -113,12 +113,12 @@
 		ch_offset = SPMI_CH_OFFSET(channel);
 
 	/* Send write command */
-	writel(reg, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0);
+	writel(reg, priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0);
 
 	/* Wait till CMD DONE status */
 	reg = 0;
 	while (!reg) {
-		reg = readl(priv->spmi_core + SPMI_CH_OFFSET(channel) +
+		reg = readl(priv->spmi_chnls + SPMI_CH_OFFSET(channel) +
 			    SPMI_REG_STATUS);
 	}
 
@@ -186,47 +186,37 @@
 static int msm_spmi_probe(struct udevice *dev)
 {
 	struct msm_spmi_priv *priv = dev_get_priv(dev);
-	phys_addr_t config_addr;
+	phys_addr_t core_addr;
 	u32 hw_ver;
-	u32 version;
 	int i;
-	int err;
 
-	config_addr = dev_read_addr_index(dev, 0);
-	priv->spmi_core = dev_read_addr_index(dev, 1);
-	priv->spmi_obs = dev_read_addr_index(dev, 2);
+	core_addr = dev_read_addr_name(dev, "core");
+	priv->spmi_chnls = dev_read_addr_name(dev, "chnls");
+	priv->spmi_obs = dev_read_addr_name(dev, "obsrvr");
 
-	hw_ver = readl(config_addr + PMIC_ARB_VERSION);
+	hw_ver = readl(core_addr + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V3_MIN) {
 		priv->arb_ver = V2;
-		version = 2;
-		priv->arb_chnl = config_addr + APID_MAP_OFFSET_V1_V2_V3;
+		priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3;
 	} else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) {
 		priv->arb_ver = V3;
-		version = 3;
-		priv->arb_chnl = config_addr + APID_MAP_OFFSET_V1_V2_V3;
+		priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3;
 	} else {
 		priv->arb_ver = V5;
-		version = 5;
-		priv->arb_chnl = config_addr + APID_MAP_OFFSET_V5;
-
-		if (err) {
-			dev_err(dev, "could not read APID->PPID mapping table, rc= %d\n", err);
-			return -1;
-		}
+		priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5;
 	}
 
-	dev_dbg(dev, "PMIC Arb Version-%d (0x%x)\n", version, hw_ver);
+	dev_dbg(dev, "PMIC Arb Version-%d (%#x)\n", hw_ver >> 28, hw_ver);
 
 	if (priv->arb_chnl == FDT_ADDR_T_NONE ||
-	    priv->spmi_core == FDT_ADDR_T_NONE ||
+	    priv->spmi_chnls == FDT_ADDR_T_NONE ||
 	    priv->spmi_obs == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
-	dev_dbg(dev, "priv->arb_chnl address (%llu)\n", priv->arb_chnl);
-	dev_dbg(dev, "priv->spmi_core address (%llu)\n", priv->spmi_core);
-	dev_dbg(dev, "priv->spmi_obs address (%llu)\n", priv->spmi_obs);
+	dev_dbg(dev, "priv->arb_chnl address (%#08llx)\n", priv->arb_chnl);
+	dev_dbg(dev, "priv->spmi_chnls address (%#08llx)\n", priv->spmi_chnls);
+	dev_dbg(dev, "priv->spmi_obs address (%#08llx)\n", priv->spmi_obs);
 	/* Scan peripherals connected to each SPMI channel */
 	for (i = 0; i < SPMI_MAX_PERIPH; i++) {
 		uint32_t periph = readl(priv->arb_chnl + ARB_CHANNEL_OFFSET(i));
diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
index 73aec34..00102cd 100644
--- a/include/configs/dragonboard410c.h
+++ b/include/configs/dragonboard410c.h
@@ -9,7 +9,6 @@
 #define __CONFIGS_DRAGONBOARD410C_H
 
 #include <linux/sizes.h>
-#include <asm/arch/sysmap-apq8016.h>
 
 /* Build new ELF image from u-boot.bin (U-Boot + appended DTB) */
 
diff --git a/include/configs/dragonboard820c.h b/include/configs/dragonboard820c.h
index 4997083..c6d9182 100644
--- a/include/configs/dragonboard820c.h
+++ b/include/configs/dragonboard820c.h
@@ -9,7 +9,6 @@
 #define __CONFIGS_DRAGONBOARD820C_H
 
 #include <linux/sizes.h>
-#include <asm/arch/sysmap-apq8096.h>
 
 /* Physical Memory Map */
 
diff --git a/include/configs/dragonboard845c.h b/include/configs/dragonboard845c.h
index c1e590f..14a8a2c 100644
--- a/include/configs/dragonboard845c.h
+++ b/include/configs/dragonboard845c.h
@@ -9,7 +9,6 @@
 #define __CONFIGS_SDM845_H
 
 #include <linux/sizes.h>
-#include <asm/arch/sysmap-sdm845.h>
 
 #define CFG_SYS_BAUDRATE_TABLE	{ 115200, 230400, 460800, 921600 }
 
diff --git a/include/configs/qcs404-evb.h b/include/configs/qcs404-evb.h
index 8ea59aa..9501d43 100644
--- a/include/configs/qcs404-evb.h
+++ b/include/configs/qcs404-evb.h
@@ -9,7 +9,6 @@
 #define __CONFIGS_QCS404EVB_H
 
 #include <linux/sizes.h>
-#include <asm/arch/sysmap-qcs404.h>
 
 #define CFG_SYS_BAUDRATE_TABLE	{ 115200, 230400, 460800, 921600 }
 
diff --git a/include/configs/sdm845.h b/include/configs/sdm845.h
index 673268d..5ad8569 100644
--- a/include/configs/sdm845.h
+++ b/include/configs/sdm845.h
@@ -9,7 +9,6 @@
 #define __CONFIGS_SDM845_H
 
 #include <linux/sizes.h>
-#include <asm/arch/sysmap-sdm845.h>
 
 #define CFG_SYS_BAUDRATE_TABLE	{ 115200, 230400, 460800, 921600 }
 
diff --git a/include/dt-bindings/clock/qcom,gcc-ipq4019.h b/include/dt-bindings/clock/qcom,gcc-ipq4019.h
new file mode 100644
index 0000000..7e8a7be
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gcc-ipq4019.h
@@ -0,0 +1,169 @@
+/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+#ifndef __QCOM_CLK_IPQ4019_H__
+#define __QCOM_CLK_IPQ4019_H__
+
+#define GCC_DUMMY_CLK					0
+#define AUDIO_CLK_SRC					1
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC			2
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC			3
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC			4
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC			5
+#define BLSP1_UART1_APPS_CLK_SRC			6
+#define BLSP1_UART2_APPS_CLK_SRC			7
+#define GCC_USB3_MOCK_UTMI_CLK_SRC			8
+#define GCC_APPS_CLK_SRC				9
+#define GCC_APPS_AHB_CLK_SRC				10
+#define GP1_CLK_SRC					11
+#define GP2_CLK_SRC					12
+#define GP3_CLK_SRC					13
+#define SDCC1_APPS_CLK_SRC				14
+#define FEPHY_125M_DLY_CLK_SRC				15
+#define WCSS2G_CLK_SRC					16
+#define WCSS5G_CLK_SRC					17
+#define GCC_APSS_AHB_CLK				18
+#define GCC_AUDIO_AHB_CLK				19
+#define GCC_AUDIO_PWM_CLK				20
+#define GCC_BLSP1_AHB_CLK				21
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK			22
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK			23
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK			24
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK			25
+#define GCC_BLSP1_UART1_APPS_CLK			26
+#define GCC_BLSP1_UART2_APPS_CLK			27
+#define GCC_DCD_XO_CLK					28
+#define GCC_GP1_CLK					29
+#define GCC_GP2_CLK					30
+#define GCC_GP3_CLK					31
+#define GCC_BOOT_ROM_AHB_CLK				32
+#define GCC_CRYPTO_AHB_CLK				33
+#define GCC_CRYPTO_AXI_CLK				34
+#define GCC_CRYPTO_CLK					35
+#define GCC_ESS_CLK					36
+#define GCC_IMEM_AXI_CLK				37
+#define GCC_IMEM_CFG_AHB_CLK				38
+#define GCC_PCIE_AHB_CLK				39
+#define GCC_PCIE_AXI_M_CLK				40
+#define GCC_PCIE_AXI_S_CLK				41
+#define GCC_PCNOC_AHB_CLK				42
+#define GCC_PRNG_AHB_CLK				43
+#define GCC_QPIC_AHB_CLK				44
+#define GCC_QPIC_CLK					45
+#define GCC_SDCC1_AHB_CLK				46
+#define GCC_SDCC1_APPS_CLK				47
+#define GCC_SNOC_PCNOC_AHB_CLK				48
+#define GCC_SYS_NOC_125M_CLK				49
+#define GCC_SYS_NOC_AXI_CLK				50
+#define GCC_TCSR_AHB_CLK				51
+#define GCC_TLMM_AHB_CLK				52
+#define GCC_USB2_MASTER_CLK				53
+#define GCC_USB2_SLEEP_CLK				54
+#define GCC_USB2_MOCK_UTMI_CLK				55
+#define GCC_USB3_MASTER_CLK				56
+#define GCC_USB3_SLEEP_CLK				57
+#define GCC_USB3_MOCK_UTMI_CLK				58
+#define GCC_WCSS2G_CLK					59
+#define GCC_WCSS2G_REF_CLK				60
+#define GCC_WCSS2G_RTC_CLK				61
+#define GCC_WCSS5G_CLK					62
+#define GCC_WCSS5G_REF_CLK				63
+#define GCC_WCSS5G_RTC_CLK				64
+#define GCC_APSS_DDRPLL_VCO				65
+#define GCC_SDCC_PLLDIV_CLK				66
+#define GCC_FEPLL_VCO					67
+#define GCC_FEPLL125_CLK				68
+#define GCC_FEPLL125DLY_CLK				69
+#define GCC_FEPLL200_CLK				70
+#define GCC_FEPLL500_CLK				71
+#define GCC_FEPLL_WCSS2G_CLK				72
+#define GCC_FEPLL_WCSS5G_CLK				73
+#define GCC_APSS_CPU_PLLDIV_CLK				74
+#define GCC_PCNOC_AHB_CLK_SRC				75
+
+#define WIFI0_CPU_INIT_RESET				0
+#define WIFI0_RADIO_SRIF_RESET				1
+#define WIFI0_RADIO_WARM_RESET				2
+#define WIFI0_RADIO_COLD_RESET				3
+#define WIFI0_CORE_WARM_RESET				4
+#define WIFI0_CORE_COLD_RESET				5
+#define WIFI1_CPU_INIT_RESET				6
+#define WIFI1_RADIO_SRIF_RESET				7
+#define WIFI1_RADIO_WARM_RESET				8
+#define WIFI1_RADIO_COLD_RESET				9
+#define WIFI1_CORE_WARM_RESET				10
+#define WIFI1_CORE_COLD_RESET				11
+#define USB3_UNIPHY_PHY_ARES				12
+#define USB3_HSPHY_POR_ARES				13
+#define USB3_HSPHY_S_ARES				14
+#define USB2_HSPHY_POR_ARES				15
+#define USB2_HSPHY_S_ARES				16
+#define PCIE_PHY_AHB_ARES				17
+#define PCIE_AHB_ARES					18
+#define PCIE_PWR_ARES					19
+#define PCIE_PIPE_STICKY_ARES				20
+#define PCIE_AXI_M_STICKY_ARES				21
+#define PCIE_PHY_ARES					22
+#define PCIE_PARF_XPU_ARES				23
+#define PCIE_AXI_S_XPU_ARES				24
+#define PCIE_AXI_M_VMIDMT_ARES				25
+#define PCIE_PIPE_ARES					26
+#define PCIE_AXI_S_ARES					27
+#define PCIE_AXI_M_ARES					28
+#define ESS_RESET					29
+#define GCC_BLSP1_BCR					30
+#define GCC_BLSP1_QUP1_BCR				31
+#define GCC_BLSP1_UART1_BCR				32
+#define GCC_BLSP1_QUP2_BCR				33
+#define GCC_BLSP1_UART2_BCR				34
+#define GCC_BIMC_BCR					35
+#define GCC_TLMM_BCR					36
+#define GCC_IMEM_BCR					37
+#define GCC_ESS_BCR					38
+#define GCC_PRNG_BCR					39
+#define GCC_BOOT_ROM_BCR				40
+#define GCC_CRYPTO_BCR					41
+#define GCC_SDCC1_BCR					42
+#define GCC_SEC_CTRL_BCR				43
+#define GCC_AUDIO_BCR					44
+#define GCC_QPIC_BCR					45
+#define GCC_PCIE_BCR					46
+#define GCC_USB2_BCR					47
+#define GCC_USB2_PHY_BCR				48
+#define GCC_USB3_BCR					49
+#define GCC_USB3_PHY_BCR				50
+#define GCC_SYSTEM_NOC_BCR				51
+#define GCC_PCNOC_BCR					52
+#define GCC_DCD_BCR					53
+#define GCC_SNOC_BUS_TIMEOUT0_BCR			54
+#define GCC_SNOC_BUS_TIMEOUT1_BCR			55
+#define GCC_SNOC_BUS_TIMEOUT2_BCR			56
+#define GCC_SNOC_BUS_TIMEOUT3_BCR			57
+#define GCC_PCNOC_BUS_TIMEOUT0_BCR			58
+#define GCC_PCNOC_BUS_TIMEOUT1_BCR			59
+#define GCC_PCNOC_BUS_TIMEOUT2_BCR			60
+#define GCC_PCNOC_BUS_TIMEOUT3_BCR			61
+#define GCC_PCNOC_BUS_TIMEOUT4_BCR			62
+#define GCC_PCNOC_BUS_TIMEOUT5_BCR			63
+#define GCC_PCNOC_BUS_TIMEOUT6_BCR			64
+#define GCC_PCNOC_BUS_TIMEOUT7_BCR			65
+#define GCC_PCNOC_BUS_TIMEOUT8_BCR			66
+#define GCC_PCNOC_BUS_TIMEOUT9_BCR			67
+#define GCC_TCSR_BCR					68
+#define GCC_QDSS_BCR					69
+#define GCC_MPM_BCR					70
+#define GCC_SPDM_BCR					71
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,ipq4019-gcc.h b/include/dt-bindings/clock/qcom,ipq4019-gcc.h
deleted file mode 100644
index 7130e22..0000000
--- a/include/dt-bindings/clock/qcom,ipq4019-gcc.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-#ifndef __QCOM_CLK_IPQ4019_H__
-#define __QCOM_CLK_IPQ4019_H__
-
-#define GCC_DUMMY_CLK					0
-#define AUDIO_CLK_SRC					1
-#define BLSP1_QUP1_I2C_APPS_CLK_SRC			2
-#define BLSP1_QUP1_SPI_APPS_CLK_SRC			3
-#define BLSP1_QUP2_I2C_APPS_CLK_SRC			4
-#define BLSP1_QUP2_SPI_APPS_CLK_SRC			5
-#define BLSP1_UART1_APPS_CLK_SRC			6
-#define BLSP1_UART2_APPS_CLK_SRC			7
-#define GCC_USB3_MOCK_UTMI_CLK_SRC			8
-#define GCC_APPS_CLK_SRC				9
-#define GCC_APPS_AHB_CLK_SRC				10
-#define GP1_CLK_SRC					11
-#define GP2_CLK_SRC					12
-#define GP3_CLK_SRC					13
-#define SDCC1_APPS_CLK_SRC				14
-#define FEPHY_125M_DLY_CLK_SRC				15
-#define WCSS2G_CLK_SRC					16
-#define WCSS5G_CLK_SRC					17
-#define GCC_APSS_AHB_CLK				18
-#define GCC_AUDIO_AHB_CLK				19
-#define GCC_AUDIO_PWM_CLK				20
-#define GCC_BLSP1_AHB_CLK				21
-#define GCC_BLSP1_QUP1_I2C_APPS_CLK			22
-#define GCC_BLSP1_QUP1_SPI_APPS_CLK			23
-#define GCC_BLSP1_QUP2_I2C_APPS_CLK			24
-#define GCC_BLSP1_QUP2_SPI_APPS_CLK			25
-#define GCC_BLSP1_UART1_APPS_CLK			26
-#define GCC_BLSP1_UART2_APPS_CLK			27
-#define GCC_DCD_XO_CLK					28
-#define GCC_GP1_CLK					29
-#define GCC_GP2_CLK					30
-#define GCC_GP3_CLK					31
-#define GCC_BOOT_ROM_AHB_CLK				32
-#define GCC_CRYPTO_AHB_CLK				33
-#define GCC_CRYPTO_AXI_CLK				34
-#define GCC_CRYPTO_CLK					35
-#define GCC_ESS_CLK					36
-#define GCC_IMEM_AXI_CLK				37
-#define GCC_IMEM_CFG_AHB_CLK				38
-#define GCC_PCIE_AHB_CLK				39
-#define GCC_PCIE_AXI_M_CLK				40
-#define GCC_PCIE_AXI_S_CLK				41
-#define GCC_PCNOC_AHB_CLK				42
-#define GCC_PRNG_AHB_CLK				43
-#define GCC_QPIC_AHB_CLK				44
-#define GCC_QPIC_CLK					45
-#define GCC_SDCC1_AHB_CLK				46
-#define GCC_SDCC1_APPS_CLK				47
-#define GCC_SNOC_PCNOC_AHB_CLK				48
-#define GCC_SYS_NOC_125M_CLK				49
-#define GCC_SYS_NOC_AXI_CLK				50
-#define GCC_TCSR_AHB_CLK				51
-#define GCC_TLMM_AHB_CLK				52
-#define GCC_USB2_MASTER_CLK				53
-#define GCC_USB2_SLEEP_CLK				54
-#define GCC_USB2_MOCK_UTMI_CLK				55
-#define GCC_USB3_MASTER_CLK				56
-#define GCC_USB3_SLEEP_CLK				57
-#define GCC_USB3_MOCK_UTMI_CLK				58
-#define GCC_WCSS2G_CLK					59
-#define GCC_WCSS2G_REF_CLK				60
-#define GCC_WCSS2G_RTC_CLK				61
-#define GCC_WCSS5G_CLK					62
-#define GCC_WCSS5G_REF_CLK				63
-#define GCC_WCSS5G_RTC_CLK				64
-#define GCC_APSS_DDRPLL_VCO				65
-#define GCC_SDCC_PLLDIV_CLK				66
-#define GCC_FEPLL_VCO					67
-#define GCC_FEPLL125_CLK				68
-#define GCC_FEPLL125DLY_CLK				69
-#define GCC_FEPLL200_CLK				70
-#define GCC_FEPLL500_CLK				71
-#define GCC_FEPLL_WCSS2G_CLK				72
-#define GCC_FEPLL_WCSS5G_CLK				73
-#define GCC_APSS_CPU_PLLDIV_CLK				74
-#define GCC_PCNOC_AHB_CLK_SRC				75
-
-#endif
diff --git a/include/dt-bindings/reset/qcom,ipq4019-reset.h b/include/dt-bindings/reset/qcom,ipq4019-reset.h
deleted file mode 100644
index ed047d7..0000000
--- a/include/dt-bindings/reset/qcom,ipq4019-reset.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-#ifndef __QCOM_RESET_IPQ4019_H__
-#define __QCOM_RESET_IPQ4019_H__
-
-#define WIFI0_CPU_INIT_RESET				0
-#define WIFI0_RADIO_SRIF_RESET				1
-#define WIFI0_RADIO_WARM_RESET				2
-#define WIFI0_RADIO_COLD_RESET				3
-#define WIFI0_CORE_WARM_RESET				4
-#define WIFI0_CORE_COLD_RESET				5
-#define WIFI1_CPU_INIT_RESET				6
-#define WIFI1_RADIO_SRIF_RESET				7
-#define WIFI1_RADIO_WARM_RESET				8
-#define WIFI1_RADIO_COLD_RESET				9
-#define WIFI1_CORE_WARM_RESET				10
-#define WIFI1_CORE_COLD_RESET				11
-#define USB3_UNIPHY_PHY_ARES				12
-#define USB3_HSPHY_POR_ARES				13
-#define USB3_HSPHY_S_ARES				14
-#define USB2_HSPHY_POR_ARES				15
-#define USB2_HSPHY_S_ARES				16
-#define PCIE_PHY_AHB_ARES				17
-#define PCIE_AHB_ARES					18
-#define PCIE_PWR_ARES					19
-#define PCIE_PIPE_STICKY_ARES				20
-#define PCIE_AXI_M_STICKY_ARES				21
-#define PCIE_PHY_ARES					22
-#define PCIE_PARF_XPU_ARES				23
-#define PCIE_AXI_S_XPU_ARES				24
-#define PCIE_AXI_M_VMIDMT_ARES				25
-#define PCIE_PIPE_ARES					26
-#define PCIE_AXI_S_ARES					27
-#define PCIE_AXI_M_ARES					28
-#define ESS_RESET					29
-#define GCC_BLSP1_BCR					30
-#define GCC_BLSP1_QUP1_BCR				31
-#define GCC_BLSP1_UART1_BCR				32
-#define GCC_BLSP1_QUP2_BCR				33
-#define GCC_BLSP1_UART2_BCR				34
-#define GCC_BIMC_BCR					35
-#define GCC_TLMM_BCR					36
-#define GCC_IMEM_BCR					37
-#define GCC_ESS_BCR					38
-#define GCC_PRNG_BCR					39
-#define GCC_BOOT_ROM_BCR				40
-#define GCC_CRYPTO_BCR					41
-#define GCC_SDCC1_BCR					42
-#define GCC_SEC_CTRL_BCR				43
-#define GCC_AUDIO_BCR					44
-#define GCC_QPIC_BCR					45
-#define GCC_PCIE_BCR					46
-#define GCC_USB2_BCR					47
-#define GCC_USB2_PHY_BCR				48
-#define GCC_USB3_BCR					49
-#define GCC_USB3_PHY_BCR				50
-#define GCC_SYSTEM_NOC_BCR				51
-#define GCC_PCNOC_BCR					52
-#define GCC_DCD_BCR					53
-#define GCC_SNOC_BUS_TIMEOUT0_BCR			54
-#define GCC_SNOC_BUS_TIMEOUT1_BCR			55
-#define GCC_SNOC_BUS_TIMEOUT2_BCR			56
-#define GCC_SNOC_BUS_TIMEOUT3_BCR			57
-#define GCC_PCNOC_BUS_TIMEOUT0_BCR			58
-#define GCC_PCNOC_BUS_TIMEOUT1_BCR			59
-#define GCC_PCNOC_BUS_TIMEOUT2_BCR			60
-#define GCC_PCNOC_BUS_TIMEOUT3_BCR			61
-#define GCC_PCNOC_BUS_TIMEOUT4_BCR			62
-#define GCC_PCNOC_BUS_TIMEOUT5_BCR			63
-#define GCC_PCNOC_BUS_TIMEOUT6_BCR			64
-#define GCC_PCNOC_BUS_TIMEOUT7_BCR			65
-#define GCC_PCNOC_BUS_TIMEOUT8_BCR			66
-#define GCC_PCNOC_BUS_TIMEOUT9_BCR			67
-#define GCC_TCSR_BCR					68
-#define GCC_QDSS_BCR					69
-#define GCC_MPM_BCR					70
-#define GCC_SPDM_BCR					71
-
-#endif
diff --git a/test/dm/spmi.c b/test/dm/spmi.c
index 9cc284b..97bb0eb 100644
--- a/test/dm/spmi.c
+++ b/test/dm/spmi.c
@@ -81,7 +81,7 @@
 	int offset_count;
 
 	/* Get second pin of PMIC GPIO */
-	ut_assertok(gpio_lookup_name("spmi1", &dev, &offset, &gpio));
+	ut_assertok(gpio_lookup_name("pmic1", &dev, &offset, &gpio));
 
 	/* Check if PMIC is parent */
 	ut_asserteq(device_get_uclass_id(dev->parent), UCLASS_PMIC);
@@ -92,7 +92,7 @@
 	name = gpio_get_bank_info(dev, &offset_count);
 
 	/* Check bank name */
-	ut_asserteq_str("spmi", name);
+	ut_asserteq_str("pmic", name);
 	/* Check pin count */
 	ut_asserteq(4, offset_count);