[openwrt/openwrt] generic: 6.1: backport AXP PMIC support

LEDE Commits lede-commits at lists.infradead.org
Tue Mar 26 14:06:01 PDT 2024


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/85b156c11318005fe56dcfbc47adf86a947be497

commit 85b156c11318005fe56dcfbc47adf86a947be497
Author: Chukun Pan <amadeus at jmu.edu.cn>
AuthorDate: Fri Dec 8 23:10:21 2023 +0800

    generic: 6.1: backport AXP PMIC support
    
    Backport AXP15060, AXP313a and AXP192 support.
    The AXP15060 PMIC is used for starfive boards,
    and the AXP313a PMIC is used for sunxi boards.
    Remove conflicting patches from starfive target.
    
    Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 ...20x-Fix-order-of-pek-rise-and-fall-events.patch |   80 ++
 ...-axp20x-Switch-to-the-sys-off-handler-API.patch |   82 ++
 ...6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch |   28 +
 ...-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch |  343 +++++++
 ...5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch |  256 +++++
 ...or-axp20x-Add-support-for-AXP313a-variant.patch |  129 +++
 ....5-regulator-axp20x-Add-AXP15060-support.patch} |  159 +--
 ...87-v6.5-mfd-axp20x-Add-support-for-AXP192.patch |  383 ++++++++
 ...river-mfd-axp20x-Add-support-for-AXP15060.patch | 1014 --------------------
 9 files changed, 1347 insertions(+), 1127 deletions(-)

