* [PATCH v7 1/8] staging: phy-hi3670-usb3: do a some minor cleanups
2021-06-24 14:01 [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Mauro Carvalho Chehab
@ 2021-06-24 14:01 ` Mauro Carvalho Chehab
2021-06-24 14:01 ` [PATCH v7 2/8] staging: hisi-spmi-controller: rename spmi-channel property Mauro Carvalho Chehab
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2021-06-24 14:01 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
linux-kernel, linux-staging
Before moving this driver out of staging:
1. group some integers altogether;
2. Use:
return some_function()
instead of:
ret = some_function();
return ret;
This is just a cleanup. No functional changes.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
drivers/staging/hikey9xx/phy-hi3670-usb3.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/hikey9xx/phy-hi3670-usb3.c b/drivers/staging/hikey9xx/phy-hi3670-usb3.c
index e7e579ce0302..b9ffe08abaab 100644
--- a/drivers/staging/hikey9xx/phy-hi3670-usb3.c
+++ b/drivers/staging/hikey9xx/phy-hi3670-usb3.c
@@ -148,10 +148,8 @@ static int hi3670_phy_cr_clk(struct regmap *usb31misc)
return ret;
/* Clock down */
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_CLK, 0);
-
- return ret;
+ return regmap_update_bits(usb31misc, USB_MISC_CFG54,
+ CFG54_USB31PHY_CR_CLK, 0);
}
static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
@@ -215,17 +213,14 @@ static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
return ret;
reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr);
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_ADDR_MASK, reg);
- return ret;
+ return regmap_update_bits(usb31misc, USB_MISC_CFG54,
+ CFG54_USB31PHY_CR_ADDR_MASK, reg);
}
static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
{
- int reg;
- int i;
- int ret;
+ int reg, i, ret;
for (i = 0; i < 100; i++) {
ret = hi3670_phy_cr_clk(usb31misc);
@@ -286,9 +281,7 @@ static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
if (ret)
return ret;
- ret = hi3670_phy_cr_wait_ack(usb31misc);
-
- return ret;
+ return hi3670_phy_cr_wait_ack(usb31misc);
}
static int hi3670_phy_set_params(struct hi3670_priv *priv)
--
2.31.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 2/8] staging: hisi-spmi-controller: rename spmi-channel property
2021-06-24 14:01 [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Mauro Carvalho Chehab
2021-06-24 14:01 ` [PATCH v7 1/8] staging: phy-hi3670-usb3: do a some minor cleanups Mauro Carvalho Chehab
@ 2021-06-24 14:01 ` Mauro Carvalho Chehab
2021-06-24 14:01 ` [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups Mauro Carvalho Chehab
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2021-06-24 14:01 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
linux-kernel, linux-staging
The spmi-channel is not used on other drivers. So, rename it,
in order to document that this is specific to those devices.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
drivers/staging/hikey9xx/hisi-spmi-controller.c | 2 +-
.../hikey9xx/hisilicon,hisi-spmi-controller.yaml | 10 ++++++----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index 0d42bc65f39b..5bd23262abd6 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -290,7 +290,7 @@ static int spmi_controller_probe(struct platform_device *pdev)
goto err_put_controller;
}
- ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel",
+ ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel",
&spmi_controller->channel);
if (ret) {
dev_err(&pdev->dev, "can not get channel\n");
diff --git a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
index 6b755039a74c..f882903769f9 100644
--- a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
+++ b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
@@ -14,7 +14,7 @@ description: |
It is a MIPI System Power Management (SPMI) controller.
The PMIC part is provided by
- drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml.
+ ./Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml.
allOf:
- $ref: spmi.yaml#
@@ -30,7 +30,7 @@ properties:
reg:
maxItems: 1
- spmi-channel:
+ hisilicon,spmi-channel:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
number of the Kirin 970 SPMI channel where the SPMI devices are connected.
@@ -38,10 +38,12 @@ properties:
required:
- compatible
- reg
- - spmi-channel
+ - hisilicon,spmi-channel
patternProperties:
"@[0-9a-f]$":
+ type: object
+
description: |
PMIC properties, which are specific to the used SPMI PMIC device(s).
When used in combination with HiSilicon 6421v600, the properties
@@ -61,7 +63,7 @@ examples:
#address-cells = <2>;
#size-cells = <0>;
reg = <0x0 0xfff24000 0x0 0x1000>;
- spmi-channel = <2>;
+ hisilicon,spmi-channel = <2>;
pmic@0 {
reg = <0 0>;
--
2.31.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups
2021-06-24 14:01 [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Mauro Carvalho Chehab
2021-06-24 14:01 ` [PATCH v7 1/8] staging: phy-hi3670-usb3: do a some minor cleanups Mauro Carvalho Chehab
2021-06-24 14:01 ` [PATCH v7 2/8] staging: hisi-spmi-controller: rename spmi-channel property Mauro Carvalho Chehab
@ 2021-06-24 14:01 ` Mauro Carvalho Chehab
2021-06-24 14:26 ` Greg Kroah-Hartman
2021-06-24 14:27 ` Greg Kroah-Hartman
2021-06-24 14:01 ` [PATCH v7 4/8] phy: phy-hi3670-usb3: move driver from staging into phy Mauro Carvalho Chehab
` (3 subsequent siblings)
6 siblings, 2 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2021-06-24 14:01 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
linux-kernel, linux-staging
Before moving this driver out of staging, do a couple of
cleanups, in order to make the driver clearer.
No functional changes.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 122 ++++++++++--------
.../hikey9xx/hisilicon,hi6421-spmi-pmic.yaml | 7 +-
2 files changed, 71 insertions(+), 58 deletions(-)
diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index 626140cb96f2..252b731e272d 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -2,9 +2,9 @@
/*
* Device driver for regulators in HISI PMIC IC
*
- * Copyright (c) 2013 Linaro Ltd.
- * Copyright (c) 2011 Hisilicon.
- * Copyright (c) 2020-2021 Huawei Technologies Co., Ltd
+ * Copyright (c) 2013- Linaro Ltd.
+ * Copyright (c) 2011- Hisilicon.
+ * Copyright (c) 2020- Huawei Technologies Co., Ltd
*/
#include <linux/bitops.h>
@@ -33,17 +33,27 @@ enum hi6421_spmi_pmic_irq_list {
SIM0_HPD_F,
SIM1_HPD_R,
SIM1_HPD_F,
- PMIC_IRQ_LIST_MAX,
+
+ PMIC_IRQ_LIST_MAX
};
-#define HISI_IRQ_ARRAY 2
-#define HISI_IRQ_NUM (HISI_IRQ_ARRAY * 8)
+#define HISI_IRQ_BANK_SIZE 2
-#define HISI_IRQ_KEY_NUM 0
+/*
+ * IRQ number for the power key button and mask for both UP and DOWN IRQs
+ */
+#define HISI_POWERKEY_IRQ_NUM 0
+#define HISI_IRQ_POWERKEY_UP_DOWN (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
-#define HISI_BITS 8
-#define HISI_IRQ_KEY_VALUE (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
-#define HISI_MASK GENMASK(HISI_BITS - 1, 0)
+/*
+ * Registers for IRQ address and IRQ mask bits
+ *
+ * Please notice that we need to regmap a larger region, as other
+ * registers are used by the regulators.
+ * See drivers/regulator/hi6421-regulator.c.
+ */
+#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202
+#define SOC_PMIC_IRQ0_ADDR 0x0212
/*
* The IRQs are mapped as:
@@ -67,13 +77,14 @@ enum hi6421_spmi_pmic_irq_list {
* SIM1_HPD_R 0x0203 0x213 bit 4
* SIM1_HPD_F 0x0203 0x213 bit 5
* ====================== ============= ============ =====
+ *
+ * Each mask register contains 8 bits. The ancillary macros below
+ * convert a number from 0 to 14 into a register address and a bit mask
*/
-#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202
-#define SOC_PMIC_IRQ0_ADDR 0x0212
-
-#define IRQ_MASK_REGISTER(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \
- (irqd_to_hwirq(irq_data) >> 3))
-#define IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & 0x07)
+#define HISI_IRQ_MASK_REG(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \
+ (irqd_to_hwirq(irq_data) / BITS_PER_BYTE))
+#define HISI_IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & (BITS_PER_BYTE - 1))
+#define HISI_8BITS_MASK 0xff
static const struct mfd_cell hi6421v600_devs[] = {
{ .name = "hi6421v600-regulator", },
@@ -86,23 +97,31 @@ static irqreturn_t hi6421_spmi_irq_handler(int irq, void *priv)
unsigned int in;
int i, offset;
- for (i = 0; i < HISI_IRQ_ARRAY; i++) {
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &in);
- pending = HISI_MASK & in;
- regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, pending);
- if (i == HISI_IRQ_KEY_NUM &&
- (pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE) {
+ /* Mark pending IRQs as handled */
+ regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, in);
+
+ pending = in & HISI_8BITS_MASK;
+
+ if (i == HISI_POWERKEY_IRQ_NUM &&
+ (pending & HISI_IRQ_POWERKEY_UP_DOWN) == HISI_IRQ_POWERKEY_UP_DOWN) {
+ /*
+ * If both powerkey down and up IRQs are received,
+ * handle them at the right order
+ */
generic_handle_irq(ddata->irqs[POWERKEY_DOWN]);
generic_handle_irq(ddata->irqs[POWERKEY_UP]);
- pending &= (~HISI_IRQ_KEY_VALUE);
+ pending &= ~HISI_IRQ_POWERKEY_UP_DOWN;
}
if (!pending)
continue;
- for_each_set_bit(offset, &pending, HISI_BITS)
- generic_handle_irq(ddata->irqs[offset + i * HISI_BITS]);
+ for_each_set_bit(offset, &pending, BITS_PER_BYTE) {
+ generic_handle_irq(ddata->irqs[offset + i * BITS_PER_BYTE]);
+ }
}
return IRQ_HANDLED;
@@ -115,12 +134,12 @@ static void hi6421_spmi_irq_mask(struct irq_data *d)
unsigned int data;
u32 offset;
- offset = IRQ_MASK_REGISTER(d);
+ offset = HISI_IRQ_MASK_REG(d);
spin_lock_irqsave(&ddata->lock, flags);
regmap_read(ddata->regmap, offset, &data);
- data |= IRQ_MASK_BIT(d);
+ data |= HISI_IRQ_MASK_BIT(d);
regmap_write(ddata->regmap, offset, data);
spin_unlock_irqrestore(&ddata->lock, flags);
@@ -132,20 +151,19 @@ static void hi6421_spmi_irq_unmask(struct irq_data *d)
u32 data, offset;
unsigned long flags;
- offset = (irqd_to_hwirq(d) >> 3);
- offset += SOC_PMIC_IRQ_MASK_0_ADDR;
+ offset = HISI_IRQ_MASK_REG(d);
spin_lock_irqsave(&ddata->lock, flags);
regmap_read(ddata->regmap, offset, &data);
- data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
+ data &= ~HISI_IRQ_MASK_BIT(d);
regmap_write(ddata->regmap, offset, data);
spin_unlock_irqrestore(&ddata->lock, flags);
}
static struct irq_chip hi6421_spmi_pmu_irqchip = {
- .name = "hisi-irq",
+ .name = "hi6421v600-irq",
.irq_mask = hi6421_spmi_irq_mask,
.irq_unmask = hi6421_spmi_irq_unmask,
.irq_disable = hi6421_spmi_irq_mask,
@@ -158,7 +176,7 @@ static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq,
struct hi6421_spmi_pmic *ddata = d->host_data;
irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip,
- handle_simple_irq, "hisi");
+ handle_simple_irq, "hi6421v600");
irq_set_chip_data(virq, ddata);
irq_set_irq_type(virq, IRQ_TYPE_NONE);
@@ -175,22 +193,24 @@ static void hi6421_spmi_pmic_irq_init(struct hi6421_spmi_pmic *ddata)
int i;
unsigned int pending;
- for (i = 0; i < HISI_IRQ_ARRAY; i++)
+ /* Mask all IRQs */
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++)
regmap_write(ddata->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i,
- HISI_MASK);
+ HISI_8BITS_MASK);
- for (i = 0; i < HISI_IRQ_ARRAY; i++) {
+ /* Mark all IRQs as handled */
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending);
regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i,
- HISI_MASK);
+ HISI_8BITS_MASK);
}
}
static const struct regmap_config regmap_config = {
- .reg_bits = 16,
- .val_bits = HISI_BITS,
- .max_register = 0xffff,
- .fast_io = true
+ .reg_bits = 16,
+ .val_bits = BITS_PER_BYTE,
+ .max_register = 0xffff,
+ .fast_io = true
};
static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
@@ -230,29 +250,31 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
hi6421_spmi_pmic_irq_init(ddata);
- ddata->irqs = devm_kzalloc(dev, HISI_IRQ_NUM * sizeof(int), GFP_KERNEL);
+ ddata->irqs = devm_kzalloc(dev, PMIC_IRQ_LIST_MAX * sizeof(int), GFP_KERNEL);
if (!ddata->irqs)
return -ENOMEM;
- ddata->domain = irq_domain_add_simple(np, HISI_IRQ_NUM, 0,
+ ddata->domain = irq_domain_add_simple(np, PMIC_IRQ_LIST_MAX, 0,
&hi6421_spmi_domain_ops, ddata);
if (!ddata->domain) {
dev_err(dev, "Failed to create IRQ domain\n");
return -ENODEV;
}
- for (i = 0; i < HISI_IRQ_NUM; i++) {
+ for (i = 0; i < PMIC_IRQ_LIST_MAX; i++) {
virq = irq_create_mapping(ddata->domain, i);
if (!virq) {
dev_err(dev, "Failed to map H/W IRQ\n");
- return -ENOSPC;
+ return -ENODEV;
}
ddata->irqs[i] = virq;
}
- ret = request_threaded_irq(ddata->irq, hi6421_spmi_irq_handler, NULL,
- IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
- "pmic", ddata);
+ ret = devm_request_threaded_irq(dev,
+ ddata->irq, hi6421_spmi_irq_handler,
+ NULL,
+ IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
+ "pmic", ddata);
if (ret < 0) {
dev_err(dev, "Failed to start IRQ handling thread: error %d\n",
ret);
@@ -270,13 +292,6 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
return ret;
}
-static void hi6421_spmi_pmic_remove(struct spmi_device *pdev)
-{
- struct hi6421_spmi_pmic *ddata = dev_get_drvdata(&pdev->dev);
-
- free_irq(ddata->irq, ddata);
-}
-
static const struct of_device_id pmic_spmi_id_table[] = {
{ .compatible = "hisilicon,hi6421-spmi" },
{ }
@@ -289,7 +304,6 @@ static struct spmi_driver hi6421_spmi_pmic_driver = {
.of_match_table = pmic_spmi_id_table,
},
.probe = hi6421_spmi_pmic_probe,
- .remove = hi6421_spmi_pmic_remove,
};
module_spmi_driver(hi6421_spmi_pmic_driver);
diff --git a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
index 3b23ad56b31a..8e355cddd437 100644
--- a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
+++ b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
@@ -17,7 +17,7 @@ description: |
node.
The SPMI controller part is provided by
- drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml.
+ Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
properties:
$nodename:
@@ -32,12 +32,11 @@ properties:
'#interrupt-cells':
const: 2
- interrupt-controller:
- description:
- Identify that the PMIC is capable of behaving as an interrupt controller.
+ interrupt-controller: true
gpios:
maxItems: 1
+ description: GPIO used for IRQs
regulators:
type: object
--
2.31.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups
2021-06-24 14:01 ` [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups Mauro Carvalho Chehab
@ 2021-06-24 14:26 ` Greg Kroah-Hartman
2021-06-24 15:43 ` Mauro Carvalho Chehab
2021-06-24 14:27 ` Greg Kroah-Hartman
1 sibling, 1 reply; 12+ messages in thread
From: Greg Kroah-Hartman @ 2021-06-24 14:26 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: linuxarm, mauro.chehab, Lee Jones, linux-kernel, linux-staging
On Thu, Jun 24, 2021 at 04:01:32PM +0200, Mauro Carvalho Chehab wrote:
> Before moving this driver out of staging, do a couple of
> cleanups, in order to make the driver clearer.
>
> No functional changes.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> ---
> drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 122 ++++++++++--------
> .../hikey9xx/hisilicon,hi6421-spmi-pmic.yaml | 7 +-
> 2 files changed, 71 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> index 626140cb96f2..252b731e272d 100644
> --- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> +++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> @@ -2,9 +2,9 @@
> /*
> * Device driver for regulators in HISI PMIC IC
> *
> - * Copyright (c) 2013 Linaro Ltd.
> - * Copyright (c) 2011 Hisilicon.
> - * Copyright (c) 2020-2021 Huawei Technologies Co., Ltd
> + * Copyright (c) 2013- Linaro Ltd.
> + * Copyright (c) 2011- Hisilicon.
What does the "-" mean here? That does not mean from 2013-present.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups
2021-06-24 14:26 ` Greg Kroah-Hartman
@ 2021-06-24 15:43 ` Mauro Carvalho Chehab
2021-06-24 16:49 ` Greg Kroah-Hartman
0 siblings, 1 reply; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2021-06-24 15:43 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linuxarm, mauro.chehab, Lee Jones, linux-kernel, linux-staging
Em Thu, 24 Jun 2021 16:26:41 +0200
Greg Kroah-Hartman <gregkh@linuxfoundation.org> escreveu:
> On Thu, Jun 24, 2021 at 04:01:32PM +0200, Mauro Carvalho Chehab wrote:
> > Before moving this driver out of staging, do a couple of
> > cleanups, in order to make the driver clearer.
> >
> > No functional changes.
> >
> > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> > ---
> > drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 122 ++++++++++--------
> > .../hikey9xx/hisilicon,hi6421-spmi-pmic.yaml | 7 +-
> > 2 files changed, 71 insertions(+), 58 deletions(-)
> >
> > diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> > index 626140cb96f2..252b731e272d 100644
> > --- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> > +++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> > @@ -2,9 +2,9 @@
> > /*
> > * Device driver for regulators in HISI PMIC IC
> > *
> > - * Copyright (c) 2013 Linaro Ltd.
> > - * Copyright (c) 2011 Hisilicon.
> > - * Copyright (c) 2020-2021 Huawei Technologies Co., Ltd
> > + * Copyright (c) 2013- Linaro Ltd.
> > + * Copyright (c) 2011- Hisilicon.
>
> What does the "-" mean here? That does not mean from 2013-present.
I'm pretty sure I found some copyright notes using this convention
somewhere to mean "2013-present".
Is there a proper/recommended way to tell so?
Regards,
Mauro
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups
2021-06-24 15:43 ` Mauro Carvalho Chehab
@ 2021-06-24 16:49 ` Greg Kroah-Hartman
0 siblings, 0 replies; 12+ messages in thread
From: Greg Kroah-Hartman @ 2021-06-24 16:49 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: linuxarm, mauro.chehab, Lee Jones, linux-kernel, linux-staging
On Thu, Jun 24, 2021 at 05:43:22PM +0200, Mauro Carvalho Chehab wrote:
> Em Thu, 24 Jun 2021 16:26:41 +0200
> Greg Kroah-Hartman <gregkh@linuxfoundation.org> escreveu:
>
> > On Thu, Jun 24, 2021 at 04:01:32PM +0200, Mauro Carvalho Chehab wrote:
> > > Before moving this driver out of staging, do a couple of
> > > cleanups, in order to make the driver clearer.
> > >
> > > No functional changes.
> > >
> > > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> > > ---
> > > drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 122 ++++++++++--------
> > > .../hikey9xx/hisilicon,hi6421-spmi-pmic.yaml | 7 +-
> > > 2 files changed, 71 insertions(+), 58 deletions(-)
> > >
> > > diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> > > index 626140cb96f2..252b731e272d 100644
> > > --- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> > > +++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
> > > @@ -2,9 +2,9 @@
> > > /*
> > > * Device driver for regulators in HISI PMIC IC
> > > *
> > > - * Copyright (c) 2013 Linaro Ltd.
> > > - * Copyright (c) 2011 Hisilicon.
> > > - * Copyright (c) 2020-2021 Huawei Technologies Co., Ltd
> > > + * Copyright (c) 2013- Linaro Ltd.
> > > + * Copyright (c) 2011- Hisilicon.
> >
> > What does the "-" mean here? That does not mean from 2013-present.
>
> I'm pretty sure I found some copyright notes using this convention
> somewhere to mean "2013-present".
That is not a valid copyright date assignment listing. There is no way
to say something like this as it does not make any sense. The years
need to be listed individually or as a range.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups
2021-06-24 14:01 ` [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups Mauro Carvalho Chehab
2021-06-24 14:26 ` Greg Kroah-Hartman
@ 2021-06-24 14:27 ` Greg Kroah-Hartman
1 sibling, 0 replies; 12+ messages in thread
From: Greg Kroah-Hartman @ 2021-06-24 14:27 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: linuxarm, mauro.chehab, Lee Jones, linux-kernel, linux-staging
On Thu, Jun 24, 2021 at 04:01:32PM +0200, Mauro Carvalho Chehab wrote:
> Before moving this driver out of staging, do a couple of
> cleanups, in order to make the driver clearer.
Please break this up into "one logical change per patch"
thanks,
greg k-h
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v7 4/8] phy: phy-hi3670-usb3: move driver from staging into phy
2021-06-24 14:01 [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Mauro Carvalho Chehab
` (2 preceding siblings ...)
2021-06-24 14:01 ` [PATCH v7 3/8] staging: hi6421-spmi-pmic: do some additional cleanups Mauro Carvalho Chehab
@ 2021-06-24 14:01 ` Mauro Carvalho Chehab
2021-06-24 14:01 ` [PATCH v7 5/8] spmi: hisi-spmi-controller: move driver from staging Mauro Carvalho Chehab
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2021-06-24 14:01 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
Alex Dewar, Atul Gopinathan, Kishon Vijay Abraham I,
Mauro Carvalho Chehab, Rob Herring, Vinod Koul, Yu Chen,
devicetree, linux-kernel, linux-phy, linux-staging, linux-usb,
Rob Herring
The phy USB3 driver for Hisilicon 970 (hi3670) is ready
for mainstream. Mode it from staging into the main driver's
phy/ directory.
Acked-by: Rob Herring <robh@kernel.org>
Acked-By: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
.../bindings/phy/hisilicon,hi3670-usb3.yaml | 73 ++
MAINTAINERS | 9 +-
drivers/phy/hisilicon/Kconfig | 10 +
drivers/phy/hisilicon/Makefile | 1 +
drivers/phy/hisilicon/phy-hi3670-usb3.c | 661 ++++++++++++++++++
drivers/staging/hikey9xx/Kconfig | 11 -
drivers/staging/hikey9xx/Makefile | 2 -
drivers/staging/hikey9xx/phy-hi3670-usb3.c | 661 ------------------
drivers/staging/hikey9xx/phy-hi3670-usb3.yaml | 73 --
9 files changed, 753 insertions(+), 748 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml
create mode 100644 drivers/phy/hisilicon/phy-hi3670-usb3.c
delete mode 100644 drivers/staging/hikey9xx/phy-hi3670-usb3.c
delete mode 100644 drivers/staging/hikey9xx/phy-hi3670-usb3.yaml
diff --git a/Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml b/Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml
new file mode 100644
index 000000000000..ebd78acfe2de
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/hisilicon,hi3670-usb3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon Kirin970 USB PHY
+
+maintainers:
+ - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+description: |+
+ Bindings for USB3 PHY on HiSilicon Kirin 970.
+
+properties:
+ compatible:
+ const: hisilicon,hi3670-usb-phy
+
+ "#phy-cells":
+ const: 0
+
+ hisilicon,pericrg-syscon:
+ $ref: '/schemas/types.yaml#/definitions/phandle'
+ description: phandle of syscon used to control iso refclk.
+
+ hisilicon,pctrl-syscon:
+ $ref: '/schemas/types.yaml#/definitions/phandle'
+ description: phandle of syscon used to control usb tcxo.
+
+ hisilicon,sctrl-syscon:
+ $ref: '/schemas/types.yaml#/definitions/phandle'
+ description: phandle of syscon used to control phy deep sleep.
+
+ hisilicon,eye-diagram-param:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Eye diagram for phy.
+
+ hisilicon,tx-vboost-lvl:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: TX level vboost for phy.
+
+required:
+ - compatible
+ - hisilicon,pericrg-syscon
+ - hisilicon,pctrl-syscon
+ - hisilicon,sctrl-syscon
+ - hisilicon,eye-diagram-param
+ - hisilicon,tx-vboost-lvl
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ usb3_otg_bc: usb3_otg_bc@ff200000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x0 0xff200000 0x0 0x1000>;
+
+ usb_phy {
+ compatible = "hisilicon,hi3670-usb-phy";
+ #phy-cells = <0>;
+ hisilicon,pericrg-syscon = <&crg_ctrl>;
+ hisilicon,pctrl-syscon = <&pctrl>;
+ hisilicon,sctrl-syscon = <&sctrl>;
+ hisilicon,eye-diagram-param = <0xfdfee4>;
+ hisilicon,tx-vboost-lvl = <0x5>;
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 8c5ee008301a..6e01424234eb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18859,7 +18859,7 @@ L: linux-usb@vger.kernel.org
S: Maintained
F: drivers/usb/roles/intel-xhci-usb-role-switch.c
-USB IP DRIVER FOR HISILICON KIRIN
+USB IP DRIVER FOR HISILICON KIRIN 960
M: Yu Chen <chenyu56@huawei.com>
M: Binghui Wang <wangbinghui@hisilicon.com>
L: linux-usb@vger.kernel.org
@@ -18867,6 +18867,13 @@ S: Maintained
F: Documentation/devicetree/bindings/phy/hisilicon,hi3660-usb3.yaml
F: drivers/phy/hisilicon/phy-hi3660-usb3.c
+USB IP DRIVER FOR HISILICON KIRIN 970
+M: Mauro Carvalho Chehab <mchehab@kernel.org>
+L: linux-usb@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml
+F: drivers/phy/hisilicon/phy-kirin970-usb3.c
+
USB ISP116X DRIVER
M: Olav Kongas <ok@artecdesign.ee>
L: linux-usb@vger.kernel.org
diff --git a/drivers/phy/hisilicon/Kconfig b/drivers/phy/hisilicon/Kconfig
index 1c73053bcc98..4d008cfc279c 100644
--- a/drivers/phy/hisilicon/Kconfig
+++ b/drivers/phy/hisilicon/Kconfig
@@ -23,6 +23,16 @@ config PHY_HI3660_USB
To compile this driver as a module, choose M here.
+config PHY_HI3670_USB
+ tristate "hi3670 USB PHY support"
+ depends on (ARCH_HISI && ARM64) || COMPILE_TEST
+ select GENERIC_PHY
+ select MFD_SYSCON
+ help
+ Enable this to support the HISILICON HI3670 USB PHY.
+
+ To compile this driver as a module, choose M here.
+
config PHY_HISTB_COMBPHY
tristate "HiSilicon STB SoCs COMBPHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
diff --git a/drivers/phy/hisilicon/Makefile b/drivers/phy/hisilicon/Makefile
index 92e874ae9c74..51729868145b 100644
--- a/drivers/phy/hisilicon/Makefile
+++ b/drivers/phy/hisilicon/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o
obj-$(CONFIG_PHY_HI3660_USB) += phy-hi3660-usb3.o
+obj-$(CONFIG_PHY_HI3670_USB) += phy-hi3670-usb3.o
obj-$(CONFIG_PHY_HISTB_COMBPHY) += phy-histb-combphy.o
obj-$(CONFIG_PHY_HISI_INNO_USB2) += phy-hisi-inno-usb2.o
obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
diff --git a/drivers/phy/hisilicon/phy-hi3670-usb3.c b/drivers/phy/hisilicon/phy-hi3670-usb3.c
new file mode 100644
index 000000000000..b9ffe08abaab
--- /dev/null
+++ b/drivers/phy/hisilicon/phy-hi3670-usb3.c
@@ -0,0 +1,661 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
+ *
+ * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
+ * http://www.huawei.com
+ *
+ * Authors: Yu Chen <chenyu56@huawei.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define SCTRL_SCDEEPSLEEPED (0x0)
+#define USB_CLK_SELECTED BIT(20)
+
+#define PERI_CRG_PEREN0 (0x00)
+#define PERI_CRG_PERDIS0 (0x04)
+#define PERI_CRG_PEREN4 (0x40)
+#define PERI_CRG_PERDIS4 (0x44)
+#define PERI_CRG_PERRSTEN4 (0x90)
+#define PERI_CRG_PERRSTDIS4 (0x94)
+#define PERI_CRG_ISODIS (0x148)
+#define PERI_CRG_PEREN6 (0x410)
+#define PERI_CRG_PERDIS6 (0x414)
+
+#define USB_REFCLK_ISO_EN BIT(25)
+
+#define GT_CLK_USB2PHY_REF BIT(19)
+
+#define PCTRL_PERI_CTRL3 (0x10)
+#define PCTRL_PERI_CTRL3_MSK_START (16)
+#define USB_TCXO_EN BIT(1)
+
+#define PCTRL_PERI_CTRL24 (0x64)
+#define SC_CLK_USB3PHY_3MUX1_SEL BIT(25)
+
+#define USB3OTG_CTRL0 (0x00)
+#define USB3OTG_CTRL3 (0x0c)
+#define USB3OTG_CTRL4 (0x10)
+#define USB3OTG_CTRL5 (0x14)
+#define USB3OTG_CTRL7 (0x1c)
+#define USB_MISC_CFG50 (0x50)
+#define USB_MISC_CFG54 (0x54)
+#define USB_MISC_CFG58 (0x58)
+#define USB_MISC_CFG5C (0x5c)
+#define USB_MISC_CFGA0 (0xa0)
+#define TCA_CLK_RST (0x200)
+#define TCA_INTR_EN (0x204)
+#define TCA_INTR_STS (0x208)
+#define TCA_GCFG (0x210)
+#define TCA_TCPC (0x214)
+#define TCA_SYSMODE_CFG (0x218)
+#define TCA_VBUS_CTRL (0x240)
+
+#define CTRL0_USB3_VBUSVLD BIT(7)
+#define CTRL0_USB3_VBUSVLD_SEL BIT(6)
+
+#define CTRL3_USB2_VBUSVLDEXT0 BIT(6)
+#define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5)
+
+#define CTRL5_USB2_SIDDQ BIT(0)
+
+#define CTRL7_USB2_REFCLKSEL_MASK GENMASK(4, 3)
+#define CTRL7_USB2_REFCLKSEL_ABB (BIT(4) | BIT(3))
+#define CTRL7_USB2_REFCLKSEL_PAD BIT(4)
+
+#define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23)
+
+#define CFG54_USB31PHY_CR_ADDR_MASK GENMASK(31, 16)
+
+#define CFG54_USB3PHY_REF_USE_PAD BIT(12)
+#define CFG54_PHY0_PMA_PWR_STABLE BIT(11)
+#define CFG54_PHY0_PCS_PWR_STABLE BIT(9)
+#define CFG54_USB31PHY_CR_ACK BIT(7)
+#define CFG54_USB31PHY_CR_WR_EN BIT(5)
+#define CFG54_USB31PHY_CR_SEL BIT(4)
+#define CFG54_USB31PHY_CR_RD_EN BIT(3)
+#define CFG54_USB31PHY_CR_CLK BIT(2)
+#define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1)
+
+#define CFG58_USB31PHY_CR_DATA_MASK GENMASK(31, 16)
+
+#define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1)
+
+#define CFGA0_VAUX_RESET BIT(9)
+#define CFGA0_USB31C_RESET BIT(8)
+#define CFGA0_USB2PHY_REFCLK_SELECT BIT(4)
+#define CFGA0_USB3PHY_RESET BIT(1)
+#define CFGA0_USB2PHY_POR BIT(0)
+
+#define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1)
+#define INTR_EN_XA_ACK_EVT_EN BIT(0)
+
+#define CLK_RST_TCA_REF_CLK_EN BIT(1)
+#define CLK_RST_SUSPEND_CLK_EN BIT(0)
+
+#define GCFG_ROLE_HSTDEV BIT(4)
+#define GCFG_OP_MODE GENMASK(1, 0)
+#define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0)
+
+#define TCPC_VALID BIT(4)
+#define TCPC_LOW_POWER_EN BIT(3)
+#define TCPC_MUX_CONTROL_MASK GENMASK(1, 0)
+#define TCPC_MUX_CONTROL_USB31 BIT(0)
+
+#define SYSMODE_CFG_TYPEC_DISABLE BIT(3)
+
+#define VBUS_CTRL_POWERPRESENT_OVERRD GENMASK(3, 2)
+#define VBUS_CTRL_VBUSVALID_OVERRD GENMASK(1, 0)
+
+#define KIRIN970_USB_DEFAULT_PHY_PARAM (0xfdfee4)
+#define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5)
+
+#define TX_VBOOST_LVL_REG (0xf)
+#define TX_VBOOST_LVL_START (6)
+#define TX_VBOOST_LVL_ENABLE BIT(9)
+
+struct hi3670_priv {
+ struct device *dev;
+ struct regmap *peri_crg;
+ struct regmap *pctrl;
+ struct regmap *sctrl;
+ struct regmap *usb31misc;
+
+ u32 eye_diagram_param;
+ u32 tx_vboost_lvl;
+
+ u32 peri_crg_offset;
+ u32 pctrl_offset;
+ u32 usb31misc_offset;
+};
+
+static int hi3670_phy_cr_clk(struct regmap *usb31misc)
+{
+ int ret;
+
+ /* Clock up */
+ ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
+ CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK);
+ if (ret)
+ return ret;
+
+ /* Clock down */
+ return regmap_update_bits(usb31misc, USB_MISC_CFG54,
+ CFG54_USB31PHY_CR_CLK, 0);
+}
+
+static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
+{
+ return regmap_update_bits(usb31misc, USB_MISC_CFG54,
+ CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL);
+}
+
+static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction)
+{
+ int ret, reg;
+
+ if (direction)
+ reg = CFG54_USB31PHY_CR_WR_EN;
+ else
+ reg = CFG54_USB31PHY_CR_RD_EN;
+
+ ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, reg, reg);
+
+ if (ret)
+ return ret;
+
+ ret = hi3670_phy_cr_clk(usb31misc);
+ if (ret)
+ return ret;
+
+ return regmap_update_bits(usb31misc, USB_MISC_CFG54,
+ CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0);
+}
+
+static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc)
+{
+ u32 reg;
+ int retry = 10;
+ int ret;
+
+ while (retry-- > 0) {
+ ret = regmap_read(usb31misc, USB_MISC_CFG54, ®);
+ if (ret)
+ return ret;
+ if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK)
+ return 0;
+
+ ret = hi3670_phy_cr_clk(usb31misc);
+ if (ret)
+ return ret;
+
+ usleep_range(10, 20);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
+{
+ u32 reg;
+ int ret;
+
+ ret = regmap_read(usb31misc, USB_MISC_CFG54, ®);
+ if (ret)
+ return ret;
+
+ reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr);
+
+ return regmap_update_bits(usb31misc, USB_MISC_CFG54,
+ CFG54_USB31PHY_CR_ADDR_MASK, reg);
+}
+
+static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
+{
+ int reg, i, ret;
+
+ for (i = 0; i < 100; i++) {
+ ret = hi3670_phy_cr_clk(usb31misc);
+ if (ret)
+ return ret;
+ }
+
+ ret = hi3670_phy_cr_set_sel(usb31misc);
+ if (ret)
+ return ret;
+
+ ret = hi3670_phy_cr_set_addr(usb31misc, addr);
+ if (ret)
+ return ret;
+
+ ret = hi3670_phy_cr_start(usb31misc, 0);
+ if (ret)
+ return ret;
+
+ ret = hi3670_phy_cr_wait_ack(usb31misc);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(usb31misc, USB_MISC_CFG58, ®);
+ if (ret)
+ return ret;
+
+ *val = FIELD_GET(CFG58_USB31PHY_CR_DATA_MASK, reg);
+
+ return 0;
+}
+
+static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
+{
+ int i;
+ int ret;
+
+ for (i = 0; i < 100; i++) {
+ ret = hi3670_phy_cr_clk(usb31misc);
+ if (ret)
+ return ret;
+ }
+
+ ret = hi3670_phy_cr_set_sel(usb31misc);
+ if (ret)
+ return ret;
+
+ ret = hi3670_phy_cr_set_addr(usb31misc, addr);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(usb31misc, USB_MISC_CFG58,
+ FIELD_PREP(CFG58_USB31PHY_CR_DATA_MASK, val));
+ if (ret)
+ return ret;
+
+ ret = hi3670_phy_cr_start(usb31misc, 1);
+ if (ret)
+ return ret;
+
+ return hi3670_phy_cr_wait_ack(usb31misc);
+}
+
+static int hi3670_phy_set_params(struct hi3670_priv *priv)
+{
+ u32 reg;
+ int ret;
+ int retry = 3;
+
+ ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4,
+ priv->eye_diagram_param);
+ if (ret) {
+ dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n");
+ return ret;
+ }
+
+ while (retry-- > 0) {
+ ret = hi3670_phy_cr_read(priv->usb31misc,
+ TX_VBOOST_LVL_REG, ®);
+ if (!ret)
+ break;
+
+ if (ret != -ETIMEDOUT) {
+ dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n");
+ return ret;
+ }
+ }
+ if (ret)
+ return ret;
+
+ reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START));
+ ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg);
+ if (ret)
+ dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n");
+
+ return ret;
+}
+
+static bool hi3670_is_abbclk_selected(struct hi3670_priv *priv)
+{
+ u32 reg;
+
+ if (!priv->sctrl) {
+ dev_err(priv->dev, "priv->sctrl is null!\n");
+ return false;
+ }
+
+ if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, ®)) {
+ dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n");
+ return false;
+ }
+
+ if ((reg & USB_CLK_SELECTED) == 0)
+ return false;
+
+ return true;
+}
+
+static int hi3670_config_phy_clock(struct hi3670_priv *priv)
+{
+ u32 val, mask;
+ int ret;
+
+ if (!hi3670_is_abbclk_selected(priv)) {
+ /* usb refclk iso disable */
+ ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
+ USB_REFCLK_ISO_EN);
+ if (ret)
+ goto out;
+
+ /* enable usb_tcxo_en */
+ ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
+ USB_TCXO_EN |
+ (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
+
+ /* select usbphy clk from abb */
+ mask = SC_CLK_USB3PHY_3MUX1_SEL;
+ ret = regmap_update_bits(priv->pctrl,
+ PCTRL_PERI_CTRL24, mask, 0);
+ if (ret)
+ goto out;
+
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
+ CFGA0_USB2PHY_REFCLK_SELECT, 0);
+ if (ret)
+ goto out;
+
+ ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
+ if (ret)
+ goto out;
+ val &= ~CTRL7_USB2_REFCLKSEL_MASK;
+ val |= CTRL7_USB2_REFCLKSEL_ABB;
+ ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
+ if (ret)
+ goto out;
+
+ return 0;
+ }
+
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
+ CFG54_USB3PHY_REF_USE_PAD,
+ CFG54_USB3PHY_REF_USE_PAD);
+ if (ret)
+ goto out;
+
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
+ CFGA0_USB2PHY_REFCLK_SELECT,
+ CFGA0_USB2PHY_REFCLK_SELECT);
+ if (ret)
+ goto out;
+
+ ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
+ if (ret)
+ goto out;
+ val &= ~CTRL7_USB2_REFCLKSEL_MASK;
+ val |= CTRL7_USB2_REFCLKSEL_PAD;
+ ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
+ if (ret)
+ goto out;
+
+ ret = regmap_write(priv->peri_crg,
+ PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF);
+ if (ret)
+ goto out;
+
+ return 0;
+out:
+ dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
+ return ret;
+}
+
+static int hi3670_config_tca(struct hi3670_priv *priv)
+{
+ u32 val, mask;
+ int ret;
+
+ ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff);
+ if (ret)
+ goto out;
+
+ ret = regmap_write(priv->usb31misc, TCA_INTR_EN,
+ INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN);
+ if (ret)
+ goto out;
+
+ mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN;
+ ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0);
+ if (ret)
+ goto out;
+
+ ret = regmap_update_bits(priv->usb31misc, TCA_GCFG,
+ GCFG_ROLE_HSTDEV | GCFG_OP_MODE,
+ GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE);
+ if (ret)
+ goto out;
+
+ ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG,
+ SYSMODE_CFG_TYPEC_DISABLE, 0);
+ if (ret)
+ goto out;
+
+ ret = regmap_read(priv->usb31misc, TCA_TCPC, &val);
+ if (ret)
+ goto out;
+ val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK);
+ val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31);
+ ret = regmap_write(priv->usb31misc, TCA_TCPC, val);
+ if (ret)
+ goto out;
+
+ ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL,
+ VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD);
+ if (ret)
+ goto out;
+
+ return 0;
+out:
+ dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
+ return ret;
+}
+
+static int hi3670_phy_init(struct phy *phy)
+{
+ struct hi3670_priv *priv = phy_get_drvdata(phy);
+ u32 val;
+ int ret;
+
+ /* assert controller */
+ val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET |
+ CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0);
+ if (ret)
+ goto out;
+
+ ret = hi3670_config_phy_clock(priv);
+ if (ret)
+ goto out;
+
+ /* Exit from IDDQ mode */
+ ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
+ CTRL5_USB2_SIDDQ, 0);
+ if (ret)
+ goto out;
+
+ /* Release USB31 PHY out of TestPowerDown mode */
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50,
+ CFG50_USB3_PHY_TEST_POWERDOWN, 0);
+ if (ret)
+ goto out;
+
+ /* Deassert phy */
+ val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
+ if (ret)
+ goto out;
+
+ usleep_range(100, 120);
+
+ /* Tell the PHY power is stable */
+ val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE |
+ CFG54_PHY0_PMA_PWR_STABLE;
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
+ val, val);
+ if (ret)
+ goto out;
+
+ ret = hi3670_config_tca(priv);
+ if (ret)
+ goto out;
+
+ /* Enable SSC */
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C,
+ CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN,
+ CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN);
+ if (ret)
+ goto out;
+
+ /* Deassert controller */
+ val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET;
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
+ if (ret)
+ goto out;
+
+ usleep_range(100, 120);
+
+ /* Set fake vbus valid signal */
+ val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL;
+ ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val);
+ if (ret)
+ goto out;
+
+ val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0;
+ ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val);
+ if (ret)
+ goto out;
+
+ usleep_range(100, 120);
+
+ ret = hi3670_phy_set_params(priv);
+ if (ret)
+ goto out;
+
+ return 0;
+out:
+ dev_err(priv->dev, "failed to init phy ret: %d\n", ret);
+ return ret;
+}
+
+static int hi3670_phy_exit(struct phy *phy)
+{
+ struct hi3670_priv *priv = phy_get_drvdata(phy);
+ u32 mask;
+ int ret;
+
+ /* Assert phy */
+ mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
+ ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0);
+ if (ret)
+ goto out;
+
+ if (!hi3670_is_abbclk_selected(priv)) {
+ /* disable usb_tcxo_en */
+ ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
+ USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START);
+ } else {
+ ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6,
+ GT_CLK_USB2PHY_REF);
+ if (ret)
+ goto out;
+ }
+
+ return 0;
+out:
+ dev_err(priv->dev, "failed to exit phy ret: %d\n", ret);
+ return ret;
+}
+
+static const struct phy_ops hi3670_phy_ops = {
+ .init = hi3670_phy_init,
+ .exit = hi3670_phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static int hi3670_phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct phy *phy;
+ struct hi3670_priv *priv;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = dev;
+ priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "hisilicon,pericrg-syscon");
+ if (IS_ERR(priv->peri_crg)) {
+ dev_err(dev, "no hisilicon,pericrg-syscon\n");
+ return PTR_ERR(priv->peri_crg);
+ }
+
+ priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "hisilicon,pctrl-syscon");
+ if (IS_ERR(priv->pctrl)) {
+ dev_err(dev, "no hisilicon,pctrl-syscon\n");
+ return PTR_ERR(priv->pctrl);
+ }
+
+ priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "hisilicon,sctrl-syscon");
+ if (IS_ERR(priv->sctrl)) {
+ dev_err(dev, "no hisilicon,sctrl-syscon\n");
+ return PTR_ERR(priv->sctrl);
+ }
+
+ /* node of hi3670 phy is a sub-node of usb3_otg_bc */
+ priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(priv->usb31misc)) {
+ dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n");
+ return PTR_ERR(priv->usb31misc);
+ }
+
+ if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param",
+ &priv->eye_diagram_param))
+ priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM;
+
+ if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl",
+ &priv->tx_vboost_lvl))
+ priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST;
+
+ phy = devm_phy_create(dev, NULL, &hi3670_phy_ops);
+ if (IS_ERR(phy))
+ return PTR_ERR(phy);
+
+ phy_set_drvdata(phy, priv);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id hi3670_phy_of_match[] = {
+ { .compatible = "hisilicon,hi3670-usb-phy" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, hi3670_phy_of_match);
+
+static struct platform_driver hi3670_phy_driver = {
+ .probe = hi3670_phy_probe,
+ .driver = {
+ .name = "hi3670-usb-phy",
+ .of_match_table = hi3670_phy_of_match,
+ }
+};
+module_platform_driver(hi3670_phy_driver);
+
+MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");
diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig
index c4dc1016edf2..3ceda03f2864 100644
--- a/drivers/staging/hikey9xx/Kconfig
+++ b/drivers/staging/hikey9xx/Kconfig
@@ -1,16 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-# to be placed at drivers/phy
-config PHY_HI3670_USB
- tristate "hi3670 USB PHY support"
- depends on (ARCH_HISI && ARM64) || COMPILE_TEST
- select GENERIC_PHY
- select MFD_SYSCON
- help
- Enable this to support the HISILICON HI3670 USB PHY.
-
- To compile this driver as a module, choose M here.
-
# to be placed at drivers/spmi
config SPMI_HISI3670
tristate "Hisilicon 3670 SPMI Controller"
diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile
index 9103735d8377..42d486104525 100644
--- a/drivers/staging/hikey9xx/Makefile
+++ b/drivers/staging/hikey9xx/Makefile
@@ -1,6 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_PHY_HI3670_USB) += phy-hi3670-usb3.o
-
obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o
obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o
diff --git a/drivers/staging/hikey9xx/phy-hi3670-usb3.c b/drivers/staging/hikey9xx/phy-hi3670-usb3.c
deleted file mode 100644
index b9ffe08abaab..000000000000
--- a/drivers/staging/hikey9xx/phy-hi3670-usb3.c
+++ /dev/null
@@ -1,661 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
- *
- * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
- * http://www.huawei.com
- *
- * Authors: Yu Chen <chenyu56@huawei.com>
- */
-
-#include <linux/bitfield.h>
-#include <linux/clk.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/module.h>
-#include <linux/phy/phy.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-
-#define SCTRL_SCDEEPSLEEPED (0x0)
-#define USB_CLK_SELECTED BIT(20)
-
-#define PERI_CRG_PEREN0 (0x00)
-#define PERI_CRG_PERDIS0 (0x04)
-#define PERI_CRG_PEREN4 (0x40)
-#define PERI_CRG_PERDIS4 (0x44)
-#define PERI_CRG_PERRSTEN4 (0x90)
-#define PERI_CRG_PERRSTDIS4 (0x94)
-#define PERI_CRG_ISODIS (0x148)
-#define PERI_CRG_PEREN6 (0x410)
-#define PERI_CRG_PERDIS6 (0x414)
-
-#define USB_REFCLK_ISO_EN BIT(25)
-
-#define GT_CLK_USB2PHY_REF BIT(19)
-
-#define PCTRL_PERI_CTRL3 (0x10)
-#define PCTRL_PERI_CTRL3_MSK_START (16)
-#define USB_TCXO_EN BIT(1)
-
-#define PCTRL_PERI_CTRL24 (0x64)
-#define SC_CLK_USB3PHY_3MUX1_SEL BIT(25)
-
-#define USB3OTG_CTRL0 (0x00)
-#define USB3OTG_CTRL3 (0x0c)
-#define USB3OTG_CTRL4 (0x10)
-#define USB3OTG_CTRL5 (0x14)
-#define USB3OTG_CTRL7 (0x1c)
-#define USB_MISC_CFG50 (0x50)
-#define USB_MISC_CFG54 (0x54)
-#define USB_MISC_CFG58 (0x58)
-#define USB_MISC_CFG5C (0x5c)
-#define USB_MISC_CFGA0 (0xa0)
-#define TCA_CLK_RST (0x200)
-#define TCA_INTR_EN (0x204)
-#define TCA_INTR_STS (0x208)
-#define TCA_GCFG (0x210)
-#define TCA_TCPC (0x214)
-#define TCA_SYSMODE_CFG (0x218)
-#define TCA_VBUS_CTRL (0x240)
-
-#define CTRL0_USB3_VBUSVLD BIT(7)
-#define CTRL0_USB3_VBUSVLD_SEL BIT(6)
-
-#define CTRL3_USB2_VBUSVLDEXT0 BIT(6)
-#define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5)
-
-#define CTRL5_USB2_SIDDQ BIT(0)
-
-#define CTRL7_USB2_REFCLKSEL_MASK GENMASK(4, 3)
-#define CTRL7_USB2_REFCLKSEL_ABB (BIT(4) | BIT(3))
-#define CTRL7_USB2_REFCLKSEL_PAD BIT(4)
-
-#define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23)
-
-#define CFG54_USB31PHY_CR_ADDR_MASK GENMASK(31, 16)
-
-#define CFG54_USB3PHY_REF_USE_PAD BIT(12)
-#define CFG54_PHY0_PMA_PWR_STABLE BIT(11)
-#define CFG54_PHY0_PCS_PWR_STABLE BIT(9)
-#define CFG54_USB31PHY_CR_ACK BIT(7)
-#define CFG54_USB31PHY_CR_WR_EN BIT(5)
-#define CFG54_USB31PHY_CR_SEL BIT(4)
-#define CFG54_USB31PHY_CR_RD_EN BIT(3)
-#define CFG54_USB31PHY_CR_CLK BIT(2)
-#define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1)
-
-#define CFG58_USB31PHY_CR_DATA_MASK GENMASK(31, 16)
-
-#define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1)
-
-#define CFGA0_VAUX_RESET BIT(9)
-#define CFGA0_USB31C_RESET BIT(8)
-#define CFGA0_USB2PHY_REFCLK_SELECT BIT(4)
-#define CFGA0_USB3PHY_RESET BIT(1)
-#define CFGA0_USB2PHY_POR BIT(0)
-
-#define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1)
-#define INTR_EN_XA_ACK_EVT_EN BIT(0)
-
-#define CLK_RST_TCA_REF_CLK_EN BIT(1)
-#define CLK_RST_SUSPEND_CLK_EN BIT(0)
-
-#define GCFG_ROLE_HSTDEV BIT(4)
-#define GCFG_OP_MODE GENMASK(1, 0)
-#define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0)
-
-#define TCPC_VALID BIT(4)
-#define TCPC_LOW_POWER_EN BIT(3)
-#define TCPC_MUX_CONTROL_MASK GENMASK(1, 0)
-#define TCPC_MUX_CONTROL_USB31 BIT(0)
-
-#define SYSMODE_CFG_TYPEC_DISABLE BIT(3)
-
-#define VBUS_CTRL_POWERPRESENT_OVERRD GENMASK(3, 2)
-#define VBUS_CTRL_VBUSVALID_OVERRD GENMASK(1, 0)
-
-#define KIRIN970_USB_DEFAULT_PHY_PARAM (0xfdfee4)
-#define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5)
-
-#define TX_VBOOST_LVL_REG (0xf)
-#define TX_VBOOST_LVL_START (6)
-#define TX_VBOOST_LVL_ENABLE BIT(9)
-
-struct hi3670_priv {
- struct device *dev;
- struct regmap *peri_crg;
- struct regmap *pctrl;
- struct regmap *sctrl;
- struct regmap *usb31misc;
-
- u32 eye_diagram_param;
- u32 tx_vboost_lvl;
-
- u32 peri_crg_offset;
- u32 pctrl_offset;
- u32 usb31misc_offset;
-};
-
-static int hi3670_phy_cr_clk(struct regmap *usb31misc)
-{
- int ret;
-
- /* Clock up */
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK);
- if (ret)
- return ret;
-
- /* Clock down */
- return regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_CLK, 0);
-}
-
-static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
-{
- return regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL);
-}
-
-static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction)
-{
- int ret, reg;
-
- if (direction)
- reg = CFG54_USB31PHY_CR_WR_EN;
- else
- reg = CFG54_USB31PHY_CR_RD_EN;
-
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, reg, reg);
-
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
-
- return regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0);
-}
-
-static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc)
-{
- u32 reg;
- int retry = 10;
- int ret;
-
- while (retry-- > 0) {
- ret = regmap_read(usb31misc, USB_MISC_CFG54, ®);
- if (ret)
- return ret;
- if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK)
- return 0;
-
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
-
- usleep_range(10, 20);
- }
-
- return -ETIMEDOUT;
-}
-
-static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
-{
- u32 reg;
- int ret;
-
- ret = regmap_read(usb31misc, USB_MISC_CFG54, ®);
- if (ret)
- return ret;
-
- reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr);
-
- return regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_ADDR_MASK, reg);
-}
-
-static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
-{
- int reg, i, ret;
-
- for (i = 0; i < 100; i++) {
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
- }
-
- ret = hi3670_phy_cr_set_sel(usb31misc);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_set_addr(usb31misc, addr);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_start(usb31misc, 0);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_wait_ack(usb31misc);
- if (ret)
- return ret;
-
- ret = regmap_read(usb31misc, USB_MISC_CFG58, ®);
- if (ret)
- return ret;
-
- *val = FIELD_GET(CFG58_USB31PHY_CR_DATA_MASK, reg);
-
- return 0;
-}
-
-static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
-{
- int i;
- int ret;
-
- for (i = 0; i < 100; i++) {
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
- }
-
- ret = hi3670_phy_cr_set_sel(usb31misc);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_set_addr(usb31misc, addr);
- if (ret)
- return ret;
-
- ret = regmap_write(usb31misc, USB_MISC_CFG58,
- FIELD_PREP(CFG58_USB31PHY_CR_DATA_MASK, val));
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_start(usb31misc, 1);
- if (ret)
- return ret;
-
- return hi3670_phy_cr_wait_ack(usb31misc);
-}
-
-static int hi3670_phy_set_params(struct hi3670_priv *priv)
-{
- u32 reg;
- int ret;
- int retry = 3;
-
- ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4,
- priv->eye_diagram_param);
- if (ret) {
- dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n");
- return ret;
- }
-
- while (retry-- > 0) {
- ret = hi3670_phy_cr_read(priv->usb31misc,
- TX_VBOOST_LVL_REG, ®);
- if (!ret)
- break;
-
- if (ret != -ETIMEDOUT) {
- dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n");
- return ret;
- }
- }
- if (ret)
- return ret;
-
- reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START));
- ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg);
- if (ret)
- dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n");
-
- return ret;
-}
-
-static bool hi3670_is_abbclk_selected(struct hi3670_priv *priv)
-{
- u32 reg;
-
- if (!priv->sctrl) {
- dev_err(priv->dev, "priv->sctrl is null!\n");
- return false;
- }
-
- if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, ®)) {
- dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n");
- return false;
- }
-
- if ((reg & USB_CLK_SELECTED) == 0)
- return false;
-
- return true;
-}
-
-static int hi3670_config_phy_clock(struct hi3670_priv *priv)
-{
- u32 val, mask;
- int ret;
-
- if (!hi3670_is_abbclk_selected(priv)) {
- /* usb refclk iso disable */
- ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
- USB_REFCLK_ISO_EN);
- if (ret)
- goto out;
-
- /* enable usb_tcxo_en */
- ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
- USB_TCXO_EN |
- (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
-
- /* select usbphy clk from abb */
- mask = SC_CLK_USB3PHY_3MUX1_SEL;
- ret = regmap_update_bits(priv->pctrl,
- PCTRL_PERI_CTRL24, mask, 0);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
- CFGA0_USB2PHY_REFCLK_SELECT, 0);
- if (ret)
- goto out;
-
- ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
- if (ret)
- goto out;
- val &= ~CTRL7_USB2_REFCLKSEL_MASK;
- val |= CTRL7_USB2_REFCLKSEL_ABB;
- ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
- if (ret)
- goto out;
-
- return 0;
- }
-
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
- CFG54_USB3PHY_REF_USE_PAD,
- CFG54_USB3PHY_REF_USE_PAD);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
- CFGA0_USB2PHY_REFCLK_SELECT,
- CFGA0_USB2PHY_REFCLK_SELECT);
- if (ret)
- goto out;
-
- ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
- if (ret)
- goto out;
- val &= ~CTRL7_USB2_REFCLKSEL_MASK;
- val |= CTRL7_USB2_REFCLKSEL_PAD;
- ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
- if (ret)
- goto out;
-
- ret = regmap_write(priv->peri_crg,
- PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF);
- if (ret)
- goto out;
-
- return 0;
-out:
- dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
- return ret;
-}
-
-static int hi3670_config_tca(struct hi3670_priv *priv)
-{
- u32 val, mask;
- int ret;
-
- ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff);
- if (ret)
- goto out;
-
- ret = regmap_write(priv->usb31misc, TCA_INTR_EN,
- INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN);
- if (ret)
- goto out;
-
- mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN;
- ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, TCA_GCFG,
- GCFG_ROLE_HSTDEV | GCFG_OP_MODE,
- GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG,
- SYSMODE_CFG_TYPEC_DISABLE, 0);
- if (ret)
- goto out;
-
- ret = regmap_read(priv->usb31misc, TCA_TCPC, &val);
- if (ret)
- goto out;
- val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK);
- val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31);
- ret = regmap_write(priv->usb31misc, TCA_TCPC, val);
- if (ret)
- goto out;
-
- ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL,
- VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD);
- if (ret)
- goto out;
-
- return 0;
-out:
- dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
- return ret;
-}
-
-static int hi3670_phy_init(struct phy *phy)
-{
- struct hi3670_priv *priv = phy_get_drvdata(phy);
- u32 val;
- int ret;
-
- /* assert controller */
- val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET |
- CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0);
- if (ret)
- goto out;
-
- ret = hi3670_config_phy_clock(priv);
- if (ret)
- goto out;
-
- /* Exit from IDDQ mode */
- ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
- CTRL5_USB2_SIDDQ, 0);
- if (ret)
- goto out;
-
- /* Release USB31 PHY out of TestPowerDown mode */
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50,
- CFG50_USB3_PHY_TEST_POWERDOWN, 0);
- if (ret)
- goto out;
-
- /* Deassert phy */
- val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
- if (ret)
- goto out;
-
- usleep_range(100, 120);
-
- /* Tell the PHY power is stable */
- val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE |
- CFG54_PHY0_PMA_PWR_STABLE;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
- val, val);
- if (ret)
- goto out;
-
- ret = hi3670_config_tca(priv);
- if (ret)
- goto out;
-
- /* Enable SSC */
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C,
- CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN,
- CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN);
- if (ret)
- goto out;
-
- /* Deassert controller */
- val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
- if (ret)
- goto out;
-
- usleep_range(100, 120);
-
- /* Set fake vbus valid signal */
- val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL;
- ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val);
- if (ret)
- goto out;
-
- val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0;
- ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val);
- if (ret)
- goto out;
-
- usleep_range(100, 120);
-
- ret = hi3670_phy_set_params(priv);
- if (ret)
- goto out;
-
- return 0;
-out:
- dev_err(priv->dev, "failed to init phy ret: %d\n", ret);
- return ret;
-}
-
-static int hi3670_phy_exit(struct phy *phy)
-{
- struct hi3670_priv *priv = phy_get_drvdata(phy);
- u32 mask;
- int ret;
-
- /* Assert phy */
- mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0);
- if (ret)
- goto out;
-
- if (!hi3670_is_abbclk_selected(priv)) {
- /* disable usb_tcxo_en */
- ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
- USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START);
- } else {
- ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6,
- GT_CLK_USB2PHY_REF);
- if (ret)
- goto out;
- }
-
- return 0;
-out:
- dev_err(priv->dev, "failed to exit phy ret: %d\n", ret);
- return ret;
-}
-
-static const struct phy_ops hi3670_phy_ops = {
- .init = hi3670_phy_init,
- .exit = hi3670_phy_exit,
- .owner = THIS_MODULE,
-};
-
-static int hi3670_phy_probe(struct platform_device *pdev)
-{
- struct phy_provider *phy_provider;
- struct device *dev = &pdev->dev;
- struct phy *phy;
- struct hi3670_priv *priv;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->dev = dev;
- priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node,
- "hisilicon,pericrg-syscon");
- if (IS_ERR(priv->peri_crg)) {
- dev_err(dev, "no hisilicon,pericrg-syscon\n");
- return PTR_ERR(priv->peri_crg);
- }
-
- priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
- "hisilicon,pctrl-syscon");
- if (IS_ERR(priv->pctrl)) {
- dev_err(dev, "no hisilicon,pctrl-syscon\n");
- return PTR_ERR(priv->pctrl);
- }
-
- priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
- "hisilicon,sctrl-syscon");
- if (IS_ERR(priv->sctrl)) {
- dev_err(dev, "no hisilicon,sctrl-syscon\n");
- return PTR_ERR(priv->sctrl);
- }
-
- /* node of hi3670 phy is a sub-node of usb3_otg_bc */
- priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node);
- if (IS_ERR(priv->usb31misc)) {
- dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n");
- return PTR_ERR(priv->usb31misc);
- }
-
- if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param",
- &priv->eye_diagram_param))
- priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM;
-
- if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl",
- &priv->tx_vboost_lvl))
- priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST;
-
- phy = devm_phy_create(dev, NULL, &hi3670_phy_ops);
- if (IS_ERR(phy))
- return PTR_ERR(phy);
-
- phy_set_drvdata(phy, priv);
- phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- return PTR_ERR_OR_ZERO(phy_provider);
-}
-
-static const struct of_device_id hi3670_phy_of_match[] = {
- { .compatible = "hisilicon,hi3670-usb-phy" },
- { },
-};
-MODULE_DEVICE_TABLE(of, hi3670_phy_of_match);
-
-static struct platform_driver hi3670_phy_driver = {
- .probe = hi3670_phy_probe,
- .driver = {
- .name = "hi3670-usb-phy",
- .of_match_table = hi3670_phy_of_match,
- }
-};
-module_platform_driver(hi3670_phy_driver);
-
-MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");
diff --git a/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml b/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml
deleted file mode 100644
index ebd78acfe2de..000000000000
--- a/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml
+++ /dev/null
@@ -1,73 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/phy/hisilicon,hi3670-usb3.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Hisilicon Kirin970 USB PHY
-
-maintainers:
- - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-
-description: |+
- Bindings for USB3 PHY on HiSilicon Kirin 970.
-
-properties:
- compatible:
- const: hisilicon,hi3670-usb-phy
-
- "#phy-cells":
- const: 0
-
- hisilicon,pericrg-syscon:
- $ref: '/schemas/types.yaml#/definitions/phandle'
- description: phandle of syscon used to control iso refclk.
-
- hisilicon,pctrl-syscon:
- $ref: '/schemas/types.yaml#/definitions/phandle'
- description: phandle of syscon used to control usb tcxo.
-
- hisilicon,sctrl-syscon:
- $ref: '/schemas/types.yaml#/definitions/phandle'
- description: phandle of syscon used to control phy deep sleep.
-
- hisilicon,eye-diagram-param:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Eye diagram for phy.
-
- hisilicon,tx-vboost-lvl:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: TX level vboost for phy.
-
-required:
- - compatible
- - hisilicon,pericrg-syscon
- - hisilicon,pctrl-syscon
- - hisilicon,sctrl-syscon
- - hisilicon,eye-diagram-param
- - hisilicon,tx-vboost-lvl
- - "#phy-cells"
-
-additionalProperties: false
-
-examples:
- - |
- bus {
- #address-cells = <2>;
- #size-cells = <2>;
-
- usb3_otg_bc: usb3_otg_bc@ff200000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x0 0xff200000 0x0 0x1000>;
-
- usb_phy {
- compatible = "hisilicon,hi3670-usb-phy";
- #phy-cells = <0>;
- hisilicon,pericrg-syscon = <&crg_ctrl>;
- hisilicon,pctrl-syscon = <&pctrl>;
- hisilicon,sctrl-syscon = <&sctrl>;
- hisilicon,eye-diagram-param = <0xfdfee4>;
- hisilicon,tx-vboost-lvl = <0x5>;
- };
- };
- };
--
2.31.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 5/8] spmi: hisi-spmi-controller: move driver from staging
2021-06-24 14:01 [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Mauro Carvalho Chehab
` (3 preceding siblings ...)
2021-06-24 14:01 ` [PATCH v7 4/8] phy: phy-hi3670-usb3: move driver from staging into phy Mauro Carvalho Chehab
@ 2021-06-24 14:01 ` Mauro Carvalho Chehab
2021-06-24 14:01 ` [PATCH v7 6/8] mfd: hi6421-spmi-pmic: " Mauro Carvalho Chehab
2021-06-24 14:27 ` [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Greg Kroah-Hartman
6 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2021-06-24 14:01 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
Rob Herring, Stephen Boyd, devicetree, linux-kernel,
linux-staging
The Hisilicon 6421v600 SPMI driver is ready for mainstream.
So, move it from staging.
Acked-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
.../spmi/hisilicon,hisi-spmi-controller.yaml | 73 ++++
MAINTAINERS | 7 +
drivers/spmi/Kconfig | 9 +
drivers/spmi/Makefile | 1 +
drivers/spmi/hisi-spmi-controller.c | 367 ++++++++++++++++++
drivers/staging/hikey9xx/Kconfig | 11 -
drivers/staging/hikey9xx/Makefile | 1 -
.../staging/hikey9xx/hisi-spmi-controller.c | 367 ------------------
.../hisilicon,hisi-spmi-controller.yaml | 73 ----
9 files changed, 457 insertions(+), 452 deletions(-)
create mode 100644 Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
create mode 100644 drivers/spmi/hisi-spmi-controller.c
delete mode 100644 drivers/staging/hikey9xx/hisi-spmi-controller.c
delete mode 100644 drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
diff --git a/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
new file mode 100644
index 000000000000..f882903769f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spmi/hisilicon,hisi-spmi-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon SPMI controller
+
+maintainers:
+ - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+description: |
+ The HiSilicon SPMI BUS controller is found on some Kirin-based designs.
+ It is a MIPI System Power Management (SPMI) controller.
+
+ The PMIC part is provided by
+ ./Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml.
+
+allOf:
+ - $ref: spmi.yaml#
+
+properties:
+
+ $nodename:
+ pattern: "spmi@[0-9a-f]"
+
+ compatible:
+ const: hisilicon,kirin970-spmi-controller
+
+ reg:
+ maxItems: 1
+
+ hisilicon,spmi-channel:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ number of the Kirin 970 SPMI channel where the SPMI devices are connected.
+
+required:
+ - compatible
+ - reg
+ - hisilicon,spmi-channel
+
+patternProperties:
+ "@[0-9a-f]$":
+ type: object
+
+ description: |
+ PMIC properties, which are specific to the used SPMI PMIC device(s).
+ When used in combination with HiSilicon 6421v600, the properties
+ are documented at
+ drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml.
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ spmi: spmi@fff24000 {
+ compatible = "hisilicon,kirin970-spmi-controller";
+ #address-cells = <2>;
+ #size-cells = <0>;
+ reg = <0x0 0xfff24000 0x0 0x1000>;
+ hisilicon,spmi-channel = <2>;
+
+ pmic@0 {
+ reg = <0 0>;
+ /* pmic properties */
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 6e01424234eb..9a69e3810964 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8284,6 +8284,13 @@ S: Maintained
W: http://www.hisilicon.com
F: drivers/spi/spi-hisi-kunpeng.c
+HISILICON SPMI CONTROLLER DRIVER FOR HIKEY 970
+M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
+F: drivers/spmi/hisi-spmi-controller.c
+
HISILICON STAGING DRIVERS FOR HIKEY 960/970
M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
S: Maintained
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index a53bad541f1a..2874b6c26028 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -11,6 +11,15 @@ menuconfig SPMI
if SPMI
+config SPMI_HISI3670
+ tristate "Hisilicon 3670 SPMI Controller"
+ select IRQ_DOMAIN_HIERARCHY
+ depends on HAS_IOMEM
+ help
+ If you say yes to this option, support will be included for the
+ built-in SPMI PMIC Arbiter interface on Hisilicon 3670
+ processors.
+
config SPMI_MSM_PMIC_ARB
tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
select IRQ_DOMAIN_HIERARCHY
diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile
index 55a94cadeffe..6e092e6f290c 100644
--- a/drivers/spmi/Makefile
+++ b/drivers/spmi/Makefile
@@ -4,4 +4,5 @@
#
obj-$(CONFIG_SPMI) += spmi.o
+obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o
obj-$(CONFIG_SPMI_MSM_PMIC_ARB) += spmi-pmic-arb.o
diff --git a/drivers/spmi/hisi-spmi-controller.c b/drivers/spmi/hisi-spmi-controller.c
new file mode 100644
index 000000000000..5bd23262abd6
--- /dev/null
+++ b/drivers/spmi/hisi-spmi-controller.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/spmi.h>
+
+/*
+ * SPMI register addr
+ */
+#define SPMI_CHANNEL_OFFSET 0x0300
+#define SPMI_SLAVE_OFFSET 0x20
+
+#define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100
+
+#define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104
+#define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108
+#define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c
+#define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110
+
+#define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200
+
+#define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204
+#define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208
+#define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c
+#define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210
+
+#define SPMI_PER_DATAREG_BYTE 4
+/*
+ * SPMI cmd register
+ */
+#define SPMI_APB_SPMI_CMD_EN BIT(31)
+#define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24
+#define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20
+#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16
+#define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0
+
+/* Command Opcodes */
+
+enum spmi_controller_cmd_op_code {
+ SPMI_CMD_REG_ZERO_WRITE = 0,
+ SPMI_CMD_REG_WRITE = 1,
+ SPMI_CMD_REG_READ = 2,
+ SPMI_CMD_EXT_REG_WRITE = 3,
+ SPMI_CMD_EXT_REG_READ = 4,
+ SPMI_CMD_EXT_REG_WRITE_L = 5,
+ SPMI_CMD_EXT_REG_READ_L = 6,
+ SPMI_CMD_REG_RESET = 7,
+ SPMI_CMD_REG_SLEEP = 8,
+ SPMI_CMD_REG_SHUTDOWN = 9,
+ SPMI_CMD_REG_WAKEUP = 10,
+};
+
+/*
+ * SPMI status register
+ */
+#define SPMI_APB_TRANS_DONE BIT(0)
+#define SPMI_APB_TRANS_FAIL BIT(2)
+
+/* Command register fields */
+#define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16
+
+/* Maximum number of support PMIC peripherals */
+#define SPMI_CONTROLLER_TIMEOUT_US 1000
+#define SPMI_CONTROLLER_MAX_TRANS_BYTES 16
+
+struct spmi_controller_dev {
+ struct spmi_controller *controller;
+ struct device *dev;
+ void __iomem *base;
+ spinlock_t lock;
+ u32 channel;
+};
+
+static int spmi_controller_wait_for_done(struct device *dev,
+ struct spmi_controller_dev *ctrl_dev,
+ void __iomem *base, u8 sid, u16 addr)
+{
+ u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
+ u32 status, offset;
+
+ offset = SPMI_APB_SPMI_STATUS_BASE_ADDR;
+ offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
+
+ do {
+ status = readl(base + offset);
+
+ if (status & SPMI_APB_TRANS_DONE) {
+ if (status & SPMI_APB_TRANS_FAIL) {
+ dev_err(dev, "%s: transaction failed (0x%x)\n",
+ __func__, status);
+ return -EIO;
+ }
+ dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
+ return 0;
+ }
+ udelay(1);
+ } while (timeout--);
+
+ dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status);
+ return -ETIMEDOUT;
+}
+
+static int spmi_read_cmd(struct spmi_controller *ctrl,
+ u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc)
+{
+ struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
+ u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
+ unsigned long flags;
+ u8 *buf = __buf;
+ u32 cmd, data;
+ int rc;
+ u8 op_code, i;
+
+ if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
+ dev_err(&ctrl->dev,
+ "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
+ SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
+ return -EINVAL;
+ }
+
+ switch (opc) {
+ case SPMI_CMD_READ:
+ op_code = SPMI_CMD_REG_READ;
+ break;
+ case SPMI_CMD_EXT_READ:
+ op_code = SPMI_CMD_EXT_REG_READ;
+ break;
+ case SPMI_CMD_EXT_READL:
+ op_code = SPMI_CMD_EXT_REG_READ_L;
+ break;
+ default:
+ dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc);
+ return -EINVAL;
+ }
+
+ cmd = SPMI_APB_SPMI_CMD_EN |
+ (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
+ ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
+ ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */
+ ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
+
+ spin_lock_irqsave(&spmi_controller->lock, flags);
+
+ writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
+
+ rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
+ spmi_controller->base, slave_id, slave_addr);
+ if (rc)
+ goto done;
+
+ for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
+ data = readl(spmi_controller->base + chnl_ofst +
+ SPMI_SLAVE_OFFSET * slave_id +
+ SPMI_APB_SPMI_RDATA0_BASE_ADDR +
+ i * SPMI_PER_DATAREG_BYTE);
+ data = be32_to_cpu((__be32 __force)data);
+ if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
+ memcpy(buf, &data, sizeof(data));
+ buf += sizeof(data);
+ } else {
+ memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE);
+ buf += (bc % SPMI_PER_DATAREG_BYTE);
+ }
+ }
+
+done:
+ spin_unlock_irqrestore(&spmi_controller->lock, flags);
+ if (rc)
+ dev_err(&ctrl->dev,
+ "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
+ opc, slave_id, slave_addr, bc + 1);
+ else
+ dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n",
+ __func__, slave_id, slave_addr, (int)bc, __buf);
+
+ return rc;
+}
+
+static int spmi_write_cmd(struct spmi_controller *ctrl,
+ u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc)
+{
+ struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
+ u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
+ const u8 *buf = __buf;
+ unsigned long flags;
+ u32 cmd, data;
+ int rc;
+ u8 op_code, i;
+
+ if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
+ dev_err(&ctrl->dev,
+ "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
+ SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
+ return -EINVAL;
+ }
+
+ switch (opc) {
+ case SPMI_CMD_WRITE:
+ op_code = SPMI_CMD_REG_WRITE;
+ break;
+ case SPMI_CMD_EXT_WRITE:
+ op_code = SPMI_CMD_EXT_REG_WRITE;
+ break;
+ case SPMI_CMD_EXT_WRITEL:
+ op_code = SPMI_CMD_EXT_REG_WRITE_L;
+ break;
+ default:
+ dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc);
+ return -EINVAL;
+ }
+
+ cmd = SPMI_APB_SPMI_CMD_EN |
+ (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
+ ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
+ ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |
+ ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET);
+
+ /* Write data to FIFOs */
+ spin_lock_irqsave(&spmi_controller->lock, flags);
+
+ for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
+ data = 0;
+ if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
+ memcpy(&data, buf, sizeof(data));
+ buf += sizeof(data);
+ } else {
+ memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE);
+ buf += (bc % SPMI_PER_DATAREG_BYTE);
+ }
+
+ writel((u32 __force)cpu_to_be32(data),
+ spmi_controller->base + chnl_ofst +
+ SPMI_APB_SPMI_WDATA0_BASE_ADDR +
+ SPMI_PER_DATAREG_BYTE * i);
+ }
+
+ /* Start the transaction */
+ writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
+
+ rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
+ spmi_controller->base, slave_id,
+ slave_addr);
+ spin_unlock_irqrestore(&spmi_controller->lock, flags);
+
+ if (rc)
+ dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
+ opc, slave_id, slave_addr, bc);
+ else
+ dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n",
+ __func__, slave_id, slave_addr, (int)bc, __buf);
+
+ return rc;
+}
+
+static int spmi_controller_probe(struct platform_device *pdev)
+{
+ struct spmi_controller_dev *spmi_controller;
+ struct spmi_controller *ctrl;
+ struct resource *iores;
+ int ret;
+
+ ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
+ if (!ctrl) {
+ dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
+ return -ENOMEM;
+ }
+ spmi_controller = spmi_controller_get_drvdata(ctrl);
+ spmi_controller->controller = ctrl;
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iores) {
+ dev_err(&pdev->dev, "can not get resource!\n");
+ ret = -EINVAL;
+ goto err_put_controller;
+ }
+
+ spmi_controller->base = devm_ioremap(&pdev->dev, iores->start,
+ resource_size(iores));
+ if (!spmi_controller->base) {
+ dev_err(&pdev->dev, "can not remap base addr!\n");
+ ret = -EADDRNOTAVAIL;
+ goto err_put_controller;
+ }
+
+ ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel",
+ &spmi_controller->channel);
+ if (ret) {
+ dev_err(&pdev->dev, "can not get channel\n");
+ ret = -ENODEV;
+ goto err_put_controller;
+ }
+
+ platform_set_drvdata(pdev, spmi_controller);
+ dev_set_drvdata(&ctrl->dev, spmi_controller);
+
+ spin_lock_init(&spmi_controller->lock);
+
+ ctrl->nr = spmi_controller->channel;
+ ctrl->dev.parent = pdev->dev.parent;
+ ctrl->dev.of_node = of_node_get(pdev->dev.of_node);
+
+ /* Callbacks */
+ ctrl->read_cmd = spmi_read_cmd;
+ ctrl->write_cmd = spmi_write_cmd;
+
+ ret = spmi_controller_add(ctrl);
+ if (ret) {
+ dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret);
+ goto err_put_controller;
+ }
+
+ return 0;
+
+err_put_controller:
+ spmi_controller_put(ctrl);
+ return ret;
+}
+
+static int spmi_del_controller(struct platform_device *pdev)
+{
+ struct spmi_controller *ctrl = platform_get_drvdata(pdev);
+
+ spmi_controller_remove(ctrl);
+ spmi_controller_put(ctrl);
+ return 0;
+}
+
+static const struct of_device_id spmi_controller_match_table[] = {
+ {
+ .compatible = "hisilicon,kirin970-spmi-controller",
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, spmi_controller_match_table);
+
+static struct platform_driver spmi_controller_driver = {
+ .probe = spmi_controller_probe,
+ .remove = spmi_del_controller,
+ .driver = {
+ .name = "hisi_spmi_controller",
+ .of_match_table = spmi_controller_match_table,
+ },
+};
+
+static int __init spmi_controller_init(void)
+{
+ return platform_driver_register(&spmi_controller_driver);
+}
+postcore_initcall(spmi_controller_init);
+
+static void __exit spmi_controller_exit(void)
+{
+ platform_driver_unregister(&spmi_controller_driver);
+}
+module_exit(spmi_controller_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:spmi_controller");
diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig
index 3ceda03f2864..9f53df9068fe 100644
--- a/drivers/staging/hikey9xx/Kconfig
+++ b/drivers/staging/hikey9xx/Kconfig
@@ -1,16 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-# to be placed at drivers/spmi
-config SPMI_HISI3670
- tristate "Hisilicon 3670 SPMI Controller"
- select IRQ_DOMAIN_HIERARCHY
- depends on HAS_IOMEM
- depends on SPMI
- help
- If you say yes to this option, support will be included for the
- built-in SPMI PMIC Arbiter interface on Hisilicon 3670
- processors.
-
# to be placed at drivers/mfd
config MFD_HI6421_SPMI
tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC"
diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile
index 42d486104525..e3108d7dd849 100644
--- a/drivers/staging/hikey9xx/Makefile
+++ b/drivers/staging/hikey9xx/Makefile
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o
obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o
diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
deleted file mode 100644
index 5bd23262abd6..000000000000
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ /dev/null
@@ -1,367 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/spmi.h>
-
-/*
- * SPMI register addr
- */
-#define SPMI_CHANNEL_OFFSET 0x0300
-#define SPMI_SLAVE_OFFSET 0x20
-
-#define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100
-
-#define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104
-#define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108
-#define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c
-#define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110
-
-#define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200
-
-#define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204
-#define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208
-#define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c
-#define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210
-
-#define SPMI_PER_DATAREG_BYTE 4
-/*
- * SPMI cmd register
- */
-#define SPMI_APB_SPMI_CMD_EN BIT(31)
-#define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24
-#define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20
-#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16
-#define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0
-
-/* Command Opcodes */
-
-enum spmi_controller_cmd_op_code {
- SPMI_CMD_REG_ZERO_WRITE = 0,
- SPMI_CMD_REG_WRITE = 1,
- SPMI_CMD_REG_READ = 2,
- SPMI_CMD_EXT_REG_WRITE = 3,
- SPMI_CMD_EXT_REG_READ = 4,
- SPMI_CMD_EXT_REG_WRITE_L = 5,
- SPMI_CMD_EXT_REG_READ_L = 6,
- SPMI_CMD_REG_RESET = 7,
- SPMI_CMD_REG_SLEEP = 8,
- SPMI_CMD_REG_SHUTDOWN = 9,
- SPMI_CMD_REG_WAKEUP = 10,
-};
-
-/*
- * SPMI status register
- */
-#define SPMI_APB_TRANS_DONE BIT(0)
-#define SPMI_APB_TRANS_FAIL BIT(2)
-
-/* Command register fields */
-#define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16
-
-/* Maximum number of support PMIC peripherals */
-#define SPMI_CONTROLLER_TIMEOUT_US 1000
-#define SPMI_CONTROLLER_MAX_TRANS_BYTES 16
-
-struct spmi_controller_dev {
- struct spmi_controller *controller;
- struct device *dev;
- void __iomem *base;
- spinlock_t lock;
- u32 channel;
-};
-
-static int spmi_controller_wait_for_done(struct device *dev,
- struct spmi_controller_dev *ctrl_dev,
- void __iomem *base, u8 sid, u16 addr)
-{
- u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
- u32 status, offset;
-
- offset = SPMI_APB_SPMI_STATUS_BASE_ADDR;
- offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
-
- do {
- status = readl(base + offset);
-
- if (status & SPMI_APB_TRANS_DONE) {
- if (status & SPMI_APB_TRANS_FAIL) {
- dev_err(dev, "%s: transaction failed (0x%x)\n",
- __func__, status);
- return -EIO;
- }
- dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
- return 0;
- }
- udelay(1);
- } while (timeout--);
-
- dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status);
- return -ETIMEDOUT;
-}
-
-static int spmi_read_cmd(struct spmi_controller *ctrl,
- u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc)
-{
- struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
- u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
- unsigned long flags;
- u8 *buf = __buf;
- u32 cmd, data;
- int rc;
- u8 op_code, i;
-
- if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
- dev_err(&ctrl->dev,
- "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
- SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
- return -EINVAL;
- }
-
- switch (opc) {
- case SPMI_CMD_READ:
- op_code = SPMI_CMD_REG_READ;
- break;
- case SPMI_CMD_EXT_READ:
- op_code = SPMI_CMD_EXT_REG_READ;
- break;
- case SPMI_CMD_EXT_READL:
- op_code = SPMI_CMD_EXT_REG_READ_L;
- break;
- default:
- dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc);
- return -EINVAL;
- }
-
- cmd = SPMI_APB_SPMI_CMD_EN |
- (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
- ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
- ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */
- ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
-
- spin_lock_irqsave(&spmi_controller->lock, flags);
-
- writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
-
- rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
- spmi_controller->base, slave_id, slave_addr);
- if (rc)
- goto done;
-
- for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
- data = readl(spmi_controller->base + chnl_ofst +
- SPMI_SLAVE_OFFSET * slave_id +
- SPMI_APB_SPMI_RDATA0_BASE_ADDR +
- i * SPMI_PER_DATAREG_BYTE);
- data = be32_to_cpu((__be32 __force)data);
- if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
- memcpy(buf, &data, sizeof(data));
- buf += sizeof(data);
- } else {
- memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE);
- buf += (bc % SPMI_PER_DATAREG_BYTE);
- }
- }
-
-done:
- spin_unlock_irqrestore(&spmi_controller->lock, flags);
- if (rc)
- dev_err(&ctrl->dev,
- "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
- opc, slave_id, slave_addr, bc + 1);
- else
- dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n",
- __func__, slave_id, slave_addr, (int)bc, __buf);
-
- return rc;
-}
-
-static int spmi_write_cmd(struct spmi_controller *ctrl,
- u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc)
-{
- struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
- u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
- const u8 *buf = __buf;
- unsigned long flags;
- u32 cmd, data;
- int rc;
- u8 op_code, i;
-
- if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
- dev_err(&ctrl->dev,
- "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
- SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
- return -EINVAL;
- }
-
- switch (opc) {
- case SPMI_CMD_WRITE:
- op_code = SPMI_CMD_REG_WRITE;
- break;
- case SPMI_CMD_EXT_WRITE:
- op_code = SPMI_CMD_EXT_REG_WRITE;
- break;
- case SPMI_CMD_EXT_WRITEL:
- op_code = SPMI_CMD_EXT_REG_WRITE_L;
- break;
- default:
- dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc);
- return -EINVAL;
- }
-
- cmd = SPMI_APB_SPMI_CMD_EN |
- (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
- ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
- ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |
- ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET);
-
- /* Write data to FIFOs */
- spin_lock_irqsave(&spmi_controller->lock, flags);
-
- for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
- data = 0;
- if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
- memcpy(&data, buf, sizeof(data));
- buf += sizeof(data);
- } else {
- memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE);
- buf += (bc % SPMI_PER_DATAREG_BYTE);
- }
-
- writel((u32 __force)cpu_to_be32(data),
- spmi_controller->base + chnl_ofst +
- SPMI_APB_SPMI_WDATA0_BASE_ADDR +
- SPMI_PER_DATAREG_BYTE * i);
- }
-
- /* Start the transaction */
- writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
-
- rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
- spmi_controller->base, slave_id,
- slave_addr);
- spin_unlock_irqrestore(&spmi_controller->lock, flags);
-
- if (rc)
- dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
- opc, slave_id, slave_addr, bc);
- else
- dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n",
- __func__, slave_id, slave_addr, (int)bc, __buf);
-
- return rc;
-}
-
-static int spmi_controller_probe(struct platform_device *pdev)
-{
- struct spmi_controller_dev *spmi_controller;
- struct spmi_controller *ctrl;
- struct resource *iores;
- int ret;
-
- ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
- if (!ctrl) {
- dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
- return -ENOMEM;
- }
- spmi_controller = spmi_controller_get_drvdata(ctrl);
- spmi_controller->controller = ctrl;
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- dev_err(&pdev->dev, "can not get resource!\n");
- ret = -EINVAL;
- goto err_put_controller;
- }
-
- spmi_controller->base = devm_ioremap(&pdev->dev, iores->start,
- resource_size(iores));
- if (!spmi_controller->base) {
- dev_err(&pdev->dev, "can not remap base addr!\n");
- ret = -EADDRNOTAVAIL;
- goto err_put_controller;
- }
-
- ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel",
- &spmi_controller->channel);
- if (ret) {
- dev_err(&pdev->dev, "can not get channel\n");
- ret = -ENODEV;
- goto err_put_controller;
- }
-
- platform_set_drvdata(pdev, spmi_controller);
- dev_set_drvdata(&ctrl->dev, spmi_controller);
-
- spin_lock_init(&spmi_controller->lock);
-
- ctrl->nr = spmi_controller->channel;
- ctrl->dev.parent = pdev->dev.parent;
- ctrl->dev.of_node = of_node_get(pdev->dev.of_node);
-
- /* Callbacks */
- ctrl->read_cmd = spmi_read_cmd;
- ctrl->write_cmd = spmi_write_cmd;
-
- ret = spmi_controller_add(ctrl);
- if (ret) {
- dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret);
- goto err_put_controller;
- }
-
- return 0;
-
-err_put_controller:
- spmi_controller_put(ctrl);
- return ret;
-}
-
-static int spmi_del_controller(struct platform_device *pdev)
-{
- struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-
- spmi_controller_remove(ctrl);
- spmi_controller_put(ctrl);
- return 0;
-}
-
-static const struct of_device_id spmi_controller_match_table[] = {
- {
- .compatible = "hisilicon,kirin970-spmi-controller",
- },
- {}
-};
-MODULE_DEVICE_TABLE(of, spmi_controller_match_table);
-
-static struct platform_driver spmi_controller_driver = {
- .probe = spmi_controller_probe,
- .remove = spmi_del_controller,
- .driver = {
- .name = "hisi_spmi_controller",
- .of_match_table = spmi_controller_match_table,
- },
-};
-
-static int __init spmi_controller_init(void)
-{
- return platform_driver_register(&spmi_controller_driver);
-}
-postcore_initcall(spmi_controller_init);
-
-static void __exit spmi_controller_exit(void)
-{
- platform_driver_unregister(&spmi_controller_driver);
-}
-module_exit(spmi_controller_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:spmi_controller");
diff --git a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
deleted file mode 100644
index f882903769f9..000000000000
--- a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
+++ /dev/null
@@ -1,73 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/spmi/hisilicon,hisi-spmi-controller.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: HiSilicon SPMI controller
-
-maintainers:
- - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-
-description: |
- The HiSilicon SPMI BUS controller is found on some Kirin-based designs.
- It is a MIPI System Power Management (SPMI) controller.
-
- The PMIC part is provided by
- ./Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml.
-
-allOf:
- - $ref: spmi.yaml#
-
-properties:
-
- $nodename:
- pattern: "spmi@[0-9a-f]"
-
- compatible:
- const: hisilicon,kirin970-spmi-controller
-
- reg:
- maxItems: 1
-
- hisilicon,spmi-channel:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: |
- number of the Kirin 970 SPMI channel where the SPMI devices are connected.
-
-required:
- - compatible
- - reg
- - hisilicon,spmi-channel
-
-patternProperties:
- "@[0-9a-f]$":
- type: object
-
- description: |
- PMIC properties, which are specific to the used SPMI PMIC device(s).
- When used in combination with HiSilicon 6421v600, the properties
- are documented at
- drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml.
-
-unevaluatedProperties: false
-
-examples:
- - |
- bus {
- #address-cells = <2>;
- #size-cells = <2>;
-
- spmi: spmi@fff24000 {
- compatible = "hisilicon,kirin970-spmi-controller";
- #address-cells = <2>;
- #size-cells = <0>;
- reg = <0x0 0xfff24000 0x0 0x1000>;
- hisilicon,spmi-channel = <2>;
-
- pmic@0 {
- reg = <0 0>;
- /* pmic properties */
- };
- };
- };
--
2.31.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v7 6/8] mfd: hi6421-spmi-pmic: move driver from staging
2021-06-24 14:01 [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Mauro Carvalho Chehab
` (4 preceding siblings ...)
2021-06-24 14:01 ` [PATCH v7 5/8] spmi: hisi-spmi-controller: move driver from staging Mauro Carvalho Chehab
@ 2021-06-24 14:01 ` Mauro Carvalho Chehab
2021-06-24 14:27 ` [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Greg Kroah-Hartman
6 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2021-06-24 14:01 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
Rob Herring, devicetree, linux-kernel, linux-staging
This driver is ready for mainstream. So, move it out of staging.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
.../mfd/hisilicon,hi6421-spmi-pmic.yaml | 134 ++++++++
MAINTAINERS | 7 +
drivers/mfd/Kconfig | 16 +
drivers/mfd/Makefile | 1 +
drivers/mfd/hi6421-spmi-pmic.c | 311 ++++++++++++++++++
drivers/staging/Kconfig | 2 -
drivers/staging/Makefile | 1 -
drivers/staging/hikey9xx/Kconfig | 19 --
drivers/staging/hikey9xx/Makefile | 3 -
drivers/staging/hikey9xx/TODO | 5 -
drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 311 ------------------
.../hikey9xx/hisilicon,hi6421-spmi-pmic.yaml | 134 --------
12 files changed, 469 insertions(+), 475 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
create mode 100644 drivers/mfd/hi6421-spmi-pmic.c
delete mode 100644 drivers/staging/hikey9xx/Kconfig
delete mode 100644 drivers/staging/hikey9xx/Makefile
delete mode 100644 drivers/staging/hikey9xx/TODO
delete mode 100644 drivers/staging/hikey9xx/hi6421-spmi-pmic.c
delete mode 100644 drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
new file mode 100644
index 000000000000..8e355cddd437
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon 6421v600 SPMI PMIC
+
+maintainers:
+ - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+description: |
+ HiSilicon 6421v600 should be connected inside a MIPI System Power Management
+ (SPMI) bus. It provides interrupts and power supply.
+
+ The GPIO and interrupt settings are represented as part of the top-level PMIC
+ node.
+
+ The SPMI controller part is provided by
+ Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
+
+properties:
+ $nodename:
+ pattern: "pmic@[0-9a-f]"
+
+ compatible:
+ const: hisilicon,hi6421v600-spmi
+
+ reg:
+ maxItems: 1
+
+ '#interrupt-cells':
+ const: 2
+
+ interrupt-controller: true
+
+ gpios:
+ maxItems: 1
+ description: GPIO used for IRQs
+
+ regulators:
+ type: object
+
+ properties:
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ patternProperties:
+ '^ldo[0-9]+@[0-9a-f]$':
+ type: object
+
+ $ref: "/schemas/regulator/regulator.yaml#"
+
+required:
+ - compatible
+ - reg
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ /* pmic properties */
+
+ pmic: pmic@0 {
+ compatible = "hisilicon,hi6421-spmi";
+ reg = <0 0>;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ gpios = <&gpio28 0 0>;
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ldo3: LDO3 {
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-boot-on;
+ };
+
+ ldo4: LDO4 {
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <1725000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-boot-on;
+ };
+
+ ldo9: LDO9 {
+ regulator-name = "ldo9";
+ regulator-min-microvolt = <1750000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ ldo15: LDO15 {
+ regulator-name = "ldo15";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ ldo16: LDO16 {
+ regulator-name = "ldo16";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ };
+
+ ldo17: LDO17 {
+ regulator-name = "ldo17";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo33: LDO33 {
+ regulator-name = "ldo33";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ ldo34: LDO34 {
+ regulator-name = "ldo34";
+ regulator-min-microvolt = <2600000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 9a69e3810964..89e84b050de6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8291,6 +8291,13 @@ S: Maintained
F: Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
F: drivers/spmi/hisi-spmi-controller.c
+HISILICON SPMI PMIC DRIVER FOR HIKEY 6421v600
+M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
+F: drivers/mfd/hi6421-spmi-pmic.c
+
HISILICON STAGING DRIVERS FOR HIKEY 960/970
M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
S: Maintained
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 5c7f2b100191..99b8da2548b5 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -509,6 +509,22 @@ config MFD_HI6421_PMIC
menus in order to enable them.
We communicate with the Hi6421 via memory-mapped I/O.
+config MFD_HI6421_SPMI
+ tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC"
+ depends on OF
+ depends on SPMI
+ select MFD_CORE
+ select REGMAP_SPMI
+ help
+ Add support for HiSilicon Hi6421v600 SPMI PMIC. Hi6421 includes
+ multi-functions, such as regulators, RTC, codec, Coulomb counter,
+ etc.
+
+ This driver includes core APIs _only_. You have to select
+ individual components like voltage regulators under corresponding
+ menus in order to enable them.
+ We communicate with the Hi6421v600 via a SPMI bus.
+
config MFD_HI655X_PMIC
tristate "HiSilicon Hi655X series PMU/Codec IC"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 4f6d2b8a5f76..e87230fc61ac 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -232,6 +232,7 @@ obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o
obj-$(CONFIG_MFD_IQS62X) += iqs62x.o
obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o
obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o
+obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o
obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o
obj-$(CONFIG_MFD_DLN2) += dln2.o
obj-$(CONFIG_MFD_RT5033) += rt5033.o
diff --git a/drivers/mfd/hi6421-spmi-pmic.c b/drivers/mfd/hi6421-spmi-pmic.c
new file mode 100644
index 000000000000..252b731e272d
--- /dev/null
+++ b/drivers/mfd/hi6421-spmi-pmic.c
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device driver for regulators in HISI PMIC IC
+ *
+ * Copyright (c) 2013- Linaro Ltd.
+ * Copyright (c) 2011- Hisilicon.
+ * Copyright (c) 2020- Huawei Technologies Co., Ltd
+ */
+
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/hi6421-spmi-pmic.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spmi.h>
+
+enum hi6421_spmi_pmic_irq_list {
+ OTMP = 0,
+ VBUS_CONNECT,
+ VBUS_DISCONNECT,
+ ALARMON_R,
+ HOLD_6S,
+ HOLD_1S,
+ POWERKEY_UP,
+ POWERKEY_DOWN,
+ OCP_SCP_R,
+ COUL_R,
+ SIM0_HPD_R,
+ SIM0_HPD_F,
+ SIM1_HPD_R,
+ SIM1_HPD_F,
+
+ PMIC_IRQ_LIST_MAX
+};
+
+#define HISI_IRQ_BANK_SIZE 2
+
+/*
+ * IRQ number for the power key button and mask for both UP and DOWN IRQs
+ */
+#define HISI_POWERKEY_IRQ_NUM 0
+#define HISI_IRQ_POWERKEY_UP_DOWN (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
+
+/*
+ * Registers for IRQ address and IRQ mask bits
+ *
+ * Please notice that we need to regmap a larger region, as other
+ * registers are used by the regulators.
+ * See drivers/regulator/hi6421-regulator.c.
+ */
+#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202
+#define SOC_PMIC_IRQ0_ADDR 0x0212
+
+/*
+ * The IRQs are mapped as:
+ *
+ * ====================== ============= ============ =====
+ * IRQ MASK REGISTER IRQ REGISTER BIT
+ * ====================== ============= ============ =====
+ * OTMP 0x0202 0x212 bit 0
+ * VBUS_CONNECT 0x0202 0x212 bit 1
+ * VBUS_DISCONNECT 0x0202 0x212 bit 2
+ * ALARMON_R 0x0202 0x212 bit 3
+ * HOLD_6S 0x0202 0x212 bit 4
+ * HOLD_1S 0x0202 0x212 bit 5
+ * POWERKEY_UP 0x0202 0x212 bit 6
+ * POWERKEY_DOWN 0x0202 0x212 bit 7
+ *
+ * OCP_SCP_R 0x0203 0x213 bit 0
+ * COUL_R 0x0203 0x213 bit 1
+ * SIM0_HPD_R 0x0203 0x213 bit 2
+ * SIM0_HPD_F 0x0203 0x213 bit 3
+ * SIM1_HPD_R 0x0203 0x213 bit 4
+ * SIM1_HPD_F 0x0203 0x213 bit 5
+ * ====================== ============= ============ =====
+ *
+ * Each mask register contains 8 bits. The ancillary macros below
+ * convert a number from 0 to 14 into a register address and a bit mask
+ */
+#define HISI_IRQ_MASK_REG(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \
+ (irqd_to_hwirq(irq_data) / BITS_PER_BYTE))
+#define HISI_IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & (BITS_PER_BYTE - 1))
+#define HISI_8BITS_MASK 0xff
+
+static const struct mfd_cell hi6421v600_devs[] = {
+ { .name = "hi6421v600-regulator", },
+};
+
+static irqreturn_t hi6421_spmi_irq_handler(int irq, void *priv)
+{
+ struct hi6421_spmi_pmic *ddata = (struct hi6421_spmi_pmic *)priv;
+ unsigned long pending;
+ unsigned int in;
+ int i, offset;
+
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
+ regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &in);
+
+ /* Mark pending IRQs as handled */
+ regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, in);
+
+ pending = in & HISI_8BITS_MASK;
+
+ if (i == HISI_POWERKEY_IRQ_NUM &&
+ (pending & HISI_IRQ_POWERKEY_UP_DOWN) == HISI_IRQ_POWERKEY_UP_DOWN) {
+ /*
+ * If both powerkey down and up IRQs are received,
+ * handle them at the right order
+ */
+ generic_handle_irq(ddata->irqs[POWERKEY_DOWN]);
+ generic_handle_irq(ddata->irqs[POWERKEY_UP]);
+ pending &= ~HISI_IRQ_POWERKEY_UP_DOWN;
+ }
+
+ if (!pending)
+ continue;
+
+ for_each_set_bit(offset, &pending, BITS_PER_BYTE) {
+ generic_handle_irq(ddata->irqs[offset + i * BITS_PER_BYTE]);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void hi6421_spmi_irq_mask(struct irq_data *d)
+{
+ struct hi6421_spmi_pmic *ddata = irq_data_get_irq_chip_data(d);
+ unsigned long flags;
+ unsigned int data;
+ u32 offset;
+
+ offset = HISI_IRQ_MASK_REG(d);
+
+ spin_lock_irqsave(&ddata->lock, flags);
+
+ regmap_read(ddata->regmap, offset, &data);
+ data |= HISI_IRQ_MASK_BIT(d);
+ regmap_write(ddata->regmap, offset, data);
+
+ spin_unlock_irqrestore(&ddata->lock, flags);
+}
+
+static void hi6421_spmi_irq_unmask(struct irq_data *d)
+{
+ struct hi6421_spmi_pmic *ddata = irq_data_get_irq_chip_data(d);
+ u32 data, offset;
+ unsigned long flags;
+
+ offset = HISI_IRQ_MASK_REG(d);
+
+ spin_lock_irqsave(&ddata->lock, flags);
+
+ regmap_read(ddata->regmap, offset, &data);
+ data &= ~HISI_IRQ_MASK_BIT(d);
+ regmap_write(ddata->regmap, offset, data);
+
+ spin_unlock_irqrestore(&ddata->lock, flags);
+}
+
+static struct irq_chip hi6421_spmi_pmu_irqchip = {
+ .name = "hi6421v600-irq",
+ .irq_mask = hi6421_spmi_irq_mask,
+ .irq_unmask = hi6421_spmi_irq_unmask,
+ .irq_disable = hi6421_spmi_irq_mask,
+ .irq_enable = hi6421_spmi_irq_unmask,
+};
+
+static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct hi6421_spmi_pmic *ddata = d->host_data;
+
+ irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip,
+ handle_simple_irq, "hi6421v600");
+ irq_set_chip_data(virq, ddata);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
+
+ return 0;
+}
+
+static const struct irq_domain_ops hi6421_spmi_domain_ops = {
+ .map = hi6421_spmi_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static void hi6421_spmi_pmic_irq_init(struct hi6421_spmi_pmic *ddata)
+{
+ int i;
+ unsigned int pending;
+
+ /* Mask all IRQs */
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++)
+ regmap_write(ddata->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i,
+ HISI_8BITS_MASK);
+
+ /* Mark all IRQs as handled */
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
+ regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending);
+ regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i,
+ HISI_8BITS_MASK);
+ }
+}
+
+static const struct regmap_config regmap_config = {
+ .reg_bits = 16,
+ .val_bits = BITS_PER_BYTE,
+ .max_register = 0xffff,
+ .fast_io = true
+};
+
+static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct hi6421_spmi_pmic *ddata;
+ unsigned int virq;
+ int ret, i;
+
+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ ddata->regmap = devm_regmap_init_spmi_ext(pdev, ®map_config);
+ if (IS_ERR(ddata->regmap))
+ return PTR_ERR(ddata->regmap);
+
+ spin_lock_init(&ddata->lock);
+
+ ddata->dev = dev;
+
+ ddata->gpio = of_get_gpio(np, 0);
+ if (ddata->gpio < 0)
+ return ddata->gpio;
+
+ if (!gpio_is_valid(ddata->gpio))
+ return -EINVAL;
+
+ ret = devm_gpio_request_one(dev, ddata->gpio, GPIOF_IN, "pmic");
+ if (ret < 0) {
+ dev_err(dev, "Failed to request gpio%d\n", ddata->gpio);
+ return ret;
+ }
+
+ ddata->irq = gpio_to_irq(ddata->gpio);
+
+ hi6421_spmi_pmic_irq_init(ddata);
+
+ ddata->irqs = devm_kzalloc(dev, PMIC_IRQ_LIST_MAX * sizeof(int), GFP_KERNEL);
+ if (!ddata->irqs)
+ return -ENOMEM;
+
+ ddata->domain = irq_domain_add_simple(np, PMIC_IRQ_LIST_MAX, 0,
+ &hi6421_spmi_domain_ops, ddata);
+ if (!ddata->domain) {
+ dev_err(dev, "Failed to create IRQ domain\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; i < PMIC_IRQ_LIST_MAX; i++) {
+ virq = irq_create_mapping(ddata->domain, i);
+ if (!virq) {
+ dev_err(dev, "Failed to map H/W IRQ\n");
+ return -ENODEV;
+ }
+ ddata->irqs[i] = virq;
+ }
+
+ ret = devm_request_threaded_irq(dev,
+ ddata->irq, hi6421_spmi_irq_handler,
+ NULL,
+ IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
+ "pmic", ddata);
+ if (ret < 0) {
+ dev_err(dev, "Failed to start IRQ handling thread: error %d\n",
+ ret);
+ return ret;
+ }
+
+ dev_set_drvdata(&pdev->dev, ddata);
+
+ ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
+ hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs),
+ NULL, 0, NULL);
+ if (ret < 0)
+ dev_err(dev, "Failed to add child devices: %d\n", ret);
+
+ return ret;
+}
+
+static const struct of_device_id pmic_spmi_id_table[] = {
+ { .compatible = "hisilicon,hi6421-spmi" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
+
+static struct spmi_driver hi6421_spmi_pmic_driver = {
+ .driver = {
+ .name = "hi6421-spmi-pmic",
+ .of_match_table = pmic_spmi_id_table,
+ },
+ .probe = hi6421_spmi_pmic_probe,
+};
+module_spmi_driver(hi6421_spmi_pmic_driver);
+
+MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index b7ae5bdc4eb5..5b4267d3ed6b 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -104,6 +104,4 @@ source "drivers/staging/qlge/Kconfig"
source "drivers/staging/wfx/Kconfig"
-source "drivers/staging/hikey9xx/Kconfig"
-
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 075c979bfe7c..7179cdcaafe7 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -42,4 +42,3 @@ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
obj-$(CONFIG_KPC2000) += kpc2000/
obj-$(CONFIG_QLGE) += qlge/
obj-$(CONFIG_WFX) += wfx/
-obj-y += hikey9xx/
diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig
deleted file mode 100644
index 9f53df9068fe..000000000000
--- a/drivers/staging/hikey9xx/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# to be placed at drivers/mfd
-config MFD_HI6421_SPMI
- tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC"
- depends on HAS_IOMEM
- depends on OF
- depends on SPMI
- select MFD_CORE
- select REGMAP_SPMI
- help
- Add support for HiSilicon Hi6421v600 SPMI PMIC. Hi6421 includes
- multi-functions, such as regulators, RTC, codec, Coulomb counter,
- etc.
-
- This driver includes core APIs _only_. You have to select
- individual components like voltage regulators under corresponding
- menus in order to enable them.
- We communicate with the Hi6421v600 via a SPMI bus.
diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile
deleted file mode 100644
index e3108d7dd849..000000000000
--- a/drivers/staging/hikey9xx/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o
diff --git a/drivers/staging/hikey9xx/TODO b/drivers/staging/hikey9xx/TODO
deleted file mode 100644
index 65e7996a3066..000000000000
--- a/drivers/staging/hikey9xx/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
-ToDo list:
-
-- Port other drivers needed by Hikey 960/970;
-- Test drivers on Hikey 960;
-- Validate device tree bindings.
diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
deleted file mode 100644
index 252b731e272d..000000000000
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ /dev/null
@@ -1,311 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Device driver for regulators in HISI PMIC IC
- *
- * Copyright (c) 2013- Linaro Ltd.
- * Copyright (c) 2011- Hisilicon.
- * Copyright (c) 2020- Huawei Technologies Co., Ltd
- */
-
-#include <linux/bitops.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/hi6421-spmi-pmic.h>
-#include <linux/module.h>
-#include <linux/of_gpio.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/spmi.h>
-
-enum hi6421_spmi_pmic_irq_list {
- OTMP = 0,
- VBUS_CONNECT,
- VBUS_DISCONNECT,
- ALARMON_R,
- HOLD_6S,
- HOLD_1S,
- POWERKEY_UP,
- POWERKEY_DOWN,
- OCP_SCP_R,
- COUL_R,
- SIM0_HPD_R,
- SIM0_HPD_F,
- SIM1_HPD_R,
- SIM1_HPD_F,
-
- PMIC_IRQ_LIST_MAX
-};
-
-#define HISI_IRQ_BANK_SIZE 2
-
-/*
- * IRQ number for the power key button and mask for both UP and DOWN IRQs
- */
-#define HISI_POWERKEY_IRQ_NUM 0
-#define HISI_IRQ_POWERKEY_UP_DOWN (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
-
-/*
- * Registers for IRQ address and IRQ mask bits
- *
- * Please notice that we need to regmap a larger region, as other
- * registers are used by the regulators.
- * See drivers/regulator/hi6421-regulator.c.
- */
-#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202
-#define SOC_PMIC_IRQ0_ADDR 0x0212
-
-/*
- * The IRQs are mapped as:
- *
- * ====================== ============= ============ =====
- * IRQ MASK REGISTER IRQ REGISTER BIT
- * ====================== ============= ============ =====
- * OTMP 0x0202 0x212 bit 0
- * VBUS_CONNECT 0x0202 0x212 bit 1
- * VBUS_DISCONNECT 0x0202 0x212 bit 2
- * ALARMON_R 0x0202 0x212 bit 3
- * HOLD_6S 0x0202 0x212 bit 4
- * HOLD_1S 0x0202 0x212 bit 5
- * POWERKEY_UP 0x0202 0x212 bit 6
- * POWERKEY_DOWN 0x0202 0x212 bit 7
- *
- * OCP_SCP_R 0x0203 0x213 bit 0
- * COUL_R 0x0203 0x213 bit 1
- * SIM0_HPD_R 0x0203 0x213 bit 2
- * SIM0_HPD_F 0x0203 0x213 bit 3
- * SIM1_HPD_R 0x0203 0x213 bit 4
- * SIM1_HPD_F 0x0203 0x213 bit 5
- * ====================== ============= ============ =====
- *
- * Each mask register contains 8 bits. The ancillary macros below
- * convert a number from 0 to 14 into a register address and a bit mask
- */
-#define HISI_IRQ_MASK_REG(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \
- (irqd_to_hwirq(irq_data) / BITS_PER_BYTE))
-#define HISI_IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & (BITS_PER_BYTE - 1))
-#define HISI_8BITS_MASK 0xff
-
-static const struct mfd_cell hi6421v600_devs[] = {
- { .name = "hi6421v600-regulator", },
-};
-
-static irqreturn_t hi6421_spmi_irq_handler(int irq, void *priv)
-{
- struct hi6421_spmi_pmic *ddata = (struct hi6421_spmi_pmic *)priv;
- unsigned long pending;
- unsigned int in;
- int i, offset;
-
- for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
- regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &in);
-
- /* Mark pending IRQs as handled */
- regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, in);
-
- pending = in & HISI_8BITS_MASK;
-
- if (i == HISI_POWERKEY_IRQ_NUM &&
- (pending & HISI_IRQ_POWERKEY_UP_DOWN) == HISI_IRQ_POWERKEY_UP_DOWN) {
- /*
- * If both powerkey down and up IRQs are received,
- * handle them at the right order
- */
- generic_handle_irq(ddata->irqs[POWERKEY_DOWN]);
- generic_handle_irq(ddata->irqs[POWERKEY_UP]);
- pending &= ~HISI_IRQ_POWERKEY_UP_DOWN;
- }
-
- if (!pending)
- continue;
-
- for_each_set_bit(offset, &pending, BITS_PER_BYTE) {
- generic_handle_irq(ddata->irqs[offset + i * BITS_PER_BYTE]);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-static void hi6421_spmi_irq_mask(struct irq_data *d)
-{
- struct hi6421_spmi_pmic *ddata = irq_data_get_irq_chip_data(d);
- unsigned long flags;
- unsigned int data;
- u32 offset;
-
- offset = HISI_IRQ_MASK_REG(d);
-
- spin_lock_irqsave(&ddata->lock, flags);
-
- regmap_read(ddata->regmap, offset, &data);
- data |= HISI_IRQ_MASK_BIT(d);
- regmap_write(ddata->regmap, offset, data);
-
- spin_unlock_irqrestore(&ddata->lock, flags);
-}
-
-static void hi6421_spmi_irq_unmask(struct irq_data *d)
-{
- struct hi6421_spmi_pmic *ddata = irq_data_get_irq_chip_data(d);
- u32 data, offset;
- unsigned long flags;
-
- offset = HISI_IRQ_MASK_REG(d);
-
- spin_lock_irqsave(&ddata->lock, flags);
-
- regmap_read(ddata->regmap, offset, &data);
- data &= ~HISI_IRQ_MASK_BIT(d);
- regmap_write(ddata->regmap, offset, data);
-
- spin_unlock_irqrestore(&ddata->lock, flags);
-}
-
-static struct irq_chip hi6421_spmi_pmu_irqchip = {
- .name = "hi6421v600-irq",
- .irq_mask = hi6421_spmi_irq_mask,
- .irq_unmask = hi6421_spmi_irq_unmask,
- .irq_disable = hi6421_spmi_irq_mask,
- .irq_enable = hi6421_spmi_irq_unmask,
-};
-
-static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct hi6421_spmi_pmic *ddata = d->host_data;
-
- irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip,
- handle_simple_irq, "hi6421v600");
- irq_set_chip_data(virq, ddata);
- irq_set_irq_type(virq, IRQ_TYPE_NONE);
-
- return 0;
-}
-
-static const struct irq_domain_ops hi6421_spmi_domain_ops = {
- .map = hi6421_spmi_irq_map,
- .xlate = irq_domain_xlate_twocell,
-};
-
-static void hi6421_spmi_pmic_irq_init(struct hi6421_spmi_pmic *ddata)
-{
- int i;
- unsigned int pending;
-
- /* Mask all IRQs */
- for (i = 0; i < HISI_IRQ_BANK_SIZE; i++)
- regmap_write(ddata->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i,
- HISI_8BITS_MASK);
-
- /* Mark all IRQs as handled */
- for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
- regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending);
- regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i,
- HISI_8BITS_MASK);
- }
-}
-
-static const struct regmap_config regmap_config = {
- .reg_bits = 16,
- .val_bits = BITS_PER_BYTE,
- .max_register = 0xffff,
- .fast_io = true
-};
-
-static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct device_node *np = dev->of_node;
- struct hi6421_spmi_pmic *ddata;
- unsigned int virq;
- int ret, i;
-
- ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
- if (!ddata)
- return -ENOMEM;
-
- ddata->regmap = devm_regmap_init_spmi_ext(pdev, ®map_config);
- if (IS_ERR(ddata->regmap))
- return PTR_ERR(ddata->regmap);
-
- spin_lock_init(&ddata->lock);
-
- ddata->dev = dev;
-
- ddata->gpio = of_get_gpio(np, 0);
- if (ddata->gpio < 0)
- return ddata->gpio;
-
- if (!gpio_is_valid(ddata->gpio))
- return -EINVAL;
-
- ret = devm_gpio_request_one(dev, ddata->gpio, GPIOF_IN, "pmic");
- if (ret < 0) {
- dev_err(dev, "Failed to request gpio%d\n", ddata->gpio);
- return ret;
- }
-
- ddata->irq = gpio_to_irq(ddata->gpio);
-
- hi6421_spmi_pmic_irq_init(ddata);
-
- ddata->irqs = devm_kzalloc(dev, PMIC_IRQ_LIST_MAX * sizeof(int), GFP_KERNEL);
- if (!ddata->irqs)
- return -ENOMEM;
-
- ddata->domain = irq_domain_add_simple(np, PMIC_IRQ_LIST_MAX, 0,
- &hi6421_spmi_domain_ops, ddata);
- if (!ddata->domain) {
- dev_err(dev, "Failed to create IRQ domain\n");
- return -ENODEV;
- }
-
- for (i = 0; i < PMIC_IRQ_LIST_MAX; i++) {
- virq = irq_create_mapping(ddata->domain, i);
- if (!virq) {
- dev_err(dev, "Failed to map H/W IRQ\n");
- return -ENODEV;
- }
- ddata->irqs[i] = virq;
- }
-
- ret = devm_request_threaded_irq(dev,
- ddata->irq, hi6421_spmi_irq_handler,
- NULL,
- IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
- "pmic", ddata);
- if (ret < 0) {
- dev_err(dev, "Failed to start IRQ handling thread: error %d\n",
- ret);
- return ret;
- }
-
- dev_set_drvdata(&pdev->dev, ddata);
-
- ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
- hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs),
- NULL, 0, NULL);
- if (ret < 0)
- dev_err(dev, "Failed to add child devices: %d\n", ret);
-
- return ret;
-}
-
-static const struct of_device_id pmic_spmi_id_table[] = {
- { .compatible = "hisilicon,hi6421-spmi" },
- { }
-};
-MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
-
-static struct spmi_driver hi6421_spmi_pmic_driver = {
- .driver = {
- .name = "hi6421-spmi-pmic",
- .of_match_table = pmic_spmi_id_table,
- },
- .probe = hi6421_spmi_pmic_probe,
-};
-module_spmi_driver(hi6421_spmi_pmic_driver);
-
-MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
deleted file mode 100644
index 8e355cddd437..000000000000
--- a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
+++ /dev/null
@@ -1,134 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: HiSilicon 6421v600 SPMI PMIC
-
-maintainers:
- - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-
-description: |
- HiSilicon 6421v600 should be connected inside a MIPI System Power Management
- (SPMI) bus. It provides interrupts and power supply.
-
- The GPIO and interrupt settings are represented as part of the top-level PMIC
- node.
-
- The SPMI controller part is provided by
- Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
-
-properties:
- $nodename:
- pattern: "pmic@[0-9a-f]"
-
- compatible:
- const: hisilicon,hi6421v600-spmi
-
- reg:
- maxItems: 1
-
- '#interrupt-cells':
- const: 2
-
- interrupt-controller: true
-
- gpios:
- maxItems: 1
- description: GPIO used for IRQs
-
- regulators:
- type: object
-
- properties:
- '#address-cells':
- const: 1
-
- '#size-cells':
- const: 0
-
- patternProperties:
- '^ldo[0-9]+@[0-9a-f]$':
- type: object
-
- $ref: "/schemas/regulator/regulator.yaml#"
-
-required:
- - compatible
- - reg
- - regulators
-
-additionalProperties: false
-
-examples:
- - |
- /* pmic properties */
-
- pmic: pmic@0 {
- compatible = "hisilicon,hi6421-spmi";
- reg = <0 0>;
-
- #interrupt-cells = <2>;
- interrupt-controller;
- gpios = <&gpio28 0 0>;
-
- regulators {
- #address-cells = <1>;
- #size-cells = <0>;
-
- ldo3: LDO3 {
- regulator-name = "ldo3";
- regulator-min-microvolt = <1500000>;
- regulator-max-microvolt = <2000000>;
- regulator-boot-on;
- };
-
- ldo4: LDO4 {
- regulator-name = "ldo4";
- regulator-min-microvolt = <1725000>;
- regulator-max-microvolt = <1900000>;
- regulator-boot-on;
- };
-
- ldo9: LDO9 {
- regulator-name = "ldo9";
- regulator-min-microvolt = <1750000>;
- regulator-max-microvolt = <3300000>;
- regulator-boot-on;
- };
-
- ldo15: LDO15 {
- regulator-name = "ldo15";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3000000>;
- regulator-always-on;
- };
-
- ldo16: LDO16 {
- regulator-name = "ldo16";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3000000>;
- regulator-boot-on;
- };
-
- ldo17: LDO17 {
- regulator-name = "ldo17";
- regulator-min-microvolt = <2500000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo33: LDO33 {
- regulator-name = "ldo33";
- regulator-min-microvolt = <2500000>;
- regulator-max-microvolt = <3300000>;
- regulator-boot-on;
- };
-
- ldo34: LDO34 {
- regulator-name = "ldo34";
- regulator-min-microvolt = <2600000>;
- regulator-max-microvolt = <3300000>;
- };
- };
- };
--
2.31.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging
2021-06-24 14:01 [PATCH v7 0/8] Move Hisilicon 6421v600 SPMI and USB drivers out of staging Mauro Carvalho Chehab
` (5 preceding siblings ...)
2021-06-24 14:01 ` [PATCH v7 6/8] mfd: hi6421-spmi-pmic: " Mauro Carvalho Chehab
@ 2021-06-24 14:27 ` Greg Kroah-Hartman
6 siblings, 0 replies; 12+ messages in thread
From: Greg Kroah-Hartman @ 2021-06-24 14:27 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: linuxarm, mauro.chehab, Lee Jones, Rob Herring, Stephen Boyd,
devicetree, linux-arm-kernel, linux-kernel, linux-phy,
linux-staging, linux-usb
On Thu, Jun 24, 2021 at 04:01:29PM +0200, Mauro Carvalho Chehab wrote:
> Hi Greg,
>
> Those are the remaining patches that are needed for the USB to work
> with Hikey970.
>
> This series address the comments made on v5. Sorry for taking so long to
> return back on this. Got sidetracked by other unrelated stuff.
I took the first 2 patches in here.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 12+ messages in thread