diff --git a/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch b/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch
new file mode 100644
index 0000000000..23681ba937
--- /dev/null
+++ b/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch
@@ -0,0 +1,80 @@
+From 8781ba7f45695af3ab8e8d1b55a31f527c9201a3 Mon Sep 17 00:00:00 2001
+From: Aren Moynihan <aren at peacevolution.org>
+Date: Thu, 8 Dec 2022 17:02:26 -0500
+Subject: [PATCH] mfd: axp20x: Fix order of pek rise and fall events
+
+The power button can get "stuck" if the rising edge and falling edge irq
+are read in the same pass. This can often be triggered when resuming
+from suspend if the power button is released before the kernel handles
+the interrupt.
+
+Swapping the order of the rise and fall events makes sure that the press
+event is handled first, which prevents this situation.
+
+Signed-off-by: Aren Moynihan <aren at peacevolution.org>
+Reviewed-by: Samuel Holland <samuel at sholland.org>
+Tested-by: Samuel Holland <samuel at sholland.org>
+Acked-by: Chen-Yu Tsai <wens at csie.org>
+Signed-off-by: Lee Jones <lee at kernel.org>
+Link: https://lore.kernel.org/r/20221208220225.635414-1-aren@peacevolution.org
+---
+ include/linux/mfd/axp20x.h | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/include/linux/mfd/axp20x.h
++++ b/include/linux/mfd/axp20x.h
+@@ -432,8 +432,9 @@ enum {
+ 	AXP152_IRQ_PEK_SHORT,
+ 	AXP152_IRQ_PEK_LONG,
+ 	AXP152_IRQ_TIMER,
+-	AXP152_IRQ_PEK_RIS_EDGE,
++	/* out of bit order to make sure the press event is handled first */
+ 	AXP152_IRQ_PEK_FAL_EDGE,
++	AXP152_IRQ_PEK_RIS_EDGE,
+ 	AXP152_IRQ_GPIO3_INPUT,
+ 	AXP152_IRQ_GPIO2_INPUT,
+ 	AXP152_IRQ_GPIO1_INPUT,
+@@ -472,8 +473,9 @@ enum {
+ 	AXP20X_IRQ_LOW_PWR_LVL1,
+ 	AXP20X_IRQ_LOW_PWR_LVL2,
+ 	AXP20X_IRQ_TIMER,
+-	AXP20X_IRQ_PEK_RIS_EDGE,
++	/* out of bit order to make sure the press event is handled first */
+ 	AXP20X_IRQ_PEK_FAL_EDGE,
++	AXP20X_IRQ_PEK_RIS_EDGE,
+ 	AXP20X_IRQ_GPIO3_INPUT,
+ 	AXP20X_IRQ_GPIO2_INPUT,
+ 	AXP20X_IRQ_GPIO1_INPUT,
+@@ -502,8 +504,9 @@ enum axp22x_irqs {
+ 	AXP22X_IRQ_LOW_PWR_LVL1,
+ 	AXP22X_IRQ_LOW_PWR_LVL2,
+ 	AXP22X_IRQ_TIMER,
+-	AXP22X_IRQ_PEK_RIS_EDGE,
++	/* out of bit order to make sure the press event is handled first */
+ 	AXP22X_IRQ_PEK_FAL_EDGE,
++	AXP22X_IRQ_PEK_RIS_EDGE,
+ 	AXP22X_IRQ_GPIO1_INPUT,
+ 	AXP22X_IRQ_GPIO0_INPUT,
+ };
+@@ -571,8 +574,9 @@ enum axp803_irqs {
+ 	AXP803_IRQ_LOW_PWR_LVL1,
+ 	AXP803_IRQ_LOW_PWR_LVL2,
+ 	AXP803_IRQ_TIMER,
+-	AXP803_IRQ_PEK_RIS_EDGE,
++	/* out of bit order to make sure the press event is handled first */
+ 	AXP803_IRQ_PEK_FAL_EDGE,
++	AXP803_IRQ_PEK_RIS_EDGE,
+ 	AXP803_IRQ_PEK_SHORT,
+ 	AXP803_IRQ_PEK_LONG,
+ 	AXP803_IRQ_PEK_OVER_OFF,
+@@ -623,8 +627,9 @@ enum axp809_irqs {
+ 	AXP809_IRQ_LOW_PWR_LVL1,
+ 	AXP809_IRQ_LOW_PWR_LVL2,
+ 	AXP809_IRQ_TIMER,
+-	AXP809_IRQ_PEK_RIS_EDGE,
++	/* out of bit order to make sure the press event is handled first */
+ 	AXP809_IRQ_PEK_FAL_EDGE,
++	AXP809_IRQ_PEK_RIS_EDGE,
+ 	AXP809_IRQ_PEK_SHORT,
+ 	AXP809_IRQ_PEK_LONG,
+ 	AXP809_IRQ_PEK_OVER_OFF,
diff --git a/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch b/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch
new file mode 100644
index 0000000000..b742276c8a
--- /dev/null
+++ b/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch
@@ -0,0 +1,82 @@
+From 1b1305e95e85624f538ec56db9acf88e2d3d7397 Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel at sholland.org>
+Date: Wed, 28 Dec 2022 10:27:52 -0600
+Subject: [PATCH] mfd: axp20x: Switch to the sys-off handler API
+
+This removes a layer of indirection through pm_power_off() and allows
+the PMIC handler to be used as a fallback when firmware power off fails.
+This happens on boards like the Clockwork DevTerm R-01 where OpenSBI
+does not know how to use the PMIC to power off the board.
+
+Move the check for AXP288 to avoid registering a dummy handler.
+
+Signed-off-by: Samuel Holland <samuel at sholland.org>
+[Lee: Removed superfluous new line]
+Signed-off-by: Lee Jones <lee at kernel.org>
+Link: https://lore.kernel.org/r/20221228162752.14204-1-samuel@sholland.org
+---
+ drivers/mfd/axp20x.c | 27 +++++++++++----------------
+ 1 file changed, 11 insertions(+), 16 deletions(-)
+
+--- a/drivers/mfd/axp20x.c
++++ b/drivers/mfd/axp20x.c
+@@ -23,7 +23,7 @@
+ #include <linux/mfd/core.h>
+ #include <linux/module.h>
+ #include <linux/of_device.h>
+-#include <linux/pm_runtime.h>
++#include <linux/reboot.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+ 
+@@ -832,17 +832,16 @@ static const struct mfd_cell axp813_cell
+ 	},
+ };
+ 
+-static struct axp20x_dev *axp20x_pm_power_off;
+-static void axp20x_power_off(void)
++static int axp20x_power_off(struct sys_off_data *data)
+ {
+-	if (axp20x_pm_power_off->variant == AXP288_ID)
+-		return;
++	struct axp20x_dev *axp20x = data->cb_data;
+ 
+-	regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
+-		     AXP20X_OFF);
++	regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
+ 
+ 	/* Give capacitors etc. time to drain to avoid kernel panic msg. */
+ 	mdelay(500);
++
++	return NOTIFY_DONE;
+ }
+ 
+ int axp20x_match_device(struct axp20x_dev *axp20x)
+@@ -1009,10 +1008,11 @@ int axp20x_device_probe(struct axp20x_de
+ 		return ret;
+ 	}
+ 
+-	if (!pm_power_off) {
+-		axp20x_pm_power_off = axp20x;
+-		pm_power_off = axp20x_power_off;
+-	}
++	if (axp20x->variant != AXP288_ID)
++		devm_register_sys_off_handler(axp20x->dev,
++					      SYS_OFF_MODE_POWER_OFF,
++					      SYS_OFF_PRIO_DEFAULT,
++					      axp20x_power_off, axp20x);
+ 
+ 	dev_info(axp20x->dev, "AXP20X driver loaded\n");
+ 
+@@ -1022,11 +1022,6 @@ EXPORT_SYMBOL(axp20x_device_probe);
+ 
+ void axp20x_device_remove(struct axp20x_dev *axp20x)
+ {
+-	if (axp20x == axp20x_pm_power_off) {
+-		axp20x_pm_power_off = NULL;
+-		pm_power_off = NULL;
+-	}
+-
+ 	mfd_remove_devices(axp20x->dev);
+ 	regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
+ }
diff --git a/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch b/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch
new file mode 100644
index 0000000000..b84815e1a8
--- /dev/null
+++ b/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch
@@ -0,0 +1,28 @@
+From 2405fbfb384ef39e9560d76d3f6e4c90519f90aa Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 29 Mar 2023 22:55:44 +0200
+Subject: [PATCH] mfd: axp20x: Fix axp288 writable-ranges
+
+Register AXP288_POWER_REASON is writable and needs to be written
+to reset the reset- / power-on-reason bits.
+
+Add it to the axp288 writable-ranges so that the extcon-axp288
+driver can properly clear the reset- / power-on-reason bits.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Lee Jones <lee at kernel.org>
+Link: https://lore.kernel.org/r/20230329205544.1051393-1-hdegoede@redhat.com
+---
+ drivers/mfd/axp20x.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mfd/axp20x.c
++++ b/drivers/mfd/axp20x.c
+@@ -119,6 +119,7 @@ static const struct regmap_access_table
+ 
+ /* AXP288 ranges are shared with the AXP803, as they cover the same range */
+ static const struct regmap_range axp288_writeable_ranges[] = {
++	regmap_reg_range(AXP288_POWER_REASON, AXP288_POWER_REASON),
+ 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
+ 	regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
+ };
diff --git a/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch b/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch
new file mode 100644
index 0000000000..83ef60aecd
--- /dev/null
+++ b/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch
@@ -0,0 +1,343 @@
+From e0f8ad2a705367518b5c56bf9d6da89681467c02 Mon Sep 17 00:00:00 2001
+From: Shengyu Qu <wiagn233 at outlook.com>
+Date: Fri, 21 Apr 2023 23:08:15 +0800
+Subject: [PATCH] mfd: axp20x: Add support for AXP15060 PMIC
+
+The AXP15060 is a PMIC chip produced by X-Powers, and could be connected
+via an I2C bus.
+
+Describe the regmap and the MFD bits, along with the registers exposed
+via I2C. Eventually advertise the device using a new compatible string
+and add support for power off the system.
+
+The driver would disable PEK function if IRQ is not configured in device
+tree, since some boards (For example, Starfive Visionfive 2) didn't
+connect IRQ line of PMIC to SOC.
+
+GPIO function isn't enabled in this commit, since its configuration
+operation is different from any existing AXP PMICs and needs
+logic modification on existing driver. GPIO support might come in later
+patches.
+
+Signed-off-by: Shengyu Qu <wiagn233 at outlook.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
+Signed-off-by: Lee Jones <lee at kernel.org>
+Link: https://lore.kernel.org/r/TY3P286MB261162D57695AC8164ED50E298609@TY3P286MB2611.JPNP286.PROD.OUTLOOK.COM
+---
+ drivers/mfd/axp20x-i2c.c   |   2 +
+ drivers/mfd/axp20x.c       | 107 +++++++++++++++++++++++++++++++++++++
+ include/linux/mfd/axp20x.h |  85 +++++++++++++++++++++++++++++
+ 3 files changed, 194 insertions(+)
+
+--- a/drivers/mfd/axp20x-i2c.c
++++ b/drivers/mfd/axp20x-i2c.c
+@@ -66,6 +66,7 @@ static const struct of_device_id axp20x_
+ 	{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
+ 	{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
+ 	{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
++	{ .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
+ 	{ },
+ };
+ MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
+@@ -79,6 +80,7 @@ static const struct i2c_device_id axp20x
+ 	{ "axp223", 0 },
+ 	{ "axp803", 0 },
+ 	{ "axp806", 0 },
++	{ "axp15060", 0 },
+ 	{ },
+ };
+ MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
+--- a/drivers/mfd/axp20x.c
++++ b/drivers/mfd/axp20x.c
+@@ -43,6 +43,7 @@ static const char * const axp20x_model_n
+ 	"AXP806",
+ 	"AXP809",
+ 	"AXP813",
++	"AXP15060",
+ };
+ 
+ static const struct regmap_range axp152_writeable_ranges[] = {
+@@ -169,6 +170,31 @@ static const struct regmap_access_table
+ 	.n_yes_ranges	= ARRAY_SIZE(axp806_volatile_ranges),
+ };
+ 
++static const struct regmap_range axp15060_writeable_ranges[] = {
++	regmap_reg_range(AXP15060_PWR_OUT_CTRL1, AXP15060_DCDC_MODE_CTRL2),
++	regmap_reg_range(AXP15060_OUTPUT_MONITOR_DISCHARGE, AXP15060_CPUSLDO_V_CTRL),
++	regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
++	regmap_reg_range(AXP15060_PEK_KEY, AXP15060_PEK_KEY),
++	regmap_reg_range(AXP15060_IRQ1_EN, AXP15060_IRQ2_EN),
++	regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
++};
++
++static const struct regmap_range axp15060_volatile_ranges[] = {
++	regmap_reg_range(AXP15060_STARTUP_SRC, AXP15060_STARTUP_SRC),
++	regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
++	regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
++};
++
++static const struct regmap_access_table axp15060_writeable_table = {
++	.yes_ranges	= axp15060_writeable_ranges,
++	.n_yes_ranges	= ARRAY_SIZE(axp15060_writeable_ranges),
++};
++
++static const struct regmap_access_table axp15060_volatile_table = {
++	.yes_ranges	= axp15060_volatile_ranges,
++	.n_yes_ranges	= ARRAY_SIZE(axp15060_volatile_ranges),
++};
++
+ static const struct resource axp152_pek_resources[] = {
+ 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
+ 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
+@@ -237,6 +263,11 @@ static const struct resource axp809_pek_
+ 	DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
+ };
+ 
++static const struct resource axp15060_pek_resources[] = {
++	DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
++	DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
++};
++
+ static const struct regmap_config axp152_regmap_config = {
+ 	.reg_bits	= 8,
+ 	.val_bits	= 8,
+@@ -282,6 +313,15 @@ static const struct regmap_config axp806
+ 	.cache_type	= REGCACHE_RBTREE,
+ };
+ 
++static const struct regmap_config axp15060_regmap_config = {
++	.reg_bits	= 8,
++	.val_bits	= 8,
++	.wr_table	= &axp15060_writeable_table,
++	.volatile_table	= &axp15060_volatile_table,
++	.max_register	= AXP15060_IRQ2_STATE,
++	.cache_type	= REGCACHE_RBTREE,
++};
++
+ #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask)			\
+ 	[_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
+ 
+@@ -503,6 +543,23 @@ static const struct regmap_irq axp809_re
+ 	INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT,		4, 0),
+ };
+ 
++static const struct regmap_irq axp15060_regmap_irqs[] = {
++	INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV1,	0, 0),
++	INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV2,	0, 1),
++	INIT_REGMAP_IRQ(AXP15060, DCDC1_V_LOW,		0, 2),
++	INIT_REGMAP_IRQ(AXP15060, DCDC2_V_LOW,		0, 3),
++	INIT_REGMAP_IRQ(AXP15060, DCDC3_V_LOW,		0, 4),
++	INIT_REGMAP_IRQ(AXP15060, DCDC4_V_LOW,		0, 5),
++	INIT_REGMAP_IRQ(AXP15060, DCDC5_V_LOW,		0, 6),
++	INIT_REGMAP_IRQ(AXP15060, DCDC6_V_LOW,		0, 7),
++	INIT_REGMAP_IRQ(AXP15060, PEK_LONG,			1, 0),
++	INIT_REGMAP_IRQ(AXP15060, PEK_SHORT,			1, 1),
++	INIT_REGMAP_IRQ(AXP15060, GPIO1_INPUT,		1, 2),
++	INIT_REGMAP_IRQ(AXP15060, PEK_FAL_EDGE,			1, 3),
++	INIT_REGMAP_IRQ(AXP15060, PEK_RIS_EDGE,			1, 4),
++	INIT_REGMAP_IRQ(AXP15060, GPIO2_INPUT,		1, 5),
++};
++
+ static const struct regmap_irq_chip axp152_regmap_irq_chip = {
+ 	.name			= "axp152_irq_chip",
+ 	.status_base		= AXP152_IRQ1_STATE,
+@@ -589,6 +646,17 @@ static const struct regmap_irq_chip axp8
+ 	.num_regs		= 5,
+ };
+ 
++static const struct regmap_irq_chip axp15060_regmap_irq_chip = {
++	.name			= "axp15060",
++	.status_base		= AXP15060_IRQ1_STATE,
++	.ack_base		= AXP15060_IRQ1_STATE,
++	.unmask_base		= AXP15060_IRQ1_EN,
++	.init_ack_masked	= true,
++	.irqs			= axp15060_regmap_irqs,
++	.num_irqs		= ARRAY_SIZE(axp15060_regmap_irqs),
++	.num_regs		= 2,
++};
++
+ static const struct mfd_cell axp20x_cells[] = {
+ 	{
+ 		.name		= "axp20x-gpio",
+@@ -833,6 +901,23 @@ static const struct mfd_cell axp813_cell
+ 	},
+ };
+ 
++static const struct mfd_cell axp15060_cells[] = {
++	{
++		.name		= "axp221-pek",
++		.num_resources	= ARRAY_SIZE(axp15060_pek_resources),
++		.resources	= axp15060_pek_resources,
++	}, {
++		.name		= "axp20x-regulator",
++	},
++};
++
++/* For boards that don't have IRQ line connected to SOC. */
++static const struct mfd_cell axp_regulator_only_cells[] = {
++	{
++		.name		= "axp20x-regulator",
++	},
++};
++
+ static int axp20x_power_off(struct sys_off_data *data)
+ {
+ 	struct axp20x_dev *axp20x = data->cb_data;
+@@ -942,6 +1027,28 @@ int axp20x_match_device(struct axp20x_de
+ 		 */
+ 		axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
+ 		break;
++	case AXP15060_ID:
++		/*
++		 * Don't register the power key part if there is no interrupt
++		 * line.
++		 *
++		 * Since most use cases of AXP PMICs are Allwinner SOCs, board
++		 * designers follow Allwinner's reference design and connects
++		 * IRQ line to SOC, there's no need for those variants to deal
++		 * with cases that IRQ isn't connected. However, AXP15660 is
++		 * used by some other vendors' SOCs that didn't connect IRQ
++		 * line, we need to deal with this case.
++		 */
++		if (axp20x->irq > 0) {
++			axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
++			axp20x->cells = axp15060_cells;
++		} else {
++			axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
++			axp20x->cells = axp_regulator_only_cells;
++		}
++		axp20x->regmap_cfg = &axp15060_regmap_config;
++		axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip;
++		break;
+ 	default:
+ 		dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
+ 		return -EINVAL;
+--- a/include/linux/mfd/axp20x.h
++++ b/include/linux/mfd/axp20x.h
+@@ -21,6 +21,7 @@ enum axp20x_variants {
+ 	AXP806_ID,
+ 	AXP809_ID,
+ 	AXP813_ID,
++	AXP15060_ID,
+ 	NR_AXP20X_VARIANTS,
+ };
+ 
+@@ -131,6 +132,39 @@ enum axp20x_variants {
+ /* Other DCDC regulator control registers are the same as AXP803 */
+ #define AXP813_DCDC7_V_OUT		0x26
+ 
++#define AXP15060_STARTUP_SRC		0x00
++#define AXP15060_PWR_OUT_CTRL1		0x10
++#define AXP15060_PWR_OUT_CTRL2		0x11
++#define AXP15060_PWR_OUT_CTRL3		0x12
++#define AXP15060_DCDC1_V_CTRL		0x13
++#define AXP15060_DCDC2_V_CTRL		0x14
++#define AXP15060_DCDC3_V_CTRL		0x15
++#define AXP15060_DCDC4_V_CTRL		0x16
++#define AXP15060_DCDC5_V_CTRL		0x17
++#define AXP15060_DCDC6_V_CTRL		0x18
++#define AXP15060_ALDO1_V_CTRL		0x19
++#define AXP15060_DCDC_MODE_CTRL1		0x1a
++#define AXP15060_DCDC_MODE_CTRL2		0x1b
++#define AXP15060_OUTPUT_MONITOR_DISCHARGE		0x1e
++#define AXP15060_IRQ_PWROK_VOFF		0x1f
++#define AXP15060_ALDO2_V_CTRL		0x20
++#define AXP15060_ALDO3_V_CTRL		0x21
++#define AXP15060_ALDO4_V_CTRL		0x22
++#define AXP15060_ALDO5_V_CTRL		0x23
++#define AXP15060_BLDO1_V_CTRL		0x24
++#define AXP15060_BLDO2_V_CTRL		0x25
++#define AXP15060_BLDO3_V_CTRL		0x26
++#define AXP15060_BLDO4_V_CTRL		0x27
++#define AXP15060_BLDO5_V_CTRL		0x28
++#define AXP15060_CLDO1_V_CTRL		0x29
++#define AXP15060_CLDO2_V_CTRL		0x2a
++#define AXP15060_CLDO3_V_CTRL		0x2b
++#define AXP15060_CLDO4_V_CTRL		0x2d
++#define AXP15060_CPUSLDO_V_CTRL		0x2e
++#define AXP15060_PWR_WAKEUP_CTRL		0x31
++#define AXP15060_PWR_DISABLE_DOWN_SEQ		0x32
++#define AXP15060_PEK_KEY		0x36
++
+ /* Interrupt */
+ #define AXP152_IRQ1_EN			0x40
+ #define AXP152_IRQ2_EN			0x41
+@@ -152,6 +186,11 @@ enum axp20x_variants {
+ #define AXP20X_IRQ5_STATE		0x4c
+ #define AXP20X_IRQ6_STATE		0x4d
+ 
++#define AXP15060_IRQ1_EN		0x40
++#define AXP15060_IRQ2_EN		0x41
++#define AXP15060_IRQ1_STATE		0x48
++#define AXP15060_IRQ2_STATE		0x49
++
+ /* ADC */
+ #define AXP20X_ACIN_V_ADC_H		0x56
+ #define AXP20X_ACIN_V_ADC_L		0x57
+@@ -222,6 +261,8 @@ enum axp20x_variants {
+ #define AXP22X_GPIO_STATE		0x94
+ #define AXP22X_GPIO_PULL_DOWN		0x95
+ 
++#define AXP15060_CLDO4_GPIO2_MODESET		0x2c
++
+ /* Battery */
+ #define AXP20X_CHRG_CC_31_24		0xb0
+ #define AXP20X_CHRG_CC_23_16		0xb1
+@@ -419,6 +460,33 @@ enum {
+ 	AXP813_REG_ID_MAX,
+ };
+ 
++enum {
++	AXP15060_DCDC1 = 0,
++	AXP15060_DCDC2,
++	AXP15060_DCDC3,
++	AXP15060_DCDC4,
++	AXP15060_DCDC5,
++	AXP15060_DCDC6,
++	AXP15060_ALDO1,
++	AXP15060_ALDO2,
++	AXP15060_ALDO3,
++	AXP15060_ALDO4,
++	AXP15060_ALDO5,
++	AXP15060_BLDO1,
++	AXP15060_BLDO2,
++	AXP15060_BLDO3,
++	AXP15060_BLDO4,
++	AXP15060_BLDO5,
++	AXP15060_CLDO1,
++	AXP15060_CLDO2,
++	AXP15060_CLDO3,
++	AXP15060_CLDO4,
++	AXP15060_CPUSLDO,
++	AXP15060_SW,
++	AXP15060_RTC_LDO,
++	AXP15060_REG_ID_MAX,
++};
++
+ /* IRQs */
+ enum {
+ 	AXP152_IRQ_LDO0IN_CONNECT = 1,
+@@ -637,6 +705,23 @@ enum axp809_irqs {
+ 	AXP809_IRQ_GPIO0_INPUT,
+ };
+ 
++enum axp15060_irqs {
++	AXP15060_IRQ_DIE_TEMP_HIGH_LV1 = 1,
++	AXP15060_IRQ_DIE_TEMP_HIGH_LV2,
++	AXP15060_IRQ_DCDC1_V_LOW,
++	AXP15060_IRQ_DCDC2_V_LOW,
++	AXP15060_IRQ_DCDC3_V_LOW,
++	AXP15060_IRQ_DCDC4_V_LOW,
++	AXP15060_IRQ_DCDC5_V_LOW,
++	AXP15060_IRQ_DCDC6_V_LOW,
++	AXP15060_IRQ_PEK_LONG,
++	AXP15060_IRQ_PEK_SHORT,
++	AXP15060_IRQ_GPIO1_INPUT,
++	AXP15060_IRQ_PEK_FAL_EDGE,
++	AXP15060_IRQ_PEK_RIS_EDGE,
++	AXP15060_IRQ_GPIO2_INPUT,
++};
++
+ struct axp20x_dev {
+ 	struct device			*dev;
+ 	int				irq;
diff --git a/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch b/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch
new file mode 100644
index 0000000000..c9470eacec
--- /dev/null
+++ b/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch
@@ -0,0 +1,256 @@
+From 75c8cb2f4cb218aaf4ea68cab08d6dbc96eeae15 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka at somainline.org>
+Date: Wed, 24 May 2023 01:00:10 +0100
+Subject: [PATCH] mfd: axp20x: Add support for AXP313a PMIC
+
+The AXP313a is a PMIC chip produced by X-Powers, it can be connected via
+an I2C bus.
+The name AXP1530 seems to appear as well, and this is what is used in
+the BSP driver. From all we know it's the same chip, just a different
+name. However we have only seen AXP313a chips in the wild, so go with
+this name.
+
+Compared to the other AXP PMICs it's a rather simple affair: just three
+DCDC converters, three LDOs, and no battery charging support.
+
+Describe the regmap and the MFD bits, along with the registers exposed
+via I2C. Aside from the various regulators, also describe the power key
+interrupts, and adjust the shutdown handler routine to use a different
+register than the other PMICs.
+Eventually advertise the device using the new compatible string.
+
+Signed-off-by: Martin Botka <martin.botka at somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara at arm.com>
+Reviewed-by: Chen-Yu Tsai <wens at csie.org>
+Link: https://lore.kernel.org/r/20230524000012.15028-2-andre.przywara@arm.com
+Signed-off-by: Lee Jones <lee at kernel.org>
+---
+ drivers/mfd/axp20x-i2c.c   |  2 +
+ drivers/mfd/axp20x.c       | 78 +++++++++++++++++++++++++++++++++++++-
+ include/linux/mfd/axp20x.h | 32 ++++++++++++++++
+ 3 files changed, 111 insertions(+), 1 deletion(-)
+
+--- a/drivers/mfd/axp20x-i2c.c
++++ b/drivers/mfd/axp20x-i2c.c
+@@ -64,6 +64,7 @@ static const struct of_device_id axp20x_
+ 	{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
+ 	{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
+ 	{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
++	{ .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID },
+ 	{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
+ 	{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
+ 	{ .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
+@@ -78,6 +79,7 @@ static const struct i2c_device_id axp20x
+ 	{ "axp209", 0 },
+ 	{ "axp221", 0 },
+ 	{ "axp223", 0 },
++	{ "axp313a", 0 },
+ 	{ "axp803", 0 },
+ 	{ "axp806", 0 },
+ 	{ "axp15060", 0 },
+--- a/drivers/mfd/axp20x.c
++++ b/drivers/mfd/axp20x.c
+@@ -39,6 +39,7 @@ static const char * const axp20x_model_n
+ 	"AXP221",
+ 	"AXP223",
+ 	"AXP288",
++	"AXP313a",
+ 	"AXP803",
+ 	"AXP806",
+ 	"AXP809",
+@@ -156,6 +157,25 @@ static const struct regmap_range axp806_
+ 	regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
+ };
+ 
++static const struct regmap_range axp313a_writeable_ranges[] = {
++	regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
++};
++
++static const struct regmap_range axp313a_volatile_ranges[] = {
++	regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
++	regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
++};
++
++static const struct regmap_access_table axp313a_writeable_table = {
++	.yes_ranges = axp313a_writeable_ranges,
++	.n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
++};
++
++static const struct regmap_access_table axp313a_volatile_table = {
++	.yes_ranges = axp313a_volatile_ranges,
++	.n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
++};
++
+ static const struct regmap_range axp806_volatile_ranges[] = {
+ 	regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
+ };
+@@ -248,6 +268,11 @@ static const struct resource axp288_fuel
+ 	DEFINE_RES_IRQ(AXP288_IRQ_WL1),
+ };
+ 
++static const struct resource axp313a_pek_resources[] = {
++	DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
++	DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
++};
++
+ static const struct resource axp803_pek_resources[] = {
+ 	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
+ 	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
+@@ -304,6 +329,15 @@ static const struct regmap_config axp288
+ 	.cache_type	= REGCACHE_RBTREE,
+ };
+ 
++static const struct regmap_config axp313a_regmap_config = {
++	.reg_bits = 8,
++	.val_bits = 8,
++	.wr_table = &axp313a_writeable_table,
++	.volatile_table = &axp313a_volatile_table,
++	.max_register = AXP313A_IRQ_STATE,
++	.cache_type = REGCACHE_RBTREE,
++};
++
+ static const struct regmap_config axp806_regmap_config = {
+ 	.reg_bits	= 8,
+ 	.val_bits	= 8,
+@@ -456,6 +490,16 @@ static const struct regmap_irq axp288_re
+ 	INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG,            5, 1),
+ };
+ 
++static const struct regmap_irq axp313a_regmap_irqs[] = {
++	INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE,		0, 7),
++	INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE,		0, 6),
++	INIT_REGMAP_IRQ(AXP313A, PEK_SHORT,		0, 5),
++	INIT_REGMAP_IRQ(AXP313A, PEK_LONG,		0, 4),
++	INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW,		0, 3),
++	INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW,		0, 2),
++	INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH,		0, 0),
++};
++
+ static const struct regmap_irq axp803_regmap_irqs[] = {
+ 	INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V,		0, 7),
+ 	INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN,		0, 6),
+@@ -610,6 +654,17 @@ static const struct regmap_irq_chip axp2
+ 
+ };
+ 
++static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
++	.name			= "axp313a_irq_chip",
++	.status_base		= AXP313A_IRQ_STATE,
++	.ack_base		= AXP313A_IRQ_STATE,
++	.unmask_base		= AXP313A_IRQ_EN,
++	.init_ack_masked	= true,
++	.irqs			= axp313a_regmap_irqs,
++	.num_irqs		= ARRAY_SIZE(axp313a_regmap_irqs),
++	.num_regs		= 1,
++};
++
+ static const struct regmap_irq_chip axp803_regmap_irq_chip = {
+ 	.name			= "axp803",
+ 	.status_base		= AXP20X_IRQ1_STATE,
+@@ -752,6 +807,11 @@ static const struct mfd_cell axp152_cell
+ 	},
+ };
+ 
++static struct mfd_cell axp313a_cells[] = {
++	MFD_CELL_NAME("axp20x-regulator"),
++	MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
++};
++
+ static const struct resource axp288_adc_resources[] = {
+ 	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
+ };
+@@ -921,8 +981,18 @@ static const struct mfd_cell axp_regulat
+ static int axp20x_power_off(struct sys_off_data *data)
+ {
+ 	struct axp20x_dev *axp20x = data->cb_data;
++	unsigned int shutdown_reg;
+ 
+-	regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
++	switch (axp20x->variant) {
++	case AXP313A_ID:
++		shutdown_reg = AXP313A_SHUTDOWN_CTRL;
++		break;
++	default:
++		shutdown_reg = AXP20X_OFF_CTRL;
++		break;
++	}
++
++	regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
+ 
+ 	/* Give capacitors etc. time to drain to avoid kernel panic msg. */
+ 	mdelay(500);
+@@ -985,6 +1055,12 @@ int axp20x_match_device(struct axp20x_de
+ 		axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
+ 		axp20x->irq_flags = IRQF_TRIGGER_LOW;
+ 		break;
++	case AXP313A_ID:
++		axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
++		axp20x->cells = axp313a_cells;
++		axp20x->regmap_cfg = &axp313a_regmap_config;
++		axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
++		break;
+ 	case AXP803_ID:
+ 		axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
+ 		axp20x->cells = axp803_cells;
+--- a/include/linux/mfd/axp20x.h
++++ b/include/linux/mfd/axp20x.h
+@@ -17,6 +17,7 @@ enum axp20x_variants {
+ 	AXP221_ID,
+ 	AXP223_ID,
+ 	AXP288_ID,
++	AXP313A_ID,
+ 	AXP803_ID,
+ 	AXP806_ID,
+ 	AXP809_ID,
+@@ -92,6 +93,17 @@ enum axp20x_variants {
+ #define AXP22X_ALDO3_V_OUT		0x2a
+ #define AXP22X_CHRG_CTRL3		0x35
+ 
++#define AXP313A_ON_INDICATE		0x00
++#define AXP313A_OUTPUT_CONTROL		0x10
++#define AXP313A_DCDC1_CONRTOL		0x13
++#define AXP313A_DCDC2_CONRTOL		0x14
++#define AXP313A_DCDC3_CONRTOL		0x15
++#define AXP313A_ALDO1_CONRTOL		0x16
++#define AXP313A_DLDO1_CONRTOL		0x17
++#define AXP313A_SHUTDOWN_CTRL		0x1a
++#define AXP313A_IRQ_EN			0x20
++#define AXP313A_IRQ_STATE		0x21
++
+ #define AXP806_STARTUP_SRC		0x00
+ #define AXP806_CHIP_ID			0x03
+ #define AXP806_PWR_OUT_CTRL1		0x10
+@@ -364,6 +376,16 @@ enum {
+ };
+ 
+ enum {
++	AXP313A_DCDC1 = 0,
++	AXP313A_DCDC2,
++	AXP313A_DCDC3,
++	AXP313A_ALDO1,
++	AXP313A_DLDO1,
++	AXP313A_RTC_LDO,
++	AXP313A_REG_ID_MAX,
++};
++
++enum {
+ 	AXP806_DCDCA = 0,
+ 	AXP806_DCDCB,
+ 	AXP806_DCDCC,
+@@ -616,6 +638,16 @@ enum axp288_irqs {
+ 	AXP288_IRQ_BC_USB_CHNG,
+ };
+ 
++enum axp313a_irqs {
++	AXP313A_IRQ_DIE_TEMP_HIGH,
++	AXP313A_IRQ_DCDC2_V_LOW = 2,
++	AXP313A_IRQ_DCDC3_V_LOW,
++	AXP313A_IRQ_PEK_LONG,
++	AXP313A_IRQ_PEK_SHORT,
++	AXP313A_IRQ_PEK_FAL_EDGE,
++	AXP313A_IRQ_PEK_RIS_EDGE,
++};
++
+ enum axp803_irqs {
+ 	AXP803_IRQ_ACIN_OVER_V = 1,
+ 	AXP803_IRQ_ACIN_PLUGIN,
diff --git a/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch b/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch
new file mode 100644
index 0000000000..91f1b39824
--- /dev/null
+++ b/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch
@@ -0,0 +1,129 @@
+From 60fd7eb89670d2636ac3156881acbd103c6eba6a Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka at somainline.org>
+Date: Wed, 24 May 2023 01:00:11 +0100
+Subject: [PATCH] regulator: axp20x: Add support for AXP313a variant
+
+The AXP313a is your typical I2C controlled PMIC, although in a lighter
+fashion compared to the other X-Powers PMICs: it has only three DCDC
+rails, three LDOs, and no battery charging support.
+
+The AXP313a datasheet does not describe a register to change the DCDC
+switching frequency, and talks of it being fixed at 3 MHz. Check that
+the property allowing to change that frequency is absent from the DT,
+and bail out otherwise.
+
+The third LDO, RTCLDO, is fixed, and cannot even be turned on or off,
+programmatically. On top of that, its voltage is customisable (either
+1.8V or 3.3V), which we cannot describe easily using the existing
+regulator wrapper functions. This should be fixed properly, using
+regulator-{min,max}-microvolt in the DT, but this requires more changes
+to the code. As some other PMICs (AXP2xx, AXP803) seem to paper over the
+same problem as well, we follow suit here and pretend it's a fixed 1.8V
+regulator. A proper fix can follow later. The BSP code seems to ignore
+this regulator altogether.
+
+Describe the AXP313A's voltage settings and switch registers, how the
+voltages are encoded, and connect this to the MFD device via its
+regulator ID.
+
+Signed-off-by: Martin Botka <martin.botka at somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara at arm.com>
+Reviewed-by: Chen-Yu Tsai <wens at csie.org>
+Reviewed-by: Mark Brown <broonie at kernel.org>
+Tested-by: Shengyu Qu <wiagn233 at outlook.com>
+Link: https://lore.kernel.org/r/20230524000012.15028-3-andre.przywara@arm.com
+Signed-off-by: Mark Brown <broonie at kernel.org>
+---
+ drivers/regulator/axp20x-regulator.c | 60 ++++++++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+--- a/drivers/regulator/axp20x-regulator.c
++++ b/drivers/regulator/axp20x-regulator.c
+@@ -134,6 +134,11 @@
+ #define AXP22X_PWR_OUT_DLDO4_MASK	BIT_MASK(6)
+ #define AXP22X_PWR_OUT_ALDO3_MASK	BIT_MASK(7)
+ 
++#define AXP313A_DCDC1_NUM_VOLTAGES	107
++#define AXP313A_DCDC23_NUM_VOLTAGES	88
++#define AXP313A_DCDC_V_OUT_MASK		GENMASK(6, 0)
++#define AXP313A_LDO_V_OUT_MASK		GENMASK(4, 0)
++
+ #define AXP803_PWR_OUT_DCDC1_MASK	BIT_MASK(0)
+ #define AXP803_PWR_OUT_DCDC2_MASK	BIT_MASK(1)
+ #define AXP803_PWR_OUT_DCDC3_MASK	BIT_MASK(2)
+@@ -638,6 +643,48 @@ static const struct regulator_desc axp22
+ 	.ops		= &axp20x_ops_sw,
+ };
+ 
++static const struct linear_range axp313a_dcdc1_ranges[] = {
++	REGULATOR_LINEAR_RANGE(500000,   0,  70,  10000),
++	REGULATOR_LINEAR_RANGE(1220000, 71,  87,  20000),
++	REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
++};
++
++static const struct linear_range axp313a_dcdc2_ranges[] = {
++	REGULATOR_LINEAR_RANGE(500000,   0, 70, 10000),
++	REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
++};
++
++/*
++ * This is deviating from the datasheet. The values here are taken from the
++ * BSP driver and have been confirmed by measurements.
++ */
++static const struct linear_range axp313a_dcdc3_ranges[] = {
++	REGULATOR_LINEAR_RANGE(500000,   0,  70, 10000),
++	REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
++};
++
++static const struct regulator_desc axp313a_regulators[] = {
++	AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
++			axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
++			AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
++			AXP313A_OUTPUT_CONTROL, BIT(0)),
++	AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
++			axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
++			AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
++			AXP313A_OUTPUT_CONTROL, BIT(1)),
++	AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
++			axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
++			AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
++			AXP313A_OUTPUT_CONTROL, BIT(2)),
++	AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
++		 AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
++		 AXP313A_OUTPUT_CONTROL, BIT(3)),
++	AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
++		 AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
++		 AXP313A_OUTPUT_CONTROL, BIT(4)),
++	AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
++};
++
+ /* DCDC ranges shared with AXP813 */
+ static const struct linear_range axp803_dcdc234_ranges[] = {
+ 	REGULATOR_LINEAR_RANGE(500000,
+@@ -1040,6 +1087,15 @@ static int axp20x_set_dcdc_freq(struct p
+ 		def = 3000;
+ 		step = 150;
+ 		break;
++	case AXP313A_ID:
++		/* The DCDC PWM frequency seems to be fixed to 3 MHz. */
++		if (dcdcfreq != 0) {
++			dev_err(&pdev->dev,
++				"DCDC frequency on AXP313a is fixed to 3 MHz.\n");
++			return -EINVAL;
++		}
++
++		return 0;
+ 	default:
+ 		dev_err(&pdev->dev,
+ 			"Setting DCDC frequency for unsupported AXP variant\n");
+@@ -1232,6 +1288,10 @@ static int axp20x_regulator_probe(struct
+ 		drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
+ 						  "x-powers,drive-vbus-en");
+ 		break;
++	case AXP313A_ID:
++		regulators = axp313a_regulators;
++		nregulators = AXP313A_REG_ID_MAX;
++		break;
+ 	case AXP803_ID:
+ 		regulators = axp803_regulators;
+ 		nregulators = AXP803_REG_ID_MAX;
diff --git a/target/linux/starfive/patches-6.1/0118-driver-regulator-axp20x-Support-AXP15060-variant.patch b/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch
similarity index 74%
rename from target/linux/starfive/patches-6.1/0118-driver-regulator-axp20x-Support-AXP15060-variant.patch
rename to target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch
index ccb277b3a0..6af09204af 100644
--- a/target/linux/starfive/patches-6.1/0118-driver-regulator-axp20x-Support-AXP15060-variant.patch
+++ b/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch
@@ -1,30 +1,35 @@
-From 1b017f3376a5df4a2cd5a120c16723e777fc9a36 Mon Sep 17 00:00:00 2001
-From: "ziv.xu" <ziv.xu at starfive.com>
-Date: Fri, 4 Aug 2023 13:55:23 +0800
-Subject: [PATCH 118/122] driver: regulator: axp20x: Support AXP15060 variant.
+From 9e72869d0fe12aba8cd489e485d93912b3f5c248 Mon Sep 17 00:00:00 2001
+From: Shengyu Qu <wiagn233 at outlook.com>
+Date: Wed, 24 May 2023 01:00:12 +0100
+Subject: [PATCH] regulator: axp20x: Add AXP15060 support
 
-Add axp15060 variant support to axp20x
+The AXP15060 is a typical I2C-controlled PMIC, seen on multiple boards
+with different default register value. Current driver is tested on
+Starfive Visionfive 2.
 
-Signed-off-by: ziv.xu <ziv.xu at starfive.com>
+The RTCLDO is fixed, and cannot even be turned on or off. On top of
+that, its voltage is customisable (either 1.8V or 3.3V). We pretend it's
+a fixed 1.8V regulator since other AXP driver also do like this. Also,
+BSP code ignores this regulator and it's not used according to VF2
+schematic.
+
+Describe the AXP15060's voltage settings and switch registers, how the
+voltages are encoded, and connect this to the MFD device via its
+regulator ID.
+
+Signed-off-by: Shengyu Qu <wiagn233 at outlook.com>
+Signed-off-by: Andre Przywara <andre.przywara at arm.com>
+Reviewed-by: Mark Brown <broonie at kernel.org>
+Tested-by: Shengyu Qu <wiagn233 at outlook.com>
+Link: https://lore.kernel.org/r/20230524000012.15028-4-andre.przywara@arm.com
+Signed-off-by: Mark Brown <broonie at kernel.org>
 ---
- drivers/regulator/axp20x-regulator.c | 291 ++++++++++++++++++++++++++-
- 1 file changed, 283 insertions(+), 8 deletions(-)
+ drivers/regulator/axp20x-regulator.c | 232 +++++++++++++++++++++++++--
+ 1 file changed, 223 insertions(+), 9 deletions(-)
 
 --- a/drivers/regulator/axp20x-regulator.c
 +++ b/drivers/regulator/axp20x-regulator.c
-@@ -134,6 +134,11 @@
- #define AXP22X_PWR_OUT_DLDO4_MASK	BIT_MASK(6)
- #define AXP22X_PWR_OUT_ALDO3_MASK	BIT_MASK(7)
- 
-+#define AXP313A_DCDC1_NUM_VOLTAGES	107
-+#define AXP313A_DCDC23_NUM_VOLTAGES	88
-+#define AXP313A_DCDC_V_OUT_MASK		GENMASK(6, 0)
-+#define AXP313A_LDO_V_OUT_MASK		GENMASK(4, 0)
-+
- #define AXP803_PWR_OUT_DCDC1_MASK	BIT_MASK(0)
- #define AXP803_PWR_OUT_DCDC2_MASK	BIT_MASK(1)
- #define AXP803_PWR_OUT_DCDC3_MASK	BIT_MASK(2)
-@@ -270,6 +275,74 @@
+@@ -275,6 +275,74 @@
  
  #define AXP813_PWR_OUT_DCDC7_MASK	BIT_MASK(6)
  
@@ -99,56 +104,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  #define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg,	\
  		    _vmask, _ereg, _emask, _enable_val, _disable_val)		\
  	[_family##_##_id] = {							\
-@@ -638,6 +711,48 @@ static const struct regulator_desc axp22
- 	.ops		= &axp20x_ops_sw,
- };
- 
-+static const struct linear_range axp313a_dcdc1_ranges[] = {
-+	REGULATOR_LINEAR_RANGE(500000,   0,  70,  10000),
-+	REGULATOR_LINEAR_RANGE(1220000, 71,  87,  20000),
-+	REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
-+};
-+
-+static const struct linear_range axp313a_dcdc2_ranges[] = {
-+	REGULATOR_LINEAR_RANGE(500000,   0, 70, 10000),
-+	REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
-+};
-+
-+/*
-+ * This is deviating from the datasheet. The values here are taken from the
-+ * BSP driver and have been confirmed by measurements.
-+ */
-+static const struct linear_range axp313a_dcdc3_ranges[] = {
-+	REGULATOR_LINEAR_RANGE(500000,   0,  70, 10000),
-+	REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
-+};
-+
-+static const struct regulator_desc axp313a_regulators[] = {
-+	AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
-+			axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
-+			AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
-+			AXP313A_OUTPUT_CONTROL, BIT(0)),
-+	AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
-+			axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
-+			AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
-+			AXP313A_OUTPUT_CONTROL, BIT(1)),
-+	AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
-+			axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
-+			AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
-+			AXP313A_OUTPUT_CONTROL, BIT(2)),
-+	AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
-+		 AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
-+		 AXP313A_OUTPUT_CONTROL, BIT(3)),
-+	AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
-+		 AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
-+		 AXP313A_OUTPUT_CONTROL, BIT(4)),
-+	AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
-+};
-+
- /* DCDC ranges shared with AXP813 */
- static const struct linear_range axp803_dcdc234_ranges[] = {
- 	REGULATOR_LINEAR_RANGE(500000,
-@@ -1001,6 +1116,104 @@ static const struct regulator_desc axp81
+@@ -1048,6 +1116,104 @@ static const struct regulator_desc axp81
  		    AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
  };
  
@@ -253,24 +209,20 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
  {
  	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
-@@ -1040,6 +1253,16 @@ static int axp20x_set_dcdc_freq(struct p
- 		def = 3000;
+@@ -1088,10 +1254,11 @@ static int axp20x_set_dcdc_freq(struct p
  		step = 150;
  		break;
-+	case AXP313A_ID:
+ 	case AXP313A_ID:
 +	case AXP15060_ID:
-+		/* The DCDC PWM frequency seems to be fixed to 3 MHz. */
-+		if (dcdcfreq != 0) {
-+			dev_err(&pdev->dev,
+ 		/* The DCDC PWM frequency seems to be fixed to 3 MHz. */
+ 		if (dcdcfreq != 0) {
+ 			dev_err(&pdev->dev,
+-				"DCDC frequency on AXP313a is fixed to 3 MHz.\n");
 +				"DCDC frequency on this PMIC is fixed to 3 MHz.\n");
-+			return -EINVAL;
-+		}
-+
-+		return 0;
- 	default:
- 		dev_err(&pdev->dev,
- 			"Setting DCDC frequency for unsupported AXP variant\n");
-@@ -1145,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(stru
+ 			return -EINVAL;
+ 		}
+ 
+@@ -1201,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(stru
  		workmode <<= id - AXP813_DCDC1;
  		break;
  
@@ -286,7 +238,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  	default:
  		/* should not happen */
  		WARN_ON(1);
-@@ -1164,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(st
+@@ -1220,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(st
  
  	/*
  	 * Currently in our supported AXP variants, only AXP803, AXP806,
@@ -295,7 +247,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  	 */
  	switch (axp20x->variant) {
  	case AXP803_ID:
-@@ -1196,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(st
+@@ -1252,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(st
  		}
  		break;
  
@@ -313,7 +265,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  	default:
  		return false;
  	}
-@@ -1217,6 +1460,7 @@ static int axp20x_regulator_probe(struct
+@@ -1273,6 +1460,7 @@ static int axp20x_regulator_probe(struct
  	u32 workmode;
  	const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
  	const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
@@ -321,18 +273,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  	bool drivevbus = false;
  
  	switch (axp20x->variant) {
-@@ -1232,6 +1476,10 @@ static int axp20x_regulator_probe(struct
- 		drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
- 						  "x-powers,drive-vbus-en");
- 		break;
-+	case AXP313A_ID:
-+		regulators = axp313a_regulators;
-+		nregulators = AXP313A_REG_ID_MAX;
-+		break;
- 	case AXP803_ID:
- 		regulators = axp803_regulators;
- 		nregulators = AXP803_REG_ID_MAX;
-@@ -1252,6 +1500,10 @@ static int axp20x_regulator_probe(struct
+@@ -1312,6 +1500,10 @@ static int axp20x_regulator_probe(struct
  		drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
  						  "x-powers,drive-vbus-en");
  		break;
@@ -343,7 +284,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  	default:
  		dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
  			axp20x->variant);
-@@ -1278,8 +1530,9 @@ static int axp20x_regulator_probe(struct
+@@ -1338,8 +1530,9 @@ static int axp20x_regulator_probe(struct
  			continue;
  
  		/*
@@ -355,7 +296,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  		 *
  		 * We always register the regulators in proper sequence,
  		 * so the supply names are correctly read. See the last
-@@ -1288,7 +1541,8 @@ static int axp20x_regulator_probe(struct
+@@ -1348,7 +1541,8 @@ static int axp20x_regulator_probe(struct
  		 */
  		if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
  		    (regulators == axp803_regulators && i == AXP803_DC1SW) ||
@@ -365,7 +306,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  			new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
  						GFP_KERNEL);
  			if (!new_desc)
-@@ -1300,7 +1554,8 @@ static int axp20x_regulator_probe(struct
+@@ -1360,7 +1554,8 @@ static int axp20x_regulator_probe(struct
  		}
  
  		if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
@@ -375,7 +316,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  			new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
  						GFP_KERNEL);
  			if (!new_desc)
-@@ -1311,6 +1566,18 @@ static int axp20x_regulator_probe(struct
+@@ -1371,6 +1566,18 @@ static int axp20x_regulator_probe(struct
  			desc = new_desc;
  		}
  
@@ -394,7 +335,7 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  		rdev = devm_regulator_register(&pdev->dev, desc, &config);
  		if (IS_ERR(rdev)) {
  			dev_err(&pdev->dev, "Failed to register %s\n",
-@@ -1329,19 +1596,26 @@ static int axp20x_regulator_probe(struct
+@@ -1389,19 +1596,26 @@ static int axp20x_regulator_probe(struct
  		}
  
  		/*
@@ -424,11 +365,3 @@ Signed-off-by: ziv.xu <ziv.xu at starfive.com>
  	}
  
  	if (drivevbus) {
-@@ -1364,6 +1638,7 @@ static struct platform_driver axp20x_reg
- 	.probe	= axp20x_regulator_probe,
- 	.driver	= {
- 		.name		= "axp20x-regulator",
-+		.probe_type	= PROBE_PREFER_ASYNCHRONOUS,
- 	},
- };
- 
diff --git a/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch b/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch
new file mode 100644
index 0000000000..d75b4e7453
--- /dev/null
+++ b/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch
@@ -0,0 +1,383 @@
+From 63eeabbc9dbddd7381409feccd9082e5ffabfe59 Mon Sep 17 00:00:00 2001
+From: Aidan MacDonald <aidanmacdonald.0x0 at gmail.com>
+Date: Thu, 11 May 2023 10:26:08 +0100
+Subject: [PATCH] mfd: axp20x: Add support for AXP192
+
+The AXP192 PMIC is similar to the AXP202/AXP209, but with different
+regulators, additional GPIOs, and a different IRQ register layout.
+
+Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0 at gmail.com>
+Link: https://lore.kernel.org/r/20230511092609.76183-1-aidanmacdonald.0x0@gmail.com
+Signed-off-by: Lee Jones <lee at kernel.org>
+---
+ drivers/mfd/axp20x-i2c.c   |   2 +
+ drivers/mfd/axp20x.c       | 141 +++++++++++++++++++++++++++++++++++++
+ include/linux/mfd/axp20x.h |  84 ++++++++++++++++++++++
+ 3 files changed, 227 insertions(+)
+
+--- a/drivers/mfd/axp20x-i2c.c
++++ b/drivers/mfd/axp20x-i2c.c
+@@ -60,6 +60,7 @@ static void axp20x_i2c_remove(struct i2c
+ #ifdef CONFIG_OF
+ static const struct of_device_id axp20x_i2c_of_match[] = {
+ 	{ .compatible = "x-powers,axp152", .data = (void *)AXP152_ID },
++	{ .compatible = "x-powers,axp192", .data = (void *)AXP192_ID },
+ 	{ .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
+ 	{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
+ 	{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
+@@ -75,6 +76,7 @@ MODULE_DEVICE_TABLE(of, axp20x_i2c_of_ma
+ 
+ static const struct i2c_device_id axp20x_i2c_id[] = {
+ 	{ "axp152", 0 },
++	{ "axp192", 0 },
+ 	{ "axp202", 0 },
+ 	{ "axp209", 0 },
+ 	{ "axp221", 0 },
+--- a/drivers/mfd/axp20x.c
++++ b/drivers/mfd/axp20x.c
+@@ -34,6 +34,7 @@
+ 
+ static const char * const axp20x_model_names[] = {
+ 	"AXP152",
++	"AXP192",
+ 	"AXP202",
+ 	"AXP209",
+ 	"AXP221",
+@@ -94,6 +95,35 @@ static const struct regmap_access_table
+ 	.n_yes_ranges	= ARRAY_SIZE(axp20x_volatile_ranges),
+ };
+ 
++static const struct regmap_range axp192_writeable_ranges[] = {
++	regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)),
++	regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE),
++	regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL),
++	regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL),
++};
++
++static const struct regmap_range axp192_volatile_ranges[] = {
++	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS),
++	regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE),
++	regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE),
++	regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
++	regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
++	regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE),
++	regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE),
++	regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL),
++	regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL),
++};
++
++static const struct regmap_access_table axp192_writeable_table = {
++	.yes_ranges	= axp192_writeable_ranges,
++	.n_yes_ranges	= ARRAY_SIZE(axp192_writeable_ranges),
++};
++
++static const struct regmap_access_table axp192_volatile_table = {
++	.yes_ranges	= axp192_volatile_ranges,
++	.n_yes_ranges	= ARRAY_SIZE(axp192_volatile_ranges),
++};
++
+ /* AXP22x ranges are shared with the AXP809, as they cover the same range */
+ static const struct regmap_range axp22x_writeable_ranges[] = {
+ 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
+@@ -220,6 +250,19 @@ static const struct resource axp152_pek_
+ 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
+ };
+ 
++static const struct resource axp192_ac_power_supply_resources[] = {
++	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
++	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
++	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
++};
++
++static const struct resource axp192_usb_power_supply_resources[] = {
++	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
++	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
++	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"),
++	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
++};
++
+ static const struct resource axp20x_ac_power_supply_resources[] = {
+ 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
+ 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
+@@ -302,6 +345,15 @@ static const struct regmap_config axp152
+ 	.cache_type	= REGCACHE_RBTREE,
+ };
+ 
++static const struct regmap_config axp192_regmap_config = {
++	.reg_bits	= 8,
++	.val_bits	= 8,
++	.wr_table	= &axp192_writeable_table,
++	.volatile_table	= &axp192_volatile_table,
++	.max_register	= AXP20X_CC_CTRL,
++	.cache_type	= REGCACHE_RBTREE,
++};
++
+ static const struct regmap_config axp20x_regmap_config = {
+ 	.reg_bits	= 8,
+ 	.val_bits	= 8,
+@@ -379,6 +431,42 @@ static const struct regmap_irq axp152_re
+ 	INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT,		2, 0),
+ };
+ 
++static const struct regmap_irq axp192_regmap_irqs[] = {
++	INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V,		0, 7),
++	INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN,		0, 6),
++	INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL,		0, 5),
++	INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V,		0, 4),
++	INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN,		0, 3),
++	INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL,		0, 2),
++	INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW,		0, 1),
++	INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN,		1, 7),
++	INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL,	        1, 6),
++	INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE,	1, 5),
++	INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE,	1, 4),
++	INIT_REGMAP_IRQ(AXP192, CHARG,		        1, 3),
++	INIT_REGMAP_IRQ(AXP192, CHARG_DONE,		1, 2),
++	INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH,	        1, 1),
++	INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW,	        1, 0),
++	INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH,	        2, 7),
++	INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW,		2, 6),
++	INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG,	        2, 5),
++	INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG,	        2, 4),
++	INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG,	        2, 3),
++	INIT_REGMAP_IRQ(AXP192, PEK_SHORT,		2, 1),
++	INIT_REGMAP_IRQ(AXP192, PEK_LONG,		2, 0),
++	INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON,		3, 7),
++	INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF,	        3, 6),
++	INIT_REGMAP_IRQ(AXP192, VBUS_VALID,		3, 5),
++	INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID,	        3, 4),
++	INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID,	3, 3),
++	INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END,	        3, 2),
++	INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL,	        3, 0),
++	INIT_REGMAP_IRQ(AXP192, TIMER,			4, 7),
++	INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT,		4, 2),
++	INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT,		4, 1),
++	INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT,		4, 0),
++};
++
+ static const struct regmap_irq axp20x_regmap_irqs[] = {
+ 	INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V,		0, 7),
+ 	INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN,		0, 6),
+@@ -616,6 +704,32 @@ static const struct regmap_irq_chip axp1
+ 	.num_regs		= 3,
+ };
+ 
++static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data,
++				       unsigned int base, int index)
++{
++	/* linear mapping for IRQ1 to IRQ4 */
++	if (index < 4)
++		return base + index;
++
++	/* handle IRQ5 separately */
++	if (base == AXP192_IRQ1_EN)
++		return AXP192_IRQ5_EN;
++
++	return AXP192_IRQ5_STATE;
++}
++
++static const struct regmap_irq_chip axp192_regmap_irq_chip = {
++	.name			= "axp192_irq_chip",
++	.status_base		= AXP192_IRQ1_STATE,
++	.ack_base		= AXP192_IRQ1_STATE,
++	.unmask_base		= AXP192_IRQ1_EN,
++	.init_ack_masked	= true,
++	.irqs			= axp192_regmap_irqs,
++	.num_irqs		= ARRAY_SIZE(axp192_regmap_irqs),
++	.num_regs		= 5,
++	.get_irq_reg		= axp192_get_irq_reg,
++};
++
+ static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
+ 	.name			= "axp20x_irq_chip",
+ 	.status_base		= AXP20X_IRQ1_STATE,
+@@ -712,6 +826,27 @@ static const struct regmap_irq_chip axp1
+ 	.num_regs		= 2,
+ };
+ 
++static const struct mfd_cell axp192_cells[] = {
++	{
++		.name		= "axp192-adc",
++		.of_compatible	= "x-powers,axp192-adc",
++	}, {
++		.name		= "axp20x-battery-power-supply",
++		.of_compatible	= "x-powers,axp192-battery-power-supply",
++	}, {
++		.name		= "axp20x-ac-power-supply",
++		.of_compatible	= "x-powers,axp202-ac-power-supply",
++		.num_resources	= ARRAY_SIZE(axp192_ac_power_supply_resources),
++		.resources	= axp192_ac_power_supply_resources,
++	}, {
++		.name		= "axp20x-usb-power-supply",
++		.of_compatible	= "x-powers,axp192-usb-power-supply",
++		.num_resources	= ARRAY_SIZE(axp192_usb_power_supply_resources),
++		.resources	= axp192_usb_power_supply_resources,
++	},
++	{	.name		= "axp20x-regulator" },
++};
++
+ static const struct mfd_cell axp20x_cells[] = {
+ 	{
+ 		.name		= "axp20x-gpio",
+@@ -1029,6 +1164,12 @@ int axp20x_match_device(struct axp20x_de
+ 		axp20x->regmap_cfg = &axp152_regmap_config;
+ 		axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
+ 		break;
++	case AXP192_ID:
++		axp20x->nr_cells = ARRAY_SIZE(axp192_cells);
++		axp20x->cells = axp192_cells;
++		axp20x->regmap_cfg = &axp192_regmap_config;
++		axp20x->regmap_irq_chip = &axp192_regmap_irq_chip;
++		break;
+ 	case AXP202_ID:
+ 	case AXP209_ID:
+ 		axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
+--- a/include/linux/mfd/axp20x.h
++++ b/include/linux/mfd/axp20x.h
+@@ -12,6 +12,7 @@
+ 
+ enum axp20x_variants {
+ 	AXP152_ID = 0,
++	AXP192_ID,
+ 	AXP202_ID,
+ 	AXP209_ID,
+ 	AXP221_ID,
+@@ -26,6 +27,7 @@ enum axp20x_variants {
+ 	NR_AXP20X_VARIANTS,
+ };
+ 
++#define AXP192_DATACACHE(m)		(0x06 + (m))
+ #define AXP20X_DATACACHE(m)		(0x04 + (m))
+ 
+ /* Power supply */
+@@ -47,6 +49,13 @@ enum axp20x_variants {
+ #define AXP152_DCDC_FREQ		0x37
+ #define AXP152_DCDC_MODE		0x80
+ 
++#define AXP192_USB_OTG_STATUS		0x04
++#define AXP192_PWR_OUT_CTRL		0x12
++#define AXP192_DCDC2_V_OUT		0x23
++#define AXP192_DCDC1_V_OUT		0x26
++#define AXP192_DCDC3_V_OUT		0x27
++#define AXP192_LDO2_3_V_OUT		0x28
++
+ #define AXP20X_PWR_INPUT_STATUS		0x00
+ #define AXP20X_PWR_OP_MODE		0x01
+ #define AXP20X_USB_OTG_STATUS		0x02
+@@ -185,6 +194,17 @@ enum axp20x_variants {
+ #define AXP152_IRQ2_STATE		0x49
+ #define AXP152_IRQ3_STATE		0x4a
+ 
++#define AXP192_IRQ1_EN			0x40
++#define AXP192_IRQ2_EN			0x41
++#define AXP192_IRQ3_EN			0x42
++#define AXP192_IRQ4_EN			0x43
++#define AXP192_IRQ1_STATE		0x44
++#define AXP192_IRQ2_STATE		0x45
++#define AXP192_IRQ3_STATE		0x46
++#define AXP192_IRQ4_STATE		0x47
++#define AXP192_IRQ5_EN			0x4a
++#define AXP192_IRQ5_STATE		0x4d
++
+ #define AXP20X_IRQ1_EN			0x40
+ #define AXP20X_IRQ2_EN			0x41
+ #define AXP20X_IRQ3_EN			0x42
+@@ -204,6 +224,11 @@ enum axp20x_variants {
+ #define AXP15060_IRQ2_STATE		0x49
+ 
+ /* ADC */
++#define AXP192_GPIO2_V_ADC_H		0x68
++#define AXP192_GPIO2_V_ADC_L		0x69
++#define AXP192_GPIO3_V_ADC_H		0x6a
++#define AXP192_GPIO3_V_ADC_L		0x6b
++
+ #define AXP20X_ACIN_V_ADC_H		0x56
+ #define AXP20X_ACIN_V_ADC_L		0x57
+ #define AXP20X_ACIN_I_ADC_H		0x58
+@@ -233,6 +258,8 @@ enum axp20x_variants {
+ #define AXP20X_IPSOUT_V_HIGH_L		0x7f
+ 
+ /* Power supply */
++#define AXP192_GPIO30_IN_RANGE		0x85
++
+ #define AXP20X_DCDC_MODE		0x80
+ #define AXP20X_ADC_EN1			0x82
+ #define AXP20X_ADC_EN2			0x83
+@@ -261,6 +288,16 @@ enum axp20x_variants {
+ #define AXP152_PWM1_FREQ_Y		0x9c
+ #define AXP152_PWM1_DUTY_CYCLE		0x9d
+ 
++#define AXP192_GPIO0_CTRL		0x90
++#define AXP192_LDO_IO0_V_OUT		0x91
++#define AXP192_GPIO1_CTRL		0x92
++#define AXP192_GPIO2_CTRL		0x93
++#define AXP192_GPIO2_0_STATE		0x94
++#define AXP192_GPIO4_3_CTRL		0x95
++#define AXP192_GPIO4_3_STATE		0x96
++#define AXP192_GPIO2_0_PULL		0x97
++#define AXP192_N_RSTO_CTRL		0x9e
++
+ #define AXP20X_GPIO0_CTRL		0x90
+ #define AXP20X_LDO5_V_OUT		0x91
+ #define AXP20X_GPIO1_CTRL		0x92
+@@ -341,6 +378,17 @@ enum axp20x_variants {
+ 
+ /* Regulators IDs */
+ enum {
++	AXP192_DCDC1 = 0,
++	AXP192_DCDC2,
++	AXP192_DCDC3,
++	AXP192_LDO1,
++	AXP192_LDO2,
++	AXP192_LDO3,
++	AXP192_LDO_IO0,
++	AXP192_REG_ID_MAX
++};
++
++enum {
+ 	AXP20X_LDO1 = 0,
+ 	AXP20X_LDO2,
+ 	AXP20X_LDO3,
+@@ -531,6 +579,42 @@ enum {
+ 	AXP152_IRQ_GPIO0_INPUT,
+ };
+ 
++enum axp192_irqs {
++	AXP192_IRQ_ACIN_OVER_V = 1,
++	AXP192_IRQ_ACIN_PLUGIN,
++	AXP192_IRQ_ACIN_REMOVAL,
++	AXP192_IRQ_VBUS_OVER_V,
++	AXP192_IRQ_VBUS_PLUGIN,
++	AXP192_IRQ_VBUS_REMOVAL,
++	AXP192_IRQ_VBUS_V_LOW,
++	AXP192_IRQ_BATT_PLUGIN,
++	AXP192_IRQ_BATT_REMOVAL,
++	AXP192_IRQ_BATT_ENT_ACT_MODE,
++	AXP192_IRQ_BATT_EXIT_ACT_MODE,
++	AXP192_IRQ_CHARG,
++	AXP192_IRQ_CHARG_DONE,
++	AXP192_IRQ_BATT_TEMP_HIGH,
++	AXP192_IRQ_BATT_TEMP_LOW,
++	AXP192_IRQ_DIE_TEMP_HIGH,
++	AXP192_IRQ_CHARG_I_LOW,
++	AXP192_IRQ_DCDC1_V_LONG,
++	AXP192_IRQ_DCDC2_V_LONG,
++	AXP192_IRQ_DCDC3_V_LONG,
++	AXP192_IRQ_PEK_SHORT = 22,
++	AXP192_IRQ_PEK_LONG,
++	AXP192_IRQ_N_OE_PWR_ON,
++	AXP192_IRQ_N_OE_PWR_OFF,
++	AXP192_IRQ_VBUS_VALID,
++	AXP192_IRQ_VBUS_NOT_VALID,
++	AXP192_IRQ_VBUS_SESS_VALID,
++	AXP192_IRQ_VBUS_SESS_END,
++	AXP192_IRQ_LOW_PWR_LVL = 31,
++	AXP192_IRQ_TIMER,
++	AXP192_IRQ_GPIO2_INPUT = 37,
++	AXP192_IRQ_GPIO1_INPUT,
++	AXP192_IRQ_GPIO0_INPUT,
++};
++
+ enum {
+ 	AXP20X_IRQ_ACIN_OVER_V = 1,
+ 	AXP20X_IRQ_ACIN_PLUGIN,
diff --git a/target/linux/starfive/patches-6.1/0117-driver-mfd-axp20x-Add-support-for-AXP15060.patch b/target/linux/starfive/patches-6.1/0117-driver-mfd-axp20x-Add-support-for-AXP15060.patch
deleted file mode 100644
index 18ad298065..0000000000
--- a/target/linux/starfive/patches-6.1/0117-driver-mfd-axp20x-Add-support-for-AXP15060.patch
+++ /dev/null
@@ -1,1014 +0,0 @@
-From e62161318f2fe3e396fc31c50d210e99bec83021 Mon Sep 17 00:00:00 2001
-From: "ziv.xu" <ziv.xu at starfive.com>
-Date: Fri, 4 Aug 2023 13:53:10 +0800
-Subject: [PATCH 117/122] driver: mfd: axp20x: Add support for AXP15060
-
-axp20x add support for AXP15060
-
-Signed-off-by: ziv.xu <ziv.xu at starfive.com>
----
- drivers/mfd/axp20x-i2c.c   |   2 +
- drivers/mfd/axp20x.c       | 373 ++++++++++++++++++++++++++++++++++---
- include/linux/mfd/axp20x.h | 218 +++++++++++++++++++++-
- 3 files changed, 557 insertions(+), 36 deletions(-)
-
---- a/drivers/mfd/axp20x-i2c.c
-+++ b/drivers/mfd/axp20x-i2c.c
-@@ -66,6 +66,7 @@ static const struct of_device_id axp20x_
- 	{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
- 	{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
- 	{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
-+	{ .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
- 	{ },
- };
- MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
-@@ -79,6 +80,7 @@ static const struct i2c_device_id axp20x
- 	{ "axp223", 0 },
- 	{ "axp803", 0 },
- 	{ "axp806", 0 },
-+	{ "axp15060", 0 },
- 	{ },
- };
- MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
---- a/drivers/mfd/axp20x.c
-+++ b/drivers/mfd/axp20x.c
-@@ -23,7 +23,7 @@
- #include <linux/mfd/core.h>
- #include <linux/module.h>
- #include <linux/of_device.h>
--#include <linux/pm_runtime.h>
-+#include <linux/reboot.h>
- #include <linux/regmap.h>
- #include <linux/regulator/consumer.h>
- 
-@@ -34,15 +34,18 @@
- 
- static const char * const axp20x_model_names[] = {
- 	"AXP152",
-+	"AXP192",
- 	"AXP202",
- 	"AXP209",
- 	"AXP221",
- 	"AXP223",
- 	"AXP288",
-+	"AXP313a",
- 	"AXP803",
- 	"AXP806",
- 	"AXP809",
- 	"AXP813",
-+	"AXP15060",
- };
- 
- static const struct regmap_range axp152_writeable_ranges[] = {
-@@ -92,6 +95,35 @@ static const struct regmap_access_table
- 	.n_yes_ranges	= ARRAY_SIZE(axp20x_volatile_ranges),
- };
- 
-+static const struct regmap_range axp192_writeable_ranges[] = {
-+	regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)),
-+	regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE),
-+	regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL),
-+	regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL),
-+};
-+
-+static const struct regmap_range axp192_volatile_ranges[] = {
-+	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS),
-+	regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE),
-+	regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE),
-+	regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
-+	regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
-+	regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE),
-+	regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE),
-+	regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL),
-+	regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL),
-+};
-+
-+static const struct regmap_access_table axp192_writeable_table = {
-+	.yes_ranges	= axp192_writeable_ranges,
-+	.n_yes_ranges	= ARRAY_SIZE(axp192_writeable_ranges),
-+};
-+
-+static const struct regmap_access_table axp192_volatile_table = {
-+	.yes_ranges	= axp192_volatile_ranges,
-+	.n_yes_ranges	= ARRAY_SIZE(axp192_volatile_ranges),
-+};
-+
- /* AXP22x ranges are shared with the AXP809, as they cover the same range */
- static const struct regmap_range axp22x_writeable_ranges[] = {
- 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
-@@ -119,6 +151,7 @@ static const struct regmap_access_table
- 
- /* AXP288 ranges are shared with the AXP803, as they cover the same range */
- static const struct regmap_range axp288_writeable_ranges[] = {
-+	regmap_reg_range(AXP288_POWER_REASON, AXP288_POWER_REASON),
- 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
- 	regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
- };
-@@ -154,6 +187,25 @@ static const struct regmap_range axp806_
- 	regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
- };
- 
-+static const struct regmap_range axp313a_writeable_ranges[] = {
-+	regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
-+};
-+
-+static const struct regmap_range axp313a_volatile_ranges[] = {
-+	regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
-+	regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
-+};
-+
-+static const struct regmap_access_table axp313a_writeable_table = {
-+	.yes_ranges = axp313a_writeable_ranges,
-+	.n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
-+};
-+
-+static const struct regmap_access_table axp313a_volatile_table = {
-+	.yes_ranges = axp313a_volatile_ranges,
-+	.n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
-+};
-+
- static const struct regmap_range axp806_volatile_ranges[] = {
- 	regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
- };
-@@ -168,11 +220,49 @@ static const struct regmap_access_table
- 	.n_yes_ranges	= ARRAY_SIZE(axp806_volatile_ranges),
- };
- 
-+static const struct regmap_range axp15060_writeable_ranges[] = {
-+	regmap_reg_range(AXP15060_PWR_OUT_CTRL1, AXP15060_DCDC_MODE_CTRL2),
-+	regmap_reg_range(AXP15060_OUTPUT_MONITOR_DISCHARGE, AXP15060_CPUSLDO_V_CTRL),
-+	regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
-+	regmap_reg_range(AXP15060_PEK_KEY, AXP15060_PEK_KEY),
-+	regmap_reg_range(AXP15060_IRQ1_EN, AXP15060_IRQ2_EN),
-+	regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
-+};
-+
-+static const struct regmap_range axp15060_volatile_ranges[] = {
-+	regmap_reg_range(AXP15060_STARTUP_SRC, AXP15060_STARTUP_SRC),
-+	regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
-+	regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
-+};
-+
-+static const struct regmap_access_table axp15060_writeable_table = {
-+	.yes_ranges	= axp15060_writeable_ranges,
-+	.n_yes_ranges	= ARRAY_SIZE(axp15060_writeable_ranges),
-+};
-+
-+static const struct regmap_access_table axp15060_volatile_table = {
-+	.yes_ranges	= axp15060_volatile_ranges,
-+	.n_yes_ranges	= ARRAY_SIZE(axp15060_volatile_ranges),
-+};
-+
- static const struct resource axp152_pek_resources[] = {
- 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- };
- 
-+static const struct resource axp192_ac_power_supply_resources[] = {
-+	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
-+	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
-+	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
-+};
-+
-+static const struct resource axp192_usb_power_supply_resources[] = {
-+	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
-+	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
-+	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"),
-+	DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
-+};
-+
- static const struct resource axp20x_ac_power_supply_resources[] = {
- 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
- 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
-@@ -221,6 +311,11 @@ static const struct resource axp288_fuel
- 	DEFINE_RES_IRQ(AXP288_IRQ_WL1),
- };
- 
-+static const struct resource axp313a_pek_resources[] = {
-+	DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
-+	DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
-+};
-+
- static const struct resource axp803_pek_resources[] = {
- 	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- 	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
-@@ -236,6 +331,11 @@ static const struct resource axp809_pek_
- 	DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- };
- 
-+static const struct resource axp15060_pek_resources[] = {
-+	DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
-+	DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
-+};
-+
- static const struct regmap_config axp152_regmap_config = {
- 	.reg_bits	= 8,
- 	.val_bits	= 8,
-@@ -245,6 +345,15 @@ static const struct regmap_config axp152
- 	.cache_type	= REGCACHE_RBTREE,
- };
- 
-+static const struct regmap_config axp192_regmap_config = {
-+	.reg_bits	= 8,
-+	.val_bits	= 8,
-+	.wr_table	= &axp192_writeable_table,
-+	.volatile_table	= &axp192_volatile_table,
-+	.max_register	= AXP20X_CC_CTRL,
-+	.cache_type	= REGCACHE_RBTREE,
-+};
-+
- static const struct regmap_config axp20x_regmap_config = {
- 	.reg_bits	= 8,
- 	.val_bits	= 8,
-@@ -272,6 +381,15 @@ static const struct regmap_config axp288
- 	.cache_type	= REGCACHE_RBTREE,
- };
- 
-+static const struct regmap_config axp313a_regmap_config = {
-+	.reg_bits = 8,
-+	.val_bits = 8,
-+	.wr_table = &axp313a_writeable_table,
-+	.volatile_table = &axp313a_volatile_table,
-+	.max_register = AXP313A_IRQ_STATE,
-+	.cache_type = REGCACHE_RBTREE,
-+};
-+
- static const struct regmap_config axp806_regmap_config = {
- 	.reg_bits	= 8,
- 	.val_bits	= 8,
-@@ -281,6 +399,15 @@ static const struct regmap_config axp806
- 	.cache_type	= REGCACHE_RBTREE,
- };
- 
-+static const struct regmap_config axp15060_regmap_config = {
-+	.reg_bits	= 8,
-+	.val_bits	= 8,
-+	.wr_table	= &axp15060_writeable_table,
-+	.volatile_table	= &axp15060_volatile_table,
-+	.max_register	= AXP15060_IRQ2_STATE,
-+	.cache_type	= REGCACHE_RBTREE,
-+};
-+
- #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask)			\
- 	[_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
- 
-@@ -304,6 +431,42 @@ static const struct regmap_irq axp152_re
- 	INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT,		2, 0),
- };
- 
-+static const struct regmap_irq axp192_regmap_irqs[] = {
-+	INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V,		0, 7),
-+	INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN,		0, 6),
-+	INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL,		0, 5),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V,		0, 4),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN,		0, 3),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL,		0, 2),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW,		0, 1),
-+	INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN,		1, 7),
-+	INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL,	        1, 6),
-+	INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE,	1, 5),
-+	INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE,	1, 4),
-+	INIT_REGMAP_IRQ(AXP192, CHARG,		        1, 3),
-+	INIT_REGMAP_IRQ(AXP192, CHARG_DONE,		1, 2),
-+	INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH,	        1, 1),
-+	INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW,	        1, 0),
-+	INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH,	        2, 7),
-+	INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW,		2, 6),
-+	INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG,	        2, 5),
-+	INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG,	        2, 4),
-+	INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG,	        2, 3),
-+	INIT_REGMAP_IRQ(AXP192, PEK_SHORT,		2, 1),
-+	INIT_REGMAP_IRQ(AXP192, PEK_LONG,		2, 0),
-+	INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON,		3, 7),
-+	INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF,	        3, 6),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_VALID,		3, 5),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID,	        3, 4),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID,	3, 3),
-+	INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END,	        3, 2),
-+	INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL,	        3, 0),
-+	INIT_REGMAP_IRQ(AXP192, TIMER,			4, 7),
-+	INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT,		4, 2),
-+	INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT,		4, 1),
-+	INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT,		4, 0),
-+};
-+
- static const struct regmap_irq axp20x_regmap_irqs[] = {
- 	INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V,		0, 7),
- 	INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN,		0, 6),
-@@ -415,6 +578,16 @@ static const struct regmap_irq axp288_re
- 	INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG,            5, 1),
- };
- 
-+static const struct regmap_irq axp313a_regmap_irqs[] = {
-+	INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE,		0, 7),
-+	INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE,		0, 6),
-+	INIT_REGMAP_IRQ(AXP313A, PEK_SHORT,		0, 5),
-+	INIT_REGMAP_IRQ(AXP313A, PEK_LONG,		0, 4),
-+	INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW,		0, 3),
-+	INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW,		0, 2),
-+	INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH,		0, 0),
-+};
-+
- static const struct regmap_irq axp803_regmap_irqs[] = {
- 	INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V,		0, 7),
- 	INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN,		0, 6),
-@@ -502,24 +675,65 @@ static const struct regmap_irq axp809_re
- 	INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT,		4, 0),
- };
- 
-+static const struct regmap_irq axp15060_regmap_irqs[] = {
-+	INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV1,	0, 0),
-+	INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV2,	0, 1),
-+	INIT_REGMAP_IRQ(AXP15060, DCDC1_V_LOW,		0, 2),
-+	INIT_REGMAP_IRQ(AXP15060, DCDC2_V_LOW,		0, 3),
-+	INIT_REGMAP_IRQ(AXP15060, DCDC3_V_LOW,		0, 4),
-+	INIT_REGMAP_IRQ(AXP15060, DCDC4_V_LOW,		0, 5),
-+	INIT_REGMAP_IRQ(AXP15060, DCDC5_V_LOW,		0, 6),
-+	INIT_REGMAP_IRQ(AXP15060, DCDC6_V_LOW,		0, 7),
-+	INIT_REGMAP_IRQ(AXP15060, PEK_LONG,			1, 0),
-+	INIT_REGMAP_IRQ(AXP15060, PEK_SHORT,			1, 1),
-+	INIT_REGMAP_IRQ(AXP15060, GPIO1_INPUT,		1, 2),
-+	INIT_REGMAP_IRQ(AXP15060, PEK_FAL_EDGE,			1, 3),
-+	INIT_REGMAP_IRQ(AXP15060, PEK_RIS_EDGE,			1, 4),
-+	INIT_REGMAP_IRQ(AXP15060, GPIO2_INPUT,		1, 5),
-+};
-+
- static const struct regmap_irq_chip axp152_regmap_irq_chip = {
- 	.name			= "axp152_irq_chip",
- 	.status_base		= AXP152_IRQ1_STATE,
- 	.ack_base		= AXP152_IRQ1_STATE,
--	.mask_base		= AXP152_IRQ1_EN,
--	.mask_invert		= true,
-+	.unmask_base		= AXP152_IRQ1_EN,
- 	.init_ack_masked	= true,
- 	.irqs			= axp152_regmap_irqs,
- 	.num_irqs		= ARRAY_SIZE(axp152_regmap_irqs),
- 	.num_regs		= 3,
- };
- 
-+static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data,
-+				       unsigned int base, int index)
-+{
-+	/* linear mapping for IRQ1 to IRQ4 */
-+	if (index < 4)
-+		return base + index;
-+
-+	/* handle IRQ5 separately */
-+	if (base == AXP192_IRQ1_EN)
-+		return AXP192_IRQ5_EN;
-+
-+	return AXP192_IRQ5_STATE;
-+}
-+
-+static const struct regmap_irq_chip axp192_regmap_irq_chip = {
-+	.name			= "axp192_irq_chip",
-+	.status_base		= AXP192_IRQ1_STATE,
-+	.ack_base		= AXP192_IRQ1_STATE,
-+	.unmask_base		= AXP192_IRQ1_EN,
-+	.init_ack_masked	= true,
-+	.irqs			= axp192_regmap_irqs,
-+	.num_irqs		= ARRAY_SIZE(axp192_regmap_irqs),
-+	.num_regs		= 5,
-+	.get_irq_reg		= axp192_get_irq_reg,
-+};
-+
- static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
- 	.name			= "axp20x_irq_chip",
- 	.status_base		= AXP20X_IRQ1_STATE,
- 	.ack_base		= AXP20X_IRQ1_STATE,
--	.mask_base		= AXP20X_IRQ1_EN,
--	.mask_invert		= true,
-+	.unmask_base		= AXP20X_IRQ1_EN,
- 	.init_ack_masked	= true,
- 	.irqs			= axp20x_regmap_irqs,
- 	.num_irqs		= ARRAY_SIZE(axp20x_regmap_irqs),
-@@ -531,8 +745,7 @@ static const struct regmap_irq_chip axp2
- 	.name			= "axp22x_irq_chip",
- 	.status_base		= AXP20X_IRQ1_STATE,
- 	.ack_base		= AXP20X_IRQ1_STATE,
--	.mask_base		= AXP20X_IRQ1_EN,
--	.mask_invert		= true,
-+	.unmask_base		= AXP20X_IRQ1_EN,
- 	.init_ack_masked	= true,
- 	.irqs			= axp22x_regmap_irqs,
- 	.num_irqs		= ARRAY_SIZE(axp22x_regmap_irqs),
-@@ -543,8 +756,7 @@ static const struct regmap_irq_chip axp2
- 	.name			= "axp288_irq_chip",
- 	.status_base		= AXP20X_IRQ1_STATE,
- 	.ack_base		= AXP20X_IRQ1_STATE,
--	.mask_base		= AXP20X_IRQ1_EN,
--	.mask_invert		= true,
-+	.unmask_base		= AXP20X_IRQ1_EN,
- 	.init_ack_masked	= true,
- 	.irqs			= axp288_regmap_irqs,
- 	.num_irqs		= ARRAY_SIZE(axp288_regmap_irqs),
-@@ -552,12 +764,22 @@ static const struct regmap_irq_chip axp2
- 
- };
- 
-+static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
-+	.name			= "axp313a_irq_chip",
-+	.status_base		= AXP313A_IRQ_STATE,
-+	.ack_base		= AXP313A_IRQ_STATE,
-+	.unmask_base		= AXP313A_IRQ_EN,
-+	.init_ack_masked	= true,
-+	.irqs			= axp313a_regmap_irqs,
-+	.num_irqs		= ARRAY_SIZE(axp313a_regmap_irqs),
-+	.num_regs		= 1,
-+};
-+
- static const struct regmap_irq_chip axp803_regmap_irq_chip = {
- 	.name			= "axp803",
- 	.status_base		= AXP20X_IRQ1_STATE,
- 	.ack_base		= AXP20X_IRQ1_STATE,
--	.mask_base		= AXP20X_IRQ1_EN,
--	.mask_invert		= true,
-+	.unmask_base		= AXP20X_IRQ1_EN,
- 	.init_ack_masked	= true,
- 	.irqs			= axp803_regmap_irqs,
- 	.num_irqs		= ARRAY_SIZE(axp803_regmap_irqs),
-@@ -568,8 +790,7 @@ static const struct regmap_irq_chip axp8
- 	.name			= "axp806",
- 	.status_base		= AXP20X_IRQ1_STATE,
- 	.ack_base		= AXP20X_IRQ1_STATE,
--	.mask_base		= AXP20X_IRQ1_EN,
--	.mask_invert		= true,
-+	.unmask_base		= AXP20X_IRQ1_EN,
- 	.init_ack_masked	= true,
- 	.irqs			= axp806_regmap_irqs,
- 	.num_irqs		= ARRAY_SIZE(axp806_regmap_irqs),
-@@ -580,14 +801,45 @@ static const struct regmap_irq_chip axp8
- 	.name			= "axp809",
- 	.status_base		= AXP20X_IRQ1_STATE,
- 	.ack_base		= AXP20X_IRQ1_STATE,
--	.mask_base		= AXP20X_IRQ1_EN,
--	.mask_invert		= true,
-+	.unmask_base		= AXP20X_IRQ1_EN,
- 	.init_ack_masked	= true,
- 	.irqs			= axp809_regmap_irqs,
- 	.num_irqs		= ARRAY_SIZE(axp809_regmap_irqs),
- 	.num_regs		= 5,
- };
- 
-+static const struct regmap_irq_chip axp15060_regmap_irq_chip = {
-+	.name			= "axp15060",
-+	.status_base		= AXP15060_IRQ1_STATE,
-+	.ack_base		= AXP15060_IRQ1_STATE,
-+	.unmask_base		= AXP15060_IRQ1_EN,
-+	.init_ack_masked	= true,
-+	.irqs			= axp15060_regmap_irqs,
-+	.num_irqs		= ARRAY_SIZE(axp15060_regmap_irqs),
-+	.num_regs		= 2,
-+};
-+
-+static const struct mfd_cell axp192_cells[] = {
-+	{
-+		.name		= "axp192-adc",
-+		.of_compatible	= "x-powers,axp192-adc",
-+	}, {
-+		.name		= "axp20x-battery-power-supply",
-+		.of_compatible	= "x-powers,axp192-battery-power-supply",
-+	}, {
-+		.name		= "axp20x-ac-power-supply",
-+		.of_compatible	= "x-powers,axp202-ac-power-supply",
-+		.num_resources	= ARRAY_SIZE(axp192_ac_power_supply_resources),
-+		.resources	= axp192_ac_power_supply_resources,
-+	}, {
-+		.name		= "axp20x-usb-power-supply",
-+		.of_compatible	= "x-powers,axp192-usb-power-supply",
-+		.num_resources	= ARRAY_SIZE(axp192_usb_power_supply_resources),
-+		.resources	= axp192_usb_power_supply_resources,
-+	},
-+	{	.name		= "axp20x-regulator" },
-+};
-+
- static const struct mfd_cell axp20x_cells[] = {
- 	{
- 		.name		= "axp20x-gpio",
-@@ -683,6 +935,11 @@ static const struct mfd_cell axp152_cell
- 	},
- };
- 
-+static struct mfd_cell axp313a_cells[] = {
-+	MFD_CELL_NAME("axp20x-regulator"),
-+	MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
-+};
-+
- static const struct resource axp288_adc_resources[] = {
- 	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
- };
-@@ -832,17 +1089,43 @@ static const struct mfd_cell axp813_cell
- 	},
- };
- 
--static struct axp20x_dev *axp20x_pm_power_off;
--static void axp20x_power_off(void)
-+static const struct mfd_cell axp15060_cells[] = {
-+	{
-+		.name		= "axp221-pek",
-+		.num_resources	= ARRAY_SIZE(axp15060_pek_resources),
-+		.resources	= axp15060_pek_resources,
-+	}, {
-+		.name		= "axp20x-regulator",
-+	},
-+};
-+
-+/* For boards that don't have IRQ line connected to SOC. */
-+static const struct mfd_cell axp_regulator_only_cells[] = {
-+	{
-+		.name		= "axp20x-regulator",
-+	},
-+};
-+
-+static int axp20x_power_off(struct sys_off_data *data)
- {
--	if (axp20x_pm_power_off->variant == AXP288_ID)
--		return;
-+	struct axp20x_dev *axp20x = data->cb_data;
-+	unsigned int shutdown_reg;
- 
--	regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
--		     AXP20X_OFF);
-+	switch (axp20x->variant) {
-+	case AXP313A_ID:
-+		shutdown_reg = AXP313A_SHUTDOWN_CTRL;
-+		break;
-+	default:
-+		shutdown_reg = AXP20X_OFF_CTRL;
-+		break;
-+	}
-+
-+	regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
- 
- 	/* Give capacitors etc. time to drain to avoid kernel panic msg. */
- 	mdelay(500);
-+
-+	return NOTIFY_DONE;
- }
- 
- int axp20x_match_device(struct axp20x_dev *axp20x)
-@@ -874,6 +1157,12 @@ int axp20x_match_device(struct axp20x_de
- 		axp20x->regmap_cfg = &axp152_regmap_config;
- 		axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
- 		break;
-+	case AXP192_ID:
-+		axp20x->nr_cells = ARRAY_SIZE(axp192_cells);
-+		axp20x->cells = axp192_cells;
-+		axp20x->regmap_cfg = &axp192_regmap_config;
-+		axp20x->regmap_irq_chip = &axp192_regmap_irq_chip;
-+		break;
- 	case AXP202_ID:
- 	case AXP209_ID:
- 		axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
-@@ -900,6 +1189,12 @@ int axp20x_match_device(struct axp20x_de
- 		axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
- 		axp20x->irq_flags = IRQF_TRIGGER_LOW;
- 		break;
-+	case AXP313A_ID:
-+		axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
-+		axp20x->cells = axp313a_cells;
-+		axp20x->regmap_cfg = &axp313a_regmap_config;
-+		axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
-+		break;
- 	case AXP803_ID:
- 		axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
- 		axp20x->cells = axp803_cells;
-@@ -942,6 +1237,28 @@ int axp20x_match_device(struct axp20x_de
- 		 */
- 		axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
- 		break;
-+	case AXP15060_ID:
-+		/*
-+		 * Don't register the power key part if there is no interrupt
-+		 * line.
-+		 *
-+		 * Since most use cases of AXP PMICs are Allwinner SOCs, board
-+		 * designers follow Allwinner's reference design and connects
-+		 * IRQ line to SOC, there's no need for those variants to deal
-+		 * with cases that IRQ isn't connected. However, AXP15660 is
-+		 * used by some other vendors' SOCs that didn't connect IRQ
-+		 * line, we need to deal with this case.
-+		 */
-+		if (axp20x->irq > 0) {
-+			axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
-+			axp20x->cells = axp15060_cells;
-+		} else {
-+			axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
-+			axp20x->cells = axp_regulator_only_cells;
-+		}
-+		axp20x->regmap_cfg = &axp15060_regmap_config;
-+		axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip;
-+		break;
- 	default:
- 		dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
- 		return -EINVAL;
-@@ -1009,10 +1326,11 @@ int axp20x_device_probe(struct axp20x_de
- 		return ret;
- 	}
- 
--	if (!pm_power_off) {
--		axp20x_pm_power_off = axp20x;
--		pm_power_off = axp20x_power_off;
--	}
-+	if (axp20x->variant != AXP288_ID)
-+		devm_register_sys_off_handler(axp20x->dev,
-+					      SYS_OFF_MODE_POWER_OFF,
-+					      SYS_OFF_PRIO_DEFAULT,
-+					      axp20x_power_off, axp20x);
- 
- 	dev_info(axp20x->dev, "AXP20X driver loaded\n");
- 
-@@ -1022,11 +1340,6 @@ EXPORT_SYMBOL(axp20x_device_probe);
- 
- void axp20x_device_remove(struct axp20x_dev *axp20x)
- {
--	if (axp20x == axp20x_pm_power_off) {
--		axp20x_pm_power_off = NULL;
--		pm_power_off = NULL;
--	}
--
- 	mfd_remove_devices(axp20x->dev);
- 	regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
- }
---- a/include/linux/mfd/axp20x.h
-+++ b/include/linux/mfd/axp20x.h
-@@ -12,18 +12,22 @@
- 
- enum axp20x_variants {
- 	AXP152_ID = 0,
-+	AXP192_ID,
- 	AXP202_ID,
- 	AXP209_ID,
- 	AXP221_ID,
- 	AXP223_ID,
- 	AXP288_ID,
-+	AXP313A_ID,
- 	AXP803_ID,
- 	AXP806_ID,
- 	AXP809_ID,
- 	AXP813_ID,
-+	AXP15060_ID,
- 	NR_AXP20X_VARIANTS,
- };
- 
-+#define AXP192_DATACACHE(m)		(0x06 + (m))
- #define AXP20X_DATACACHE(m)		(0x04 + (m))
- 
- /* Power supply */
-@@ -45,6 +49,13 @@ enum axp20x_variants {
- #define AXP152_DCDC_FREQ		0x37
- #define AXP152_DCDC_MODE		0x80
- 
-+#define AXP192_USB_OTG_STATUS		0x04
-+#define AXP192_PWR_OUT_CTRL		0x12
-+#define AXP192_DCDC2_V_OUT		0x23
-+#define AXP192_DCDC1_V_OUT		0x26
-+#define AXP192_DCDC3_V_OUT		0x27
-+#define AXP192_LDO2_3_V_OUT		0x28
-+
- #define AXP20X_PWR_INPUT_STATUS		0x00
- #define AXP20X_PWR_OP_MODE		0x01
- #define AXP20X_USB_OTG_STATUS		0x02
-@@ -91,6 +102,17 @@ enum axp20x_variants {
- #define AXP22X_ALDO3_V_OUT		0x2a
- #define AXP22X_CHRG_CTRL3		0x35
- 
-+#define AXP313A_ON_INDICATE		0x00
-+#define AXP313A_OUTPUT_CONTROL		0x10
-+#define AXP313A_DCDC1_CONRTOL		0x13
-+#define AXP313A_DCDC2_CONRTOL		0x14
-+#define AXP313A_DCDC3_CONRTOL		0x15
-+#define AXP313A_ALDO1_CONRTOL		0x16
-+#define AXP313A_DLDO1_CONRTOL		0x17
-+#define AXP313A_SHUTDOWN_CTRL		0x1a
-+#define AXP313A_IRQ_EN			0x20
-+#define AXP313A_IRQ_STATE		0x21
-+
- #define AXP806_STARTUP_SRC		0x00
- #define AXP806_CHIP_ID			0x03
- #define AXP806_PWR_OUT_CTRL1		0x10
-@@ -131,6 +153,39 @@ enum axp20x_variants {
- /* Other DCDC regulator control registers are the same as AXP803 */
- #define AXP813_DCDC7_V_OUT		0x26
- 
-+#define AXP15060_STARTUP_SRC		0x00
-+#define AXP15060_PWR_OUT_CTRL1		0x10
-+#define AXP15060_PWR_OUT_CTRL2		0x11
-+#define AXP15060_PWR_OUT_CTRL3		0x12
-+#define AXP15060_DCDC1_V_CTRL		0x13
-+#define AXP15060_DCDC2_V_CTRL		0x14
-+#define AXP15060_DCDC3_V_CTRL		0x15
-+#define AXP15060_DCDC4_V_CTRL		0x16
-+#define AXP15060_DCDC5_V_CTRL		0x17
-+#define AXP15060_DCDC6_V_CTRL		0x18
-+#define AXP15060_ALDO1_V_CTRL		0x19
-+#define AXP15060_DCDC_MODE_CTRL1		0x1a
-+#define AXP15060_DCDC_MODE_CTRL2		0x1b
-+#define AXP15060_OUTPUT_MONITOR_DISCHARGE		0x1e
-+#define AXP15060_IRQ_PWROK_VOFF		0x1f
-+#define AXP15060_ALDO2_V_CTRL		0x20
-+#define AXP15060_ALDO3_V_CTRL		0x21
-+#define AXP15060_ALDO4_V_CTRL		0x22
-+#define AXP15060_ALDO5_V_CTRL		0x23
-+#define AXP15060_BLDO1_V_CTRL		0x24
-+#define AXP15060_BLDO2_V_CTRL		0x25
-+#define AXP15060_BLDO3_V_CTRL		0x26
-+#define AXP15060_BLDO4_V_CTRL		0x27
-+#define AXP15060_BLDO5_V_CTRL		0x28
-+#define AXP15060_CLDO1_V_CTRL		0x29
-+#define AXP15060_CLDO2_V_CTRL		0x2a
-+#define AXP15060_CLDO3_V_CTRL		0x2b
-+#define AXP15060_CLDO4_V_CTRL		0x2d
-+#define AXP15060_CPUSLDO_V_CTRL		0x2e
-+#define AXP15060_PWR_WAKEUP_CTRL		0x31
-+#define AXP15060_PWR_DISABLE_DOWN_SEQ		0x32
-+#define AXP15060_PEK_KEY		0x36
-+
- /* Interrupt */
- #define AXP152_IRQ1_EN			0x40
- #define AXP152_IRQ2_EN			0x41
-@@ -139,6 +194,17 @@ enum axp20x_variants {
- #define AXP152_IRQ2_STATE		0x49
- #define AXP152_IRQ3_STATE		0x4a
- 
-+#define AXP192_IRQ1_EN			0x40
-+#define AXP192_IRQ2_EN			0x41
-+#define AXP192_IRQ3_EN			0x42
-+#define AXP192_IRQ4_EN			0x43
-+#define AXP192_IRQ1_STATE		0x44
-+#define AXP192_IRQ2_STATE		0x45
-+#define AXP192_IRQ3_STATE		0x46
-+#define AXP192_IRQ4_STATE		0x47
-+#define AXP192_IRQ5_EN			0x4a
-+#define AXP192_IRQ5_STATE		0x4d
-+
- #define AXP20X_IRQ1_EN			0x40
- #define AXP20X_IRQ2_EN			0x41
- #define AXP20X_IRQ3_EN			0x42
-@@ -152,7 +218,17 @@ enum axp20x_variants {
- #define AXP20X_IRQ5_STATE		0x4c
- #define AXP20X_IRQ6_STATE		0x4d
- 
-+#define AXP15060_IRQ1_EN		0x40
-+#define AXP15060_IRQ2_EN		0x41
-+#define AXP15060_IRQ1_STATE		0x48
-+#define AXP15060_IRQ2_STATE		0x49
-+
- /* ADC */
-+#define AXP192_GPIO2_V_ADC_H		0x68
-+#define AXP192_GPIO2_V_ADC_L		0x69
-+#define AXP192_GPIO3_V_ADC_H		0x6a
-+#define AXP192_GPIO3_V_ADC_L		0x6b
-+
- #define AXP20X_ACIN_V_ADC_H		0x56
- #define AXP20X_ACIN_V_ADC_L		0x57
- #define AXP20X_ACIN_I_ADC_H		0x58
-@@ -182,6 +258,8 @@ enum axp20x_variants {
- #define AXP20X_IPSOUT_V_HIGH_L		0x7f
- 
- /* Power supply */
-+#define AXP192_GPIO30_IN_RANGE		0x85
-+
- #define AXP20X_DCDC_MODE		0x80
- #define AXP20X_ADC_EN1			0x82
- #define AXP20X_ADC_EN2			0x83
-@@ -210,6 +288,16 @@ enum axp20x_variants {
- #define AXP152_PWM1_FREQ_Y		0x9c
- #define AXP152_PWM1_DUTY_CYCLE		0x9d
- 
-+#define AXP192_GPIO0_CTRL		0x90
-+#define AXP192_LDO_IO0_V_OUT		0x91
-+#define AXP192_GPIO1_CTRL		0x92
-+#define AXP192_GPIO2_CTRL		0x93
-+#define AXP192_GPIO2_0_STATE		0x94
-+#define AXP192_GPIO4_3_CTRL		0x95
-+#define AXP192_GPIO4_3_STATE		0x96
-+#define AXP192_GPIO2_0_PULL		0x97
-+#define AXP192_N_RSTO_CTRL		0x9e
-+
- #define AXP20X_GPIO0_CTRL		0x90
- #define AXP20X_LDO5_V_OUT		0x91
- #define AXP20X_GPIO1_CTRL		0x92
-@@ -222,6 +310,8 @@ enum axp20x_variants {
- #define AXP22X_GPIO_STATE		0x94
- #define AXP22X_GPIO_PULL_DOWN		0x95
- 
-+#define AXP15060_CLDO4_GPIO2_MODESET		0x2c
-+
- /* Battery */
- #define AXP20X_CHRG_CC_31_24		0xb0
- #define AXP20X_CHRG_CC_23_16		0xb1
-@@ -288,6 +378,17 @@ enum axp20x_variants {
- 
- /* Regulators IDs */
- enum {
-+	AXP192_DCDC1 = 0,
-+	AXP192_DCDC2,
-+	AXP192_DCDC3,
-+	AXP192_LDO1,
-+	AXP192_LDO2,
-+	AXP192_LDO3,
-+	AXP192_LDO_IO0,
-+	AXP192_REG_ID_MAX
-+};
-+
-+enum {
- 	AXP20X_LDO1 = 0,
- 	AXP20X_LDO2,
- 	AXP20X_LDO3,
-@@ -323,6 +424,16 @@ enum {
- };
- 
- enum {
-+	AXP313A_DCDC1 = 0,
-+	AXP313A_DCDC2,
-+	AXP313A_DCDC3,
-+	AXP313A_ALDO1,
-+	AXP313A_DLDO1,
-+	AXP313A_RTC_LDO,
-+	AXP313A_REG_ID_MAX,
-+};
-+
-+enum {
- 	AXP806_DCDCA = 0,
- 	AXP806_DCDCB,
- 	AXP806_DCDCC,
-@@ -419,6 +530,33 @@ enum {
- 	AXP813_REG_ID_MAX,
- };
- 
-+enum {
-+	AXP15060_DCDC1 = 0,
-+	AXP15060_DCDC2,
-+	AXP15060_DCDC3,
-+	AXP15060_DCDC4,
-+	AXP15060_DCDC5,
-+	AXP15060_DCDC6,
-+	AXP15060_ALDO1,
-+	AXP15060_ALDO2,
-+	AXP15060_ALDO3,
-+	AXP15060_ALDO4,
-+	AXP15060_ALDO5,
-+	AXP15060_BLDO1,
-+	AXP15060_BLDO2,
-+	AXP15060_BLDO3,
-+	AXP15060_BLDO4,
-+	AXP15060_BLDO5,
-+	AXP15060_CLDO1,
-+	AXP15060_CLDO2,
-+	AXP15060_CLDO3,
-+	AXP15060_CLDO4,
-+	AXP15060_CPUSLDO,
-+	AXP15060_SW,
-+	AXP15060_RTC_LDO,
-+	AXP15060_REG_ID_MAX,
-+};
-+
- /* IRQs */
- enum {
- 	AXP152_IRQ_LDO0IN_CONNECT = 1,
-@@ -432,14 +570,51 @@ enum {
- 	AXP152_IRQ_PEK_SHORT,
- 	AXP152_IRQ_PEK_LONG,
- 	AXP152_IRQ_TIMER,
--	AXP152_IRQ_PEK_RIS_EDGE,
-+	/* out of bit order to make sure the press event is handled first */
- 	AXP152_IRQ_PEK_FAL_EDGE,
-+	AXP152_IRQ_PEK_RIS_EDGE,
- 	AXP152_IRQ_GPIO3_INPUT,
- 	AXP152_IRQ_GPIO2_INPUT,
- 	AXP152_IRQ_GPIO1_INPUT,
- 	AXP152_IRQ_GPIO0_INPUT,
- };
- 
-+enum axp192_irqs {
-+	AXP192_IRQ_ACIN_OVER_V = 1,
-+	AXP192_IRQ_ACIN_PLUGIN,
-+	AXP192_IRQ_ACIN_REMOVAL,
-+	AXP192_IRQ_VBUS_OVER_V,
-+	AXP192_IRQ_VBUS_PLUGIN,
-+	AXP192_IRQ_VBUS_REMOVAL,
-+	AXP192_IRQ_VBUS_V_LOW,
-+	AXP192_IRQ_BATT_PLUGIN,
-+	AXP192_IRQ_BATT_REMOVAL,
-+	AXP192_IRQ_BATT_ENT_ACT_MODE,
-+	AXP192_IRQ_BATT_EXIT_ACT_MODE,
-+	AXP192_IRQ_CHARG,
-+	AXP192_IRQ_CHARG_DONE,
-+	AXP192_IRQ_BATT_TEMP_HIGH,
-+	AXP192_IRQ_BATT_TEMP_LOW,
-+	AXP192_IRQ_DIE_TEMP_HIGH,
-+	AXP192_IRQ_CHARG_I_LOW,
-+	AXP192_IRQ_DCDC1_V_LONG,
-+	AXP192_IRQ_DCDC2_V_LONG,
-+	AXP192_IRQ_DCDC3_V_LONG,
-+	AXP192_IRQ_PEK_SHORT = 22,
-+	AXP192_IRQ_PEK_LONG,
-+	AXP192_IRQ_N_OE_PWR_ON,
-+	AXP192_IRQ_N_OE_PWR_OFF,
-+	AXP192_IRQ_VBUS_VALID,
-+	AXP192_IRQ_VBUS_NOT_VALID,
-+	AXP192_IRQ_VBUS_SESS_VALID,
-+	AXP192_IRQ_VBUS_SESS_END,
-+	AXP192_IRQ_LOW_PWR_LVL = 31,
-+	AXP192_IRQ_TIMER,
-+	AXP192_IRQ_GPIO2_INPUT = 37,
-+	AXP192_IRQ_GPIO1_INPUT,
-+	AXP192_IRQ_GPIO0_INPUT,
-+};
-+
- enum {
- 	AXP20X_IRQ_ACIN_OVER_V = 1,
- 	AXP20X_IRQ_ACIN_PLUGIN,
-@@ -472,8 +647,9 @@ enum {
- 	AXP20X_IRQ_LOW_PWR_LVL1,
- 	AXP20X_IRQ_LOW_PWR_LVL2,
- 	AXP20X_IRQ_TIMER,
--	AXP20X_IRQ_PEK_RIS_EDGE,
-+	/* out of bit order to make sure the press event is handled first */
- 	AXP20X_IRQ_PEK_FAL_EDGE,
-+	AXP20X_IRQ_PEK_RIS_EDGE,
- 	AXP20X_IRQ_GPIO3_INPUT,
- 	AXP20X_IRQ_GPIO2_INPUT,
- 	AXP20X_IRQ_GPIO1_INPUT,
-@@ -502,8 +678,9 @@ enum axp22x_irqs {
- 	AXP22X_IRQ_LOW_PWR_LVL1,
- 	AXP22X_IRQ_LOW_PWR_LVL2,
- 	AXP22X_IRQ_TIMER,
--	AXP22X_IRQ_PEK_RIS_EDGE,
-+	/* out of bit order to make sure the press event is handled first */
- 	AXP22X_IRQ_PEK_FAL_EDGE,
-+	AXP22X_IRQ_PEK_RIS_EDGE,
- 	AXP22X_IRQ_GPIO1_INPUT,
- 	AXP22X_IRQ_GPIO0_INPUT,
- };
-@@ -545,6 +722,16 @@ enum axp288_irqs {
- 	AXP288_IRQ_BC_USB_CHNG,
- };
- 
-+enum axp313a_irqs {
-+	AXP313A_IRQ_DIE_TEMP_HIGH,
-+	AXP313A_IRQ_DCDC2_V_LOW = 2,
-+	AXP313A_IRQ_DCDC3_V_LOW,
-+	AXP313A_IRQ_PEK_LONG,
-+	AXP313A_IRQ_PEK_SHORT,
-+	AXP313A_IRQ_PEK_FAL_EDGE,
-+	AXP313A_IRQ_PEK_RIS_EDGE,
-+};
-+
- enum axp803_irqs {
- 	AXP803_IRQ_ACIN_OVER_V = 1,
- 	AXP803_IRQ_ACIN_PLUGIN,
-@@ -571,8 +758,9 @@ enum axp803_irqs {
- 	AXP803_IRQ_LOW_PWR_LVL1,
- 	AXP803_IRQ_LOW_PWR_LVL2,
- 	AXP803_IRQ_TIMER,
--	AXP803_IRQ_PEK_RIS_EDGE,
-+	/* out of bit order to make sure the press event is handled first */
- 	AXP803_IRQ_PEK_FAL_EDGE,
-+	AXP803_IRQ_PEK_RIS_EDGE,
- 	AXP803_IRQ_PEK_SHORT,
- 	AXP803_IRQ_PEK_LONG,
- 	AXP803_IRQ_PEK_OVER_OFF,
-@@ -623,8 +811,9 @@ enum axp809_irqs {
- 	AXP809_IRQ_LOW_PWR_LVL1,
- 	AXP809_IRQ_LOW_PWR_LVL2,
- 	AXP809_IRQ_TIMER,
--	AXP809_IRQ_PEK_RIS_EDGE,
-+	/* out of bit order to make sure the press event is handled first */
- 	AXP809_IRQ_PEK_FAL_EDGE,
-+	AXP809_IRQ_PEK_RIS_EDGE,
- 	AXP809_IRQ_PEK_SHORT,
- 	AXP809_IRQ_PEK_LONG,
- 	AXP809_IRQ_PEK_OVER_OFF,
-@@ -632,6 +821,23 @@ enum axp809_irqs {
- 	AXP809_IRQ_GPIO0_INPUT,
- };
- 
-+enum axp15060_irqs {
-+	AXP15060_IRQ_DIE_TEMP_HIGH_LV1 = 1,
-+	AXP15060_IRQ_DIE_TEMP_HIGH_LV2,
-+	AXP15060_IRQ_DCDC1_V_LOW,
-+	AXP15060_IRQ_DCDC2_V_LOW,
-+	AXP15060_IRQ_DCDC3_V_LOW,
-+	AXP15060_IRQ_DCDC4_V_LOW,
-+	AXP15060_IRQ_DCDC5_V_LOW,
-+	AXP15060_IRQ_DCDC6_V_LOW,
-+	AXP15060_IRQ_PEK_LONG,
-+	AXP15060_IRQ_PEK_SHORT,
-+	AXP15060_IRQ_GPIO1_INPUT,
-+	AXP15060_IRQ_PEK_FAL_EDGE,
-+	AXP15060_IRQ_PEK_RIS_EDGE,
-+	AXP15060_IRQ_GPIO2_INPUT,
-+};
-+
- struct axp20x_dev {
- 	struct device			*dev;
- 	int				irq;
-@@ -698,4 +904,4 @@ int axp20x_device_probe(struct axp20x_de
-  */
- void axp20x_device_remove(struct axp20x_dev *axp20x);
- 
--#endif /* __LINUX_MFD_AXP20X_H */
-+#endif /* __LINUX_MFD_AXP20X_H */
-\ No newline at end of file




More information about the lede-commits mailing list