linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/44] SPMI patches needed by Hikey 970
@ 2020-08-17  7:10 Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 01/44] staging: spmi: add Hikey 970 SPMI controller driver Mauro Carvalho Chehab
                   ` (45 more replies)
  0 siblings, 46 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Rob Herring,
	devicetree, Lee Jones, David S. Miller, linux-arm-kernel,
	Rob Herring, linux-arm-msm, Wei Xu, devel, linux-kernel,
	Stephen Boyd

Hi Greg,

This patch series is part of a work I'm doing in order to be able to support
a HiKey 970 board that I recently got on my hands.

Regards,
Mauro.

v1:
   submitted to drivers/{mfd,spmi,regulator}

v2:
  - submitted via staging, mainly to preserve original
    authorship and his SoB;
  - as requested on previous review, patches were split per
    target subsystem.

v3:
  - Some coding style changes, due to reviews from Joe Perches

Patches were tested on a Hikey 970 board.

Mauro Carvalho Chehab (41):
  staging: spmi: hisi-spmi-controller: coding style fixup
  staging: spmi: hisi-spmi-controller: fix it to probe successfully
  staging: spmi: hisi-spmi-controller: fix a typo
  staging: spmi: hisi-spmi-controller: adjust whitespaces at defines
  staging: spmi: hisi-spmi-controller: use le32 macros where needed
  staging: spmi: hisi-spmi-controller: add debug when values are
    read/write
  staging: spmi: hisi-spmi-controller: fix the dev_foo() logic
  staging: spmi: hisi-spmi-controller: add it to the building system
  staging: spmi: hisi-spmi-controller: do some code cleanups
  staging: mfd: hi6421-spmi-pmic: get rid of unused code
  staging: mfd: hi6421-spmi-pmic: deal with non-static functions
  staging: mfd: hi6421-spmi-pmic: get rid of the static vars
  staging: mfd: hi6421-spmi-pmic: cleanup hi6421-spmi-pmic.h header
  staging: mfd: hi6421-spmi-pmic: change the binding logic
  staging: mfd: hi6421-spmi-pmic: get rid of unused OF properties
  staging: mfd: hi6421-spmi-pmic: cleanup OF properties
  staging: mfd: hi6421-spmi-pmic: change namespace on its functions
  staging: mfd: hi6421-spmi-pmic: fix some coding style issues
  staging: mfd: hi6421-spmi-pmic: add it to the building system
  staging: mfd: hi6421-spmi-pmic: cleanup the code
  staging: regulator: hi6421v600-regulator: get rid of unused code
  staging: regulator: hi6421v600-regulator: port it to upstream
  staging: regulator: hi6421v600-regulator: coding style fixups
  staging: regulator: hi6421v600-regulator: change the binding logic
  staging: regulator: hi6421v600-regulator: cleanup struct
    hisi_regulator
  staging: regulator: hi6421v600-regulator: cleanup debug messages
  staging: regulator: hi6421v600-regulator: use shorter names for OF
    properties
  staging: regulator: hi6421v600-regulator: better handle modes
  staging: regulator: hi6421v600-regulator: change namespace
  staging: regulator: hi6421v600-regulator: convert to use get/set
    voltage_sel
  staging: regulator: hi6421v600-regulator: don't use usleep_range for
    off_on_delay
  staging: regulator: hi6421v600-regulator: add a driver-specific debug
    macro
  staging: regulator: hi6421v600-regulator: initialize ramp_delay
  staging: regulator: hi6421v600-regulator: cleanup DT settings
  staging: regulator: hi6421v600-regulator: fix some coding style issues
  staging: regulator: hi6421v600-regulator: add it to the building
    system
  staging: regulator: hi6421v600-regulator: code cleanup
  staging: hikey9xx: add a TODO list
  MAINTAINERS: add an entry for HiSilicon 6421v600 drivers
  dt: document HiSilicon SPMI controller and mfd/regulator properties
  dt: hisilicon: add support for the PMIC found on Hikey 970

Mayulong (3):
  staging: spmi: add Hikey 970 SPMI controller driver
  staging: mfd: add a PMIC driver for HiSilicon 6421 SPMI version
  staging: regulator: add a regulator driver for HiSilicon 6421v600 SPMI
    PMIC

 .../mfd/hisilicon,hi6421-spmi-pmic.yaml       | 182 +++++++
 .../spmi/hisilicon,hisi-spmi-controller.yaml  |  54 ++
 MAINTAINERS                                   |   6 +
 .../boot/dts/hisilicon/hi3670-hikey970.dts    |  22 +-
 .../boot/dts/hisilicon/hikey970-pmic.dtsi     | 200 ++++++++
 drivers/staging/Kconfig                       |   2 +
 drivers/staging/Makefile                      |   1 +
 drivers/staging/hikey9xx/Kconfig              |  35 ++
 drivers/staging/hikey9xx/Makefile             |   5 +
 drivers/staging/hikey9xx/TODO                 |   5 +
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c   | 382 ++++++++++++++
 .../staging/hikey9xx/hi6421v600-regulator.c   | 479 ++++++++++++++++++
 .../staging/hikey9xx/hisi-spmi-controller.c   | 356 +++++++++++++
 include/linux/mfd/hi6421-spmi-pmic.h          |  68 +++
 14 files changed, 1778 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
 create mode 100644 Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
 create mode 100644 arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi
 create mode 100644 drivers/staging/hikey9xx/Kconfig
 create mode 100644 drivers/staging/hikey9xx/Makefile
 create mode 100644 drivers/staging/hikey9xx/TODO
 create mode 100644 drivers/staging/hikey9xx/hi6421-spmi-pmic.c
 create mode 100644 drivers/staging/hikey9xx/hi6421v600-regulator.c
 create mode 100644 drivers/staging/hikey9xx/hisi-spmi-controller.c
 create mode 100644 include/linux/mfd/hi6421-spmi-pmic.h

-- 
2.26.2



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH v3 01/44] staging: spmi: add Hikey 970 SPMI controller driver
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 02/44] staging: spmi: hisi-spmi-controller: coding style fixup Mauro Carvalho Chehab
                   ` (44 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mayulong, Mauro Carvalho Chehab,
	linux-kernel, devel

From: Mayulong <mayulong1@huawei.com>

Add the SPMI controller code required to use the Kirin 970
SPMI bus.

[mchehab+huawei@kernel.org: added just the SPMI controller on this patch]

The complete patch is at:

	https://github.com/96boards-hikey/linux/commit/08464419fba2

Signed-off-by: Mayulong <mayulong1@huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hisi-spmi-controller.c   | 390 ++++++++++++++++++
 1 file changed, 390 insertions(+)
 create mode 100644 drivers/staging/hikey9xx/hisi-spmi-controller.c

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
new file mode 100644
index 000000000000..987526c8b49f
--- /dev/null
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -0,0 +1,390 @@
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/spmi.h>
+#include <linux/spmi.h>
+
+#define SPMI_CONTROLLER_NAME		"spmi_controller"
+
+/*
+ * SPMI register addr
+ */
+#define SPMI_CHANNEL_OFFSET					0x0300
+#define SPMI_SLAVE_OFFSET						0x20
+
+#define SPMI_APB_SPMI_CMD_BASE_ADDR				0x0100
+/*lint -e750 -esym(750,*)*/
+#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
+/*lint +e750 -esym(750,*)*/
+
+#define SPMI_PER_DATAREG_BYTE					4
+/*
+ * SPMI cmd register
+ */
+#define SPMI_APB_SPMI_CMD_EN						(1 << 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
+
+#define Tranverse32(X)                 ((((u32)(X) & 0xff000000) >> 24) | \
+							   (((u32)(X) & 0x00ff0000) >> 8) | \
+							   (((u32)(X) & 0x0000ff00) << 8) | \
+							   (((u32)(X) & 0x000000ff) << 24))
+
+/* Command Opcodes */
+/*lint -e749 -esym(749,*)*/
+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,
+};
+/*lint +e749 -esym(749,*)*/
+
+/*
+ * SPMI status register
+ */
+#define SPMI_APB_TRANS_DONE						(1 << 0)
+#define SPMI_APB_TRANS_FAIL						(1 << 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)
+
+#define SPMI_WRITEL( dev, reg, addr )	\
+	do { \
+		writel( ( reg ), ( addr ) ); \
+	} while (0)
+
+#define  SPMI_READL( dev, reg, addr )	\
+	do { \
+		reg = readl( addr ); \
+	} while (0)
+
+/*
+ * @base base address of the PMIC Arbiter core registers.
+ * @rdbase, @wrbase base address of the PMIC Arbiter read core registers.
+ *     For HW-v1 these are equal to base.
+ *     For HW-v2, the value is the same in eeraly probing, in order to read
+ *     PMIC_ARB_CORE registers, then chnls, and obsrvr are set to
+ *     PMIC_ARB_CORE_REGISTERS and PMIC_ARB_CORE_REGISTERS_OBS respectivly.
+ * @intr base address of the SPMI interrupt control registers
+ * @ppid_2_chnl_tbl lookup table f(SID, Periph-ID) -> channel num
+ *      entry is only valid if corresponding bit is set in valid_ppid_bitmap.
+ * @valid_ppid_bitmap bit is set only for valid ppids.
+ * @fmt_cmd formats a command to be set into PMIC_ARBq_CHNLn_CMD
+ * @chnl_ofst calculates offset of the base of a channel reg space
+ * @ee execution environment id
+ * @irq_acc0_init_val initial value of the interrupt accumulator at probe time.
+ *      Use for an HW workaround. On handling interrupts, the first accumulator
+ *      register will be compared against this value, and bits which are set at
+ *      boot will be ignored.
+ * @reserved_chnl entry of ppid_2_chnl_tbl that this driver should never touch.
+ *      value is positive channel number or negative to mark it unused.
+ */
+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 spmi_controller_dev *ctrl_dev,
+				  void __iomem *base, u8 sid, u16 addr)
+{
+	u32 status = 0;
+	u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
+	u32 offset = SPMI_APB_SPMI_STATUS_BASE_ADDR + SPMI_CHANNEL_OFFSET * ctrl_dev->channel
+		+ SPMI_SLAVE_OFFSET * sid;
+
+	while (timeout--) {
+		SPMI_READL(ctrl_dev->dev, status, base + offset);/*lint !e732 */
+
+		if (status & SPMI_APB_TRANS_DONE) {
+			if (status & SPMI_APB_TRANS_FAIL) {
+				dev_err(ctrl_dev->dev,
+					"%s: transaction failed (0x%x)\n",
+					__func__, status);
+				return -EIO;
+			}
+			return 0;
+		}
+		udelay(1);/*lint !e778 !e774 !e747*/
+	}
+
+	dev_err(ctrl_dev->dev,
+		"%s: timeout, status 0x%x\n",
+		__func__, status);
+	return -ETIMEDOUT;/*lint !e438*/
+}/*lint !e715 !e529*/
+
+static int spmi_read_cmd(struct spmi_controller *ctrl,
+				u8 opc, u8 sid, u16 addr, u8 *buf, size_t bc)
+{
+	struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
+	unsigned long flags;
+	u32 cmd, data;
+	int rc;
+	u32 chnl_ofst = SPMI_CHANNEL_OFFSET*spmi_controller->channel;
+	u8 op_code, i;
+
+	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
+		dev_err(spmi_controller->dev
+		, "spmi_controller supports 1..%d bytes per trans, but:%ld requested"
+					, SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
+		return  -EINVAL;
+	}
+
+	/* Check the opcode */
+	if (SPMI_CMD_READ == opc)
+		op_code = SPMI_CMD_REG_READ;
+	else if (SPMI_CMD_EXT_READ == opc)
+		op_code = SPMI_CMD_EXT_REG_READ;
+	else if (SPMI_CMD_EXT_READL == opc)
+		op_code = SPMI_CMD_EXT_REG_READ_L;
+	else {
+		dev_err(spmi_controller->dev, "invalid read cmd 0x%x", opc);
+		return -EINVAL;
+	}
+
+	cmd = SPMI_APB_SPMI_CMD_EN |/*lint !e648 !e701 */								/* cmd_en */
+		 (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |/*lint !e648 !e701 */			/* cmd_type */
+		 ((bc-1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |/*lint !e648 !e701 */		/* byte_cnt */
+		 ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |						/* slvid */
+		 ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET);					/* slave_addr */
+
+	spin_lock_irqsave(&spmi_controller->lock, flags);/*lint !e550 */
+
+	SPMI_WRITEL(spmi_controller->dev, cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
+
+
+	rc = spmi_controller_wait_for_done(spmi_controller, spmi_controller->base, sid, addr);
+	if (rc)
+		goto done;
+
+	i = 0;
+	do {
+		SPMI_READL(spmi_controller->dev, data, spmi_controller->base + chnl_ofst + SPMI_SLAVE_OFFSET*sid + SPMI_APB_SPMI_RDATA0_BASE_ADDR + i*SPMI_PER_DATAREG_BYTE);/*lint !e732 */
+		data = Tranverse32(data);
+		if ((bc - i*SPMI_PER_DATAREG_BYTE ) >> 2) {/*lint !e702 */
+			memcpy(buf, &data, sizeof(data));
+			buf += sizeof(data);
+		} else {
+			memcpy(buf, &data, bc%SPMI_PER_DATAREG_BYTE);/*lint !e747 */
+			buf += (bc%SPMI_PER_DATAREG_BYTE);
+		}
+		i++;
+	} while (bc > i*SPMI_PER_DATAREG_BYTE);
+
+done:
+	spin_unlock_irqrestore(&spmi_controller->lock, flags);
+	if (rc)
+		dev_err(spmi_controller->dev, "spmi read wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
+							opc, sid, addr, bc + 1);
+	return rc;
+}/*lint !e550 !e529*/
+
+/*lint -e438 -esym(438,*)*/
+static int spmi_write_cmd(struct spmi_controller *ctrl,
+				u8 opc, u8 sid, u16 addr, const u8 *buf, size_t bc)
+{
+	struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
+	unsigned long flags;
+	u32 cmd;
+	u32 data = 0;
+	int rc;
+	u32 chnl_ofst = SPMI_CHANNEL_OFFSET*spmi_controller->channel;
+	u8 op_code, i;
+
+
+	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
+		dev_err(spmi_controller->dev
+		, "spmi_controller supports 1..%d bytes per trans, but:%ld requested"
+					, SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
+		return  -EINVAL;
+	}
+
+	/* Check the opcode */
+	if (SPMI_CMD_WRITE == opc)
+		op_code = SPMI_CMD_REG_WRITE;
+	else if (SPMI_CMD_EXT_WRITE == opc)
+		op_code = SPMI_CMD_EXT_REG_WRITE;
+	else if (SPMI_CMD_EXT_WRITEL == opc)
+		op_code = SPMI_CMD_EXT_REG_WRITE_L;
+	else {
+		dev_err(spmi_controller->dev, "invalid write cmd 0x%x", opc);
+		return -EINVAL;
+	}
+
+	cmd = SPMI_APB_SPMI_CMD_EN |/*lint !e648 !e701 */								/* cmd_en */
+		 (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |/*lint !e648 !e701 */			/* cmd_type */
+		 ((bc-1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |/*lint !e648 !e701 */		/* byte_cnt */
+		 ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |						/* slvid */
+		 ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET);					/* slave_addr */
+
+	/* Write data to FIFOs */
+	spin_lock_irqsave(&spmi_controller->lock, flags);/*lint !e550 */
+
+	i = 0;
+	do {
+		memset(&data, 0, sizeof(data));
+		if ((bc - i*SPMI_PER_DATAREG_BYTE ) >> 2) {/*lint !e702 */
+			memcpy(&data, buf, sizeof(data));
+			buf +=sizeof(data);
+		} else {
+			memcpy(&data, buf, bc%SPMI_PER_DATAREG_BYTE);/*lint !e747 */
+			buf +=(bc%SPMI_PER_DATAREG_BYTE);
+		}
+
+		data = Tranverse32(data);
+		SPMI_WRITEL(spmi_controller->dev, data, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_WDATA0_BASE_ADDR+SPMI_PER_DATAREG_BYTE*i);
+		i++;
+	} while (bc > i*SPMI_PER_DATAREG_BYTE);
+
+	/* Start the transaction */
+	SPMI_WRITEL(spmi_controller->dev, cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
+
+	rc = spmi_controller_wait_for_done(spmi_controller, spmi_controller->base, sid, addr);
+	spin_unlock_irqrestore(&spmi_controller->lock, flags);
+
+	if (rc)
+		dev_err(spmi_controller->dev, "spmi write wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
+							opc, sid, addr, bc);
+
+	return rc;
+}/*lint !e438 !e550 !e529*/
+/*lint +e438 -esym(438,*)*/
+static int spmi_controller_probe(struct platform_device *pdev)
+{
+	struct spmi_controller_dev *spmi_controller;
+	struct spmi_controller *ctrl;
+	struct resource *iores;
+	int ret = 0;
+
+	printk(KERN_INFO "HISI SPMI probe\n");
+	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
+	if (!ctrl) {
+		dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
+		return -ENOMEM;  /*lint !e429*/
+	}
+	spmi_controller = spmi_controller_get_drvdata(ctrl);
+	spmi_controller->controller = ctrl;
+
+	/* NOTE: driver uses the static register mapping */
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iores) {
+		dev_err(&pdev->dev, "can not get resource! \n");
+		return -EINVAL; /*lint !e429*/
+	}
+
+	spmi_controller->base = ioremap(iores->start, resource_size(iores));
+	if (!spmi_controller->base) {
+		dev_err(&pdev->dev, "can not remap base addr! \n");
+		return -EADDRNOTAVAIL; /*lint !e429*/
+	}
+	dev_dbg(&pdev->dev, "spmi_add_controller base addr=0x%lx!\n", (long unsigned int)spmi_controller->base);/*lint !e774*/
+
+	/* Get properties from the device tree */
+	ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel",
+			&spmi_controller->channel);/*lint !e838*/
+	if (ret) {
+		dev_err(&pdev->dev, "can not get chanel \n");
+		return -ENODEV; /*lint !e429*/
+	}
+
+	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_add_controller failed!\n");
+		goto err_add_controller;
+	}
+err_add_controller:
+	platform_set_drvdata(pdev, NULL);
+	return ret; /*lint !e429*/
+}
+
+static int spmi_del_controller(struct platform_device *pdev)
+{
+	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	spmi_controller_remove(ctrl);
+	return 0;
+}
+
+static struct of_device_id spmi_controller_match_table[] = {
+	{	.compatible = "hisilicon,spmi-controller",
+	},/*lint !e785*/
+	{}/*lint !e785*/
+};
+
+static struct platform_driver spmi_controller_driver = {
+	.probe		= spmi_controller_probe,
+	.remove		= spmi_del_controller,
+	.driver		= {
+		.name	= SPMI_CONTROLLER_NAME,
+		.owner	= THIS_MODULE,/*lint !e64*/
+		.of_match_table = spmi_controller_match_table,
+	},/*lint !e785*/
+};/*lint !e785*/
+/*lint -e528 -esym(528,*)*/
+static int __init spmi_controller_init(void)
+{
+	return platform_driver_register(&spmi_controller_driver);/*lint !e64*/
+}
+postcore_initcall(spmi_controller_init);
+
+static void __exit spmi_controller_exit(void)
+{
+	platform_driver_unregister(&spmi_controller_driver);
+}
+module_exit(spmi_controller_exit);
+/*lint -e753 -esym(753,*)*/
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");/*lint !e785 !e64 !e528*/
+MODULE_ALIAS("platform:spmi_controlller");
+/*lint -e753 +esym(753,*)*/
+/*lint -e528 +esym(528,*)*/
+
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 02/44] staging: spmi: hisi-spmi-controller: coding style fixup
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 01/44] staging: spmi: add Hikey 970 SPMI controller driver Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 03/44] staging: spmi: hisi-spmi-controller: fix it to probe successfully Mauro Carvalho Chehab
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

In order to prepare for upstream, fix most coding style issues.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hisi-spmi-controller.c   | 179 ++++++++----------
 1 file changed, 82 insertions(+), 97 deletions(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index 987526c8b49f..3af0bd1b379f 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -21,7 +22,7 @@
 #define SPMI_SLAVE_OFFSET						0x20
 
 #define SPMI_APB_SPMI_CMD_BASE_ADDR				0x0100
-/*lint -e750 -esym(750,*)*/
+
 #define SPMI_APB_SPMI_WDATA0_BASE_ADDR			0x0104
 #define SPMI_APB_SPMI_WDATA1_BASE_ADDR			0x0108
 #define SPMI_APB_SPMI_WDATA2_BASE_ADDR			0x010c
@@ -33,25 +34,25 @@
 #define SPMI_APB_SPMI_RDATA1_BASE_ADDR			0x0208
 #define SPMI_APB_SPMI_RDATA2_BASE_ADDR			0x020c
 #define SPMI_APB_SPMI_RDATA3_BASE_ADDR			0x0210
-/*lint +e750 -esym(750,*)*/
 
 #define SPMI_PER_DATAREG_BYTE					4
 /*
  * SPMI cmd register
  */
-#define SPMI_APB_SPMI_CMD_EN						(1 << 31)
+#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
 
-#define Tranverse32(X)                 ((((u32)(X) & 0xff000000) >> 24) | \
-							   (((u32)(X) & 0x00ff0000) >> 8) | \
-							   (((u32)(X) & 0x0000ff00) << 8) | \
-							   (((u32)(X) & 0x000000ff) << 24))
+#define bswap_32(X)   \
+    ((((u32)(X) & 0xff000000) >> 24) | \
+     (((u32)(X) & 0x00ff0000) >> 8) | \
+     (((u32)(X) & 0x0000ff00) << 8) | \
+     (((u32)(X) & 0x000000ff) << 24))
 
 /* Command Opcodes */
-/*lint -e749 -esym(749,*)*/
+
 enum spmi_controller_cmd_op_code {
 	SPMI_CMD_REG_ZERO_WRITE = 0,
 	SPMI_CMD_REG_WRITE = 1,
@@ -65,13 +66,12 @@ enum spmi_controller_cmd_op_code {
 	SPMI_CMD_REG_SHUTDOWN = 9,
 	SPMI_CMD_REG_WAKEUP = 10,
 };
-/*lint +e749 -esym(749,*)*/
 
 /*
  * SPMI status register
  */
-#define SPMI_APB_TRANS_DONE						(1 << 0)
-#define SPMI_APB_TRANS_FAIL						(1 << 2)
+#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
@@ -80,16 +80,6 @@ enum spmi_controller_cmd_op_code {
 #define SPMI_CONTROLLER_TIMEOUT_US		1000
 #define SPMI_CONTROLLER_MAX_TRANS_BYTES	(16)
 
-#define SPMI_WRITEL( dev, reg, addr )	\
-	do { \
-		writel( ( reg ), ( addr ) ); \
-	} while (0)
-
-#define  SPMI_READL( dev, reg, addr )	\
-	do { \
-		reg = readl( addr ); \
-	} while (0)
-
 /*
  * @base base address of the PMIC Arbiter core registers.
  * @rdbase, @wrbase base address of the PMIC Arbiter read core registers.
@@ -120,7 +110,7 @@ struct spmi_controller_dev {
 };
 
 static int spmi_controller_wait_for_done(struct spmi_controller_dev *ctrl_dev,
-				  void __iomem *base, u8 sid, u16 addr)
+					 void __iomem *base, u8 sid, u16 addr)
 {
 	u32 status = 0;
 	u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
@@ -128,7 +118,7 @@ static int spmi_controller_wait_for_done(struct spmi_controller_dev *ctrl_dev,
 		+ SPMI_SLAVE_OFFSET * sid;
 
 	while (timeout--) {
-		SPMI_READL(ctrl_dev->dev, status, base + offset);/*lint !e732 */
+		status = readl(base + offset);
 
 		if (status & SPMI_APB_TRANS_DONE) {
 			if (status & SPMI_APB_TRANS_FAIL) {
@@ -139,23 +129,23 @@ static int spmi_controller_wait_for_done(struct spmi_controller_dev *ctrl_dev,
 			}
 			return 0;
 		}
-		udelay(1);/*lint !e778 !e774 !e747*/
+		udelay(1);
 	}
 
 	dev_err(ctrl_dev->dev,
 		"%s: timeout, status 0x%x\n",
 		__func__, status);
-	return -ETIMEDOUT;/*lint !e438*/
-}/*lint !e715 !e529*/
+	return -ETIMEDOUT;
+}
 
 static int spmi_read_cmd(struct spmi_controller *ctrl,
-				u8 opc, u8 sid, u16 addr, u8 *buf, size_t bc)
+			 u8 opc, u8 sid, u16 addr, u8 *buf, size_t bc)
 {
 	struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
 	unsigned long flags;
 	u32 cmd, data;
 	int rc;
-	u32 chnl_ofst = SPMI_CHANNEL_OFFSET*spmi_controller->channel;
+	u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
 	u8 op_code, i;
 
 	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
@@ -166,27 +156,26 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 	}
 
 	/* Check the opcode */
-	if (SPMI_CMD_READ == opc)
+	if (opc == SPMI_CMD_READ) {
 		op_code = SPMI_CMD_REG_READ;
-	else if (SPMI_CMD_EXT_READ == opc)
+	} else if (opc == SPMI_CMD_EXT_READ) {
 		op_code = SPMI_CMD_EXT_REG_READ;
-	else if (SPMI_CMD_EXT_READL == opc)
+	} else if (opc == SPMI_CMD_EXT_READL) {
 		op_code = SPMI_CMD_EXT_REG_READ_L;
-	else {
+	} else {
 		dev_err(spmi_controller->dev, "invalid read cmd 0x%x", opc);
 		return -EINVAL;
 	}
 
-	cmd = SPMI_APB_SPMI_CMD_EN |/*lint !e648 !e701 */								/* cmd_en */
-		 (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |/*lint !e648 !e701 */			/* cmd_type */
-		 ((bc-1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |/*lint !e648 !e701 */		/* byte_cnt */
-		 ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |						/* slvid */
-		 ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET);					/* slave_addr */
+	cmd = SPMI_APB_SPMI_CMD_EN |
+	     (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
+	     ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
+	     ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |  /* slvid */
+	     ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
 
-	spin_lock_irqsave(&spmi_controller->lock, flags);/*lint !e550 */
-
-	SPMI_WRITEL(spmi_controller->dev, cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_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(spmi_controller, spmi_controller->base, sid, addr);
 	if (rc)
@@ -194,39 +183,37 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 
 	i = 0;
 	do {
-		SPMI_READL(spmi_controller->dev, data, spmi_controller->base + chnl_ofst + SPMI_SLAVE_OFFSET*sid + SPMI_APB_SPMI_RDATA0_BASE_ADDR + i*SPMI_PER_DATAREG_BYTE);/*lint !e732 */
-		data = Tranverse32(data);
-		if ((bc - i*SPMI_PER_DATAREG_BYTE ) >> 2) {/*lint !e702 */
+		data = readl(spmi_controller->base + chnl_ofst + SPMI_SLAVE_OFFSET * sid + SPMI_APB_SPMI_RDATA0_BASE_ADDR + i * SPMI_PER_DATAREG_BYTE);
+		data = bswap_32(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);/*lint !e747 */
-			buf += (bc%SPMI_PER_DATAREG_BYTE);
+			memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE);
+			buf += (bc % SPMI_PER_DATAREG_BYTE);
 		}
 		i++;
-	} while (bc > i*SPMI_PER_DATAREG_BYTE);
+	} while (bc > i * SPMI_PER_DATAREG_BYTE);
 
 done:
 	spin_unlock_irqrestore(&spmi_controller->lock, flags);
 	if (rc)
 		dev_err(spmi_controller->dev, "spmi read wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
-							opc, sid, addr, bc + 1);
+			opc, sid, addr, bc + 1);
 	return rc;
-}/*lint !e550 !e529*/
+}
 
-/*lint -e438 -esym(438,*)*/
 static int spmi_write_cmd(struct spmi_controller *ctrl,
-				u8 opc, u8 sid, u16 addr, const u8 *buf, size_t bc)
+			  u8 opc, u8 sid, u16 addr, const u8 *buf, size_t bc)
 {
 	struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
 	unsigned long flags;
 	u32 cmd;
 	u32 data = 0;
 	int rc;
-	u32 chnl_ofst = SPMI_CHANNEL_OFFSET*spmi_controller->channel;
+	u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
 	u8 op_code, i;
 
-
 	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
 		dev_err(spmi_controller->dev
 		, "spmi_controller supports 1..%d bytes per trans, but:%ld requested"
@@ -235,55 +222,55 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 	}
 
 	/* Check the opcode */
-	if (SPMI_CMD_WRITE == opc)
+	if (opc == SPMI_CMD_WRITE) {
 		op_code = SPMI_CMD_REG_WRITE;
-	else if (SPMI_CMD_EXT_WRITE == opc)
+	} else if (opc == SPMI_CMD_EXT_WRITE) {
 		op_code = SPMI_CMD_EXT_REG_WRITE;
-	else if (SPMI_CMD_EXT_WRITEL == opc)
+	} else if (opc == SPMI_CMD_EXT_WRITEL) {
 		op_code = SPMI_CMD_EXT_REG_WRITE_L;
-	else {
+	} else {
 		dev_err(spmi_controller->dev, "invalid write cmd 0x%x", opc);
 		return -EINVAL;
 	}
 
-	cmd = SPMI_APB_SPMI_CMD_EN |/*lint !e648 !e701 */								/* cmd_en */
-		 (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |/*lint !e648 !e701 */			/* cmd_type */
-		 ((bc-1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |/*lint !e648 !e701 */		/* byte_cnt */
-		 ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |						/* slvid */
-		 ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET);					/* slave_addr */
+	cmd = SPMI_APB_SPMI_CMD_EN |
+	      (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
+	      ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
+	      ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |  /* slvid */
+	      ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
 
 	/* Write data to FIFOs */
-	spin_lock_irqsave(&spmi_controller->lock, flags);/*lint !e550 */
+	spin_lock_irqsave(&spmi_controller->lock, flags);
 
 	i = 0;
 	do {
 		memset(&data, 0, sizeof(data));
-		if ((bc - i*SPMI_PER_DATAREG_BYTE ) >> 2) {/*lint !e702 */
+		if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
 			memcpy(&data, buf, sizeof(data));
-			buf +=sizeof(data);
+			buf += sizeof(data);
 		} else {
-			memcpy(&data, buf, bc%SPMI_PER_DATAREG_BYTE);/*lint !e747 */
-			buf +=(bc%SPMI_PER_DATAREG_BYTE);
+			memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE);
+			buf += (bc % SPMI_PER_DATAREG_BYTE);
 		}
 
-		data = Tranverse32(data);
-		SPMI_WRITEL(spmi_controller->dev, data, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_WDATA0_BASE_ADDR+SPMI_PER_DATAREG_BYTE*i);
+		data = bswap_32(data);
+		writel(data, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_WDATA0_BASE_ADDR + SPMI_PER_DATAREG_BYTE * i);
 		i++;
-	} while (bc > i*SPMI_PER_DATAREG_BYTE);
+	} while (bc > i * SPMI_PER_DATAREG_BYTE);
 
 	/* Start the transaction */
-	SPMI_WRITEL(spmi_controller->dev, cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
+	writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
 
 	rc = spmi_controller_wait_for_done(spmi_controller, spmi_controller->base, sid, addr);
 	spin_unlock_irqrestore(&spmi_controller->lock, flags);
 
 	if (rc)
 		dev_err(spmi_controller->dev, "spmi write wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
-							opc, sid, addr, bc);
+			opc, sid, addr, bc);
 
 	return rc;
-}/*lint !e438 !e550 !e529*/
-/*lint +e438 -esym(438,*)*/
+}
+
 static int spmi_controller_probe(struct platform_device *pdev)
 {
 	struct spmi_controller_dev *spmi_controller;
@@ -291,11 +278,11 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	struct resource *iores;
 	int ret = 0;
 
-	printk(KERN_INFO "HISI SPMI probe\n");
+	dev_info(&pdev->dev, "HISI SPMI probe\n");
 	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
 	if (!ctrl) {
 		dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
-		return -ENOMEM;  /*lint !e429*/
+		return -ENOMEM;
 	}
 	spmi_controller = spmi_controller_get_drvdata(ctrl);
 	spmi_controller->controller = ctrl;
@@ -303,23 +290,24 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	/* NOTE: driver uses the static register mapping */
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!iores) {
-		dev_err(&pdev->dev, "can not get resource! \n");
-		return -EINVAL; /*lint !e429*/
+		dev_err(&pdev->dev, "can not get resource!\n");
+		return -EINVAL;
 	}
 
 	spmi_controller->base = ioremap(iores->start, resource_size(iores));
 	if (!spmi_controller->base) {
-		dev_err(&pdev->dev, "can not remap base addr! \n");
-		return -EADDRNOTAVAIL; /*lint !e429*/
+		dev_err(&pdev->dev, "can not remap base addr!\n");
+		return -EADDRNOTAVAIL;
 	}
-	dev_dbg(&pdev->dev, "spmi_add_controller base addr=0x%lx!\n", (long unsigned int)spmi_controller->base);/*lint !e774*/
+	dev_dbg(&pdev->dev, "spmi_add_controller base addr=0x%lx!\n",
+		(unsigned long)spmi_controller->base);
 
 	/* Get properties from the device tree */
 	ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel",
-			&spmi_controller->channel);/*lint !e838*/
+				   &spmi_controller->channel);
 	if (ret) {
-		dev_err(&pdev->dev, "can not get chanel \n");
-		return -ENODEV; /*lint !e429*/
+		dev_err(&pdev->dev, "can not get chanel\n");
+		return -ENODEV;
 	}
 
 	platform_set_drvdata(pdev, spmi_controller);
@@ -342,7 +330,7 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	}
 err_add_controller:
 	platform_set_drvdata(pdev, NULL);
-	return ret; /*lint !e429*/
+	return ret;
 }
 
 static int spmi_del_controller(struct platform_device *pdev)
@@ -354,10 +342,10 @@ static int spmi_del_controller(struct platform_device *pdev)
 	return 0;
 }
 
-static struct of_device_id spmi_controller_match_table[] = {
+static const struct of_device_id spmi_controller_match_table[] = {
 	{	.compatible = "hisilicon,spmi-controller",
-	},/*lint !e785*/
-	{}/*lint !e785*/
+	},
+	{}
 };
 
 static struct platform_driver spmi_controller_driver = {
@@ -365,14 +353,14 @@ static struct platform_driver spmi_controller_driver = {
 	.remove		= spmi_del_controller,
 	.driver		= {
 		.name	= SPMI_CONTROLLER_NAME,
-		.owner	= THIS_MODULE,/*lint !e64*/
+		.owner	= THIS_MODULE,
 		.of_match_table = spmi_controller_match_table,
-	},/*lint !e785*/
-};/*lint !e785*/
-/*lint -e528 -esym(528,*)*/
+	},
+};
+
 static int __init spmi_controller_init(void)
 {
-	return platform_driver_register(&spmi_controller_driver);/*lint !e64*/
+	return platform_driver_register(&spmi_controller_driver);
 }
 postcore_initcall(spmi_controller_init);
 
@@ -381,10 +369,7 @@ static void __exit spmi_controller_exit(void)
 	platform_driver_unregister(&spmi_controller_driver);
 }
 module_exit(spmi_controller_exit);
-/*lint -e753 -esym(753,*)*/
+
 MODULE_LICENSE("GPL v2");
-MODULE_VERSION("1.0");/*lint !e785 !e64 !e528*/
+MODULE_VERSION("1.0");
 MODULE_ALIAS("platform:spmi_controlller");
-/*lint -e753 +esym(753,*)*/
-/*lint -e528 +esym(528,*)*/
-
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 03/44] staging: spmi: hisi-spmi-controller: fix it to probe successfully
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 01/44] staging: spmi: add Hikey 970 SPMI controller driver Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 02/44] staging: spmi: hisi-spmi-controller: coding style fixup Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 04/44] staging: spmi: hisi-spmi-controller: fix a typo Mauro Carvalho Chehab
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Add a MODULE_DEVICE_TABLE() to the driver.

Also, the current logic calls platform_set_drvdata(pdev, NULL)
if the driver succeeds loading.

While here, remove the .owner, as it is not needed upstream
anymore.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hisi-spmi-controller.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index 3af0bd1b379f..bc6847f9a5e7 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -324,11 +324,14 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	ctrl->write_cmd = spmi_write_cmd;
 
 	ret = spmi_controller_add(ctrl);
-	if (ret) {
-		dev_err(&pdev->dev, "spmi_add_controller failed!\n");
+	if (ret)
 		goto err_add_controller;
-	}
+
+	dev_info(&pdev->dev, "spmi_add_controller initialized\n");
+	return 0;
+
 err_add_controller:
+	dev_err(&pdev->dev, "spmi_add_controller failed!\n");
 	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
@@ -347,13 +350,13 @@ static const struct of_device_id spmi_controller_match_table[] = {
 	},
 	{}
 };
+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	= SPMI_CONTROLLER_NAME,
-		.owner	= THIS_MODULE,
 		.of_match_table = spmi_controller_match_table,
 	},
 };
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 04/44] staging: spmi: hisi-spmi-controller: fix a typo
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (2 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 03/44] staging: spmi: hisi-spmi-controller: fix it to probe successfully Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 05/44] staging: spmi: hisi-spmi-controller: adjust whitespaces at defines Mauro Carvalho Chehab
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

chanel -> channel

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hisi-spmi-controller.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index bc6847f9a5e7..99cf757d76fe 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -306,7 +306,7 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel",
 				   &spmi_controller->channel);
 	if (ret) {
-		dev_err(&pdev->dev, "can not get chanel\n");
+		dev_err(&pdev->dev, "can not get channel\n");
 		return -ENODEV;
 	}
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 05/44] staging: spmi: hisi-spmi-controller: adjust whitespaces at defines
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (3 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 04/44] staging: spmi: hisi-spmi-controller: fix a typo Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 06/44] staging: spmi: hisi-spmi-controller: use le32 macros where needed Mauro Carvalho Chehab
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Some defines are not aligned with tab=8, which is the
style defined on Linux. Adjust them.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hisi-spmi-controller.c   | 26 ++++++++++---------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index 99cf757d76fe..7fae267a6062 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -18,10 +18,10 @@
 /*
  * SPMI register addr
  */
-#define SPMI_CHANNEL_OFFSET					0x0300
-#define SPMI_SLAVE_OFFSET						0x20
+#define SPMI_CHANNEL_OFFSET				0x0300
+#define SPMI_SLAVE_OFFSET				0x20
 
-#define SPMI_APB_SPMI_CMD_BASE_ADDR				0x0100
+#define SPMI_APB_SPMI_CMD_BASE_ADDR			0x0100
 
 #define SPMI_APB_SPMI_WDATA0_BASE_ADDR			0x0104
 #define SPMI_APB_SPMI_WDATA1_BASE_ADDR			0x0108
@@ -35,21 +35,21 @@
 #define SPMI_APB_SPMI_RDATA2_BASE_ADDR			0x020c
 #define SPMI_APB_SPMI_RDATA3_BASE_ADDR			0x0210
 
-#define SPMI_PER_DATAREG_BYTE					4
+#define SPMI_PER_DATAREG_BYTE				4
 /*
  * SPMI cmd register
  */
-#define SPMI_APB_SPMI_CMD_EN						BIT(31)
+#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
 
 #define bswap_32(X)   \
     ((((u32)(X) & 0xff000000) >> 24) | \
      (((u32)(X) & 0x00ff0000) >> 8) | \
      (((u32)(X) & 0x0000ff00) << 8) | \
      (((u32)(X) & 0x000000ff) << 24))
+#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET		16
+#define SPMI_APB_SPMI_CMD_ADDR_OFFSET			0
 
 /* Command Opcodes */
 
@@ -70,15 +70,15 @@ enum spmi_controller_cmd_op_code {
 /*
  * SPMI status register
  */
-#define SPMI_APB_TRANS_DONE						BIT(0)
-#define SPMI_APB_TRANS_FAIL						BIT(2)
+#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)
+#define SPMI_CONTROLLER_MAX_TRANS_BYTES		16
 
 /*
  * @base base address of the PMIC Arbiter core registers.
@@ -114,8 +114,10 @@ static int spmi_controller_wait_for_done(struct spmi_controller_dev *ctrl_dev,
 {
 	u32 status = 0;
 	u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
-	u32 offset = SPMI_APB_SPMI_STATUS_BASE_ADDR + SPMI_CHANNEL_OFFSET * ctrl_dev->channel
-		+ SPMI_SLAVE_OFFSET * sid;
+	u32 offset;
+
+	offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
+	offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
 
 	while (timeout--) {
 		status = readl(base + offset);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 06/44] staging: spmi: hisi-spmi-controller: use le32 macros where needed
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (4 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 05/44] staging: spmi: hisi-spmi-controller: adjust whitespaces at defines Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 07/44] staging: spmi: hisi-spmi-controller: add debug when values are read/write Mauro Carvalho Chehab
                   ` (39 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Instead of manually using bswap_32(), just use the
le32 macros.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hisi-spmi-controller.c   | 20 +++++++------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index 7fae267a6062..cacd28150b49 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/spmi.h>
-#include <linux/spmi.h>
 
 #define SPMI_CONTROLLER_NAME		"spmi_controller"
 
@@ -43,11 +42,6 @@
 #define SPMI_APB_SPMI_CMD_TYPE_OFFSET			24
 #define SPMI_APB_SPMI_CMD_LENGTH_OFFSET			20
 
-#define bswap_32(X)   \
-    ((((u32)(X) & 0xff000000) >> 24) | \
-     (((u32)(X) & 0x00ff0000) >> 8) | \
-     (((u32)(X) & 0x0000ff00) << 8) | \
-     (((u32)(X) & 0x000000ff) << 24))
 #define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET		16
 #define SPMI_APB_SPMI_CMD_ADDR_OFFSET			0
 
@@ -179,14 +173,15 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 
 	writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
 
-	rc = spmi_controller_wait_for_done(spmi_controller, spmi_controller->base, sid, addr);
+	rc = spmi_controller_wait_for_done(spmi_controller,
+					   spmi_controller->base, sid, addr);
 	if (rc)
 		goto done;
 
 	i = 0;
 	do {
 		data = readl(spmi_controller->base + chnl_ofst + SPMI_SLAVE_OFFSET * sid + SPMI_APB_SPMI_RDATA0_BASE_ADDR + i * SPMI_PER_DATAREG_BYTE);
-		data = bswap_32(data);
+		data = be32_to_cpu((__be32)data);
 		if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
 			memcpy(buf, &data, sizeof(data));
 			buf += sizeof(data);
@@ -210,8 +205,7 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 {
 	struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
 	unsigned long flags;
-	u32 cmd;
-	u32 data = 0;
+	u32 cmd, data;
 	int rc;
 	u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
 	u8 op_code, i;
@@ -246,7 +240,7 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 
 	i = 0;
 	do {
-		memset(&data, 0, sizeof(data));
+		data = 0;
 		if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
 			memcpy(&data, buf, sizeof(data));
 			buf += sizeof(data);
@@ -255,8 +249,8 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 			buf += (bc % SPMI_PER_DATAREG_BYTE);
 		}
 
-		data = bswap_32(data);
-		writel(data, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_WDATA0_BASE_ADDR + SPMI_PER_DATAREG_BYTE * i);
+		writel((u32)cpu_to_be32(data),
+		       spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_WDATA0_BASE_ADDR + SPMI_PER_DATAREG_BYTE * i);
 		i++;
 	} while (bc > i * SPMI_PER_DATAREG_BYTE);
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 07/44] staging: spmi: hisi-spmi-controller: add debug when values are read/write
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (5 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 06/44] staging: spmi: hisi-spmi-controller: use le32 macros where needed Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 08/44] staging: spmi: hisi-spmi-controller: fix the dev_foo() logic Mauro Carvalho Chehab
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

It is interesting to be able to check if the driver is doing
the right thing. So, add some debug macros to allow checking it.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hisi-spmi-controller.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index cacd28150b49..e996114bc717 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -41,7 +41,6 @@
 #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
 
@@ -135,10 +134,11 @@ static int spmi_controller_wait_for_done(struct spmi_controller_dev *ctrl_dev,
 }
 
 static int spmi_read_cmd(struct spmi_controller *ctrl,
-			 u8 opc, u8 sid, u16 addr, u8 *buf, size_t bc)
+			 u8 opc, u8 sid, u16 addr, u8 *__buf, size_t bc)
 {
 	struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
 	unsigned long flags;
+	u8 *buf = __buf;
 	u32 cmd, data;
 	int rc;
 	u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
@@ -197,13 +197,18 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 	if (rc)
 		dev_err(spmi_controller->dev, "spmi read wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
 			opc, sid, addr, bc + 1);
+	else
+		dev_dbg(spmi_controller->dev, "%s: id:%d addr:0x%x, read value: %*ph\n",
+			__func__, sid, addr, (int)bc, __buf);
+
 	return rc;
 }
 
 static int spmi_write_cmd(struct spmi_controller *ctrl,
-			  u8 opc, u8 sid, u16 addr, const u8 *buf, size_t bc)
+			  u8 opc, u8 sid, u16 addr, const u8 *__buf, size_t bc)
 {
 	struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
+	const u8 *buf = __buf;
 	unsigned long flags;
 	u32 cmd, data;
 	int rc;
@@ -263,6 +268,9 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 	if (rc)
 		dev_err(spmi_controller->dev, "spmi write wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
 			opc, sid, addr, bc);
+	else
+		dev_dbg(spmi_controller->dev, "%s: id:%d addr:0x%x, wrote value: %*ph\n",
+			__func__, sid, addr, (int)bc, __buf);
 
 	return rc;
 }
@@ -275,6 +283,7 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	int ret = 0;
 
 	dev_info(&pdev->dev, "HISI SPMI probe\n");
+
 	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
 	if (!ctrl) {
 		dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 08/44] staging: spmi: hisi-spmi-controller: fix the dev_foo() logic
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (6 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 07/44] staging: spmi: hisi-spmi-controller: add debug when values are read/write Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 09/44] staging: spmi: hisi-spmi-controller: add it to the building system Mauro Carvalho Chehab
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Right now, driver is printing some messages as:

	[   33.833026] (NULL device *): spmi_read_cmd: id:0 addr:0x17, read value: 00

This is because dev_foo() are not using a device with a name
set. Change the logic for it to print it right.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hisi-spmi-controller.c   | 41 ++++++++++---------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index e996114bc717..153bcdb0cde4 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -102,7 +102,8 @@ struct spmi_controller_dev {
 	u32			channel;
 };
 
-static int spmi_controller_wait_for_done(struct spmi_controller_dev *ctrl_dev,
+static int spmi_controller_wait_for_done(struct device *dev,
+					 struct spmi_controller_dev *ctrl_dev,
 					 void __iomem *base, u8 sid, u16 addr)
 {
 	u32 status = 0;
@@ -117,19 +118,17 @@ static int spmi_controller_wait_for_done(struct spmi_controller_dev *ctrl_dev,
 
 		if (status & SPMI_APB_TRANS_DONE) {
 			if (status & SPMI_APB_TRANS_FAIL) {
-				dev_err(ctrl_dev->dev,
-					"%s: transaction failed (0x%x)\n",
+				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);
 	}
 
-	dev_err(ctrl_dev->dev,
-		"%s: timeout, status 0x%x\n",
-		__func__, status);
+	dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status);
 	return -ETIMEDOUT;
 }
 
@@ -145,9 +144,9 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 	u8 op_code, i;
 
 	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
-		dev_err(spmi_controller->dev
-		, "spmi_controller supports 1..%d bytes per trans, but:%ld requested"
-					, SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
+		dev_err(&ctrl->dev,
+			"spmi_controller supports 1..%d bytes per trans, but:%ld requested",
+			SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
 		return  -EINVAL;
 	}
 
@@ -159,7 +158,7 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 	} else if (opc == SPMI_CMD_EXT_READL) {
 		op_code = SPMI_CMD_EXT_REG_READ_L;
 	} else {
-		dev_err(spmi_controller->dev, "invalid read cmd 0x%x", opc);
+		dev_err(&ctrl->dev, "invalid read cmd 0x%x", opc);
 		return -EINVAL;
 	}
 
@@ -173,7 +172,7 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 
 	writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
 
-	rc = spmi_controller_wait_for_done(spmi_controller,
+	rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
 					   spmi_controller->base, sid, addr);
 	if (rc)
 		goto done;
@@ -195,10 +194,11 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 done:
 	spin_unlock_irqrestore(&spmi_controller->lock, flags);
 	if (rc)
-		dev_err(spmi_controller->dev, "spmi read wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
+		dev_err(&ctrl->dev,
+			"spmi read wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
 			opc, sid, addr, bc + 1);
 	else
-		dev_dbg(spmi_controller->dev, "%s: id:%d addr:0x%x, read value: %*ph\n",
+		dev_dbg(&ctrl->dev, "%s: id:%d addr:0x%x, read value: %*ph\n",
 			__func__, sid, addr, (int)bc, __buf);
 
 	return rc;
@@ -216,9 +216,9 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 	u8 op_code, i;
 
 	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
-		dev_err(spmi_controller->dev
-		, "spmi_controller supports 1..%d bytes per trans, but:%ld requested"
-					, SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
+		dev_err(&ctrl->dev,
+			"spmi_controller supports 1..%d bytes per trans, but:%ld requested",
+			SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
 		return  -EINVAL;
 	}
 
@@ -230,7 +230,7 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 	} else if (opc == SPMI_CMD_EXT_WRITEL) {
 		op_code = SPMI_CMD_EXT_REG_WRITE_L;
 	} else {
-		dev_err(spmi_controller->dev, "invalid write cmd 0x%x", opc);
+		dev_err(&ctrl->dev, "invalid write cmd 0x%x", opc);
 		return -EINVAL;
 	}
 
@@ -262,14 +262,15 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 	/* Start the transaction */
 	writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
 
-	rc = spmi_controller_wait_for_done(spmi_controller, spmi_controller->base, sid, addr);
+	rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
+					   spmi_controller->base, sid, addr);
 	spin_unlock_irqrestore(&spmi_controller->lock, flags);
 
 	if (rc)
-		dev_err(spmi_controller->dev, "spmi write wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
+		dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x sid:%d addr:0x%x bc:%ld\n",
 			opc, sid, addr, bc);
 	else
-		dev_dbg(spmi_controller->dev, "%s: id:%d addr:0x%x, wrote value: %*ph\n",
+		dev_dbg(&ctrl->dev, "%s: id:%d addr:0x%x, wrote value: %*ph\n",
 			__func__, sid, addr, (int)bc, __buf);
 
 	return rc;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 09/44] staging: spmi: hisi-spmi-controller: add it to the building system
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (7 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 08/44] staging: spmi: hisi-spmi-controller: fix the dev_foo() logic Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 10/44] staging: spmi: hisi-spmi-controller: do some code cleanups Mauro Carvalho Chehab
                   ` (36 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Now that the driver was ported to upstream, add it as a
SPMI controller.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/Kconfig           |  2 ++
 drivers/staging/Makefile          |  1 +
 drivers/staging/hikey9xx/Kconfig  | 10 ++++++++++
 drivers/staging/hikey9xx/Makefile |  3 +++
 4 files changed, 16 insertions(+)
 create mode 100644 drivers/staging/hikey9xx/Kconfig
 create mode 100644 drivers/staging/hikey9xx/Makefile

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 4ec5528f89fa..dfce8e39dbc3 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -120,4 +120,6 @@ 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 4d34198151b3..e369a4f5e14a 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -50,3 +50,4 @@ 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
new file mode 100644
index 000000000000..31eb01b5ef2b
--- /dev/null
+++ b/drivers/staging/hikey9xx/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+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.
diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile
new file mode 100644
index 000000000000..e8085abce444
--- /dev/null
+++ b/drivers/staging/hikey9xx/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 10/44] staging: spmi: hisi-spmi-controller: do some code cleanups
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (8 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 09/44] staging: spmi: hisi-spmi-controller: add it to the building system Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 11/44] staging: mfd: add a PMIC driver for HiSilicon 6421 SPMI version Mauro Carvalho Chehab
                   ` (35 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel,
	devel, Jonathan Cameron

There are several minor things that can be cleanup in
order to make this driver more prepared for leaving staging.

Suggested-by: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hisi-spmi-controller.c   | 150 +++++++-----------
 1 file changed, 61 insertions(+), 89 deletions(-)

diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
index 153bcdb0cde4..513d962b8bce 100644
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ b/drivers/staging/hikey9xx/hisi-spmi-controller.c
@@ -2,18 +2,16 @@
 
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/interrupt.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>
 
-#define SPMI_CONTROLLER_NAME		"spmi_controller"
-
 /*
  * SPMI register addr
  */
@@ -73,27 +71,6 @@ enum spmi_controller_cmd_op_code {
 #define SPMI_CONTROLLER_TIMEOUT_US		1000
 #define SPMI_CONTROLLER_MAX_TRANS_BYTES		16
 
-/*
- * @base base address of the PMIC Arbiter core registers.
- * @rdbase, @wrbase base address of the PMIC Arbiter read core registers.
- *     For HW-v1 these are equal to base.
- *     For HW-v2, the value is the same in eeraly probing, in order to read
- *     PMIC_ARB_CORE registers, then chnls, and obsrvr are set to
- *     PMIC_ARB_CORE_REGISTERS and PMIC_ARB_CORE_REGISTERS_OBS respectivly.
- * @intr base address of the SPMI interrupt control registers
- * @ppid_2_chnl_tbl lookup table f(SID, Periph-ID) -> channel num
- *      entry is only valid if corresponding bit is set in valid_ppid_bitmap.
- * @valid_ppid_bitmap bit is set only for valid ppids.
- * @fmt_cmd formats a command to be set into PMIC_ARBq_CHNLn_CMD
- * @chnl_ofst calculates offset of the base of a channel reg space
- * @ee execution environment id
- * @irq_acc0_init_val initial value of the interrupt accumulator at probe time.
- *      Use for an HW workaround. On handling interrupts, the first accumulator
- *      register will be compared against this value, and bits which are set at
- *      boot will be ignored.
- * @reserved_chnl entry of ppid_2_chnl_tbl that this driver should never touch.
- *      value is positive channel number or negative to mark it unused.
- */
 struct spmi_controller_dev {
 	struct spmi_controller	*controller;
 	struct device		*dev;
@@ -106,14 +83,13 @@ static int spmi_controller_wait_for_done(struct device *dev,
 					 struct spmi_controller_dev *ctrl_dev,
 					 void __iomem *base, u8 sid, u16 addr)
 {
-	u32 status = 0;
 	u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
-	u32 offset;
+	u32 status, offset;
 
 	offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
 	offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
 
-	while (timeout--) {
+	do {
 		status = readl(base + offset);
 
 		if (status & SPMI_APB_TRANS_DONE) {
@@ -126,60 +102,65 @@ static int spmi_controller_wait_for_done(struct device *dev,
 			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 sid, u16 addr, u8 *__buf, size_t bc)
+			 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;
-	u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
 	u8 op_code, i;
 
 	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
 		dev_err(&ctrl->dev,
-			"spmi_controller supports 1..%d bytes per trans, but:%ld requested",
+			"spmi_controller supports 1..%d bytes per trans, but:%ld requested\n",
 			SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
 		return  -EINVAL;
 	}
 
-	/* Check the opcode */
-	if (opc == SPMI_CMD_READ) {
+	switch (opc) {
+	case SPMI_CMD_READ:
 		op_code = SPMI_CMD_REG_READ;
-	} else if (opc == SPMI_CMD_EXT_READ) {
+		break;
+	case SPMI_CMD_EXT_READ:
 		op_code = SPMI_CMD_EXT_REG_READ;
-	} else if (opc == SPMI_CMD_EXT_READL) {
+		break;
+	case SPMI_CMD_EXT_READL:
 		op_code = SPMI_CMD_EXT_REG_READ_L;
-	} else {
-		dev_err(&ctrl->dev, "invalid read cmd 0x%x", opc);
+		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) |
-	     ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |  /* slvid */
-	     ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
+	     ((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, sid, addr);
+					   spmi_controller->base, slave_id, slave_addr);
 	if (rc)
 		goto done;
 
-	i = 0;
-	do {
-		data = readl(spmi_controller->base + chnl_ofst + SPMI_SLAVE_OFFSET * sid + SPMI_APB_SPMI_RDATA0_BASE_ADDR + i * SPMI_PER_DATAREG_BYTE);
+	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)data);
 		if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
 			memcpy(buf, &data, sizeof(data));
@@ -188,63 +169,64 @@ static int spmi_read_cmd(struct spmi_controller *ctrl,
 			memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE);
 			buf += (bc % SPMI_PER_DATAREG_BYTE);
 		}
-		i++;
-	} while (bc > i * 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 sid:%d addr:0x%x bc:%ld\n",
-			opc, sid, addr, bc + 1);
+			"spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%ld\n",
+			opc, slave_id, slave_addr, bc + 1);
 	else
-		dev_dbg(&ctrl->dev, "%s: id:%d addr:0x%x, read value: %*ph\n",
-			__func__, sid, addr, (int)bc, __buf);
+		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 sid, u16 addr, const u8 *__buf, size_t bc)
+			  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;
-	u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
 	u8 op_code, i;
 
 	if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
 		dev_err(&ctrl->dev,
-			"spmi_controller supports 1..%d bytes per trans, but:%ld requested",
+			"spmi_controller supports 1..%d bytes per trans, but:%ld requested\n",
 			SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
 		return  -EINVAL;
 	}
 
-	/* Check the opcode */
-	if (opc == SPMI_CMD_WRITE) {
+	switch (opc) {
+	case SPMI_CMD_WRITE:
 		op_code = SPMI_CMD_REG_WRITE;
-	} else if (opc == SPMI_CMD_EXT_WRITE) {
+		break;
+	case SPMI_CMD_EXT_WRITE:
 		op_code = SPMI_CMD_EXT_REG_WRITE;
-	} else if (opc == SPMI_CMD_EXT_WRITEL) {
+		break;
+	case SPMI_CMD_EXT_WRITEL:
 		op_code = SPMI_CMD_EXT_REG_WRITE_L;
-	} else {
-		dev_err(&ctrl->dev, "invalid write cmd 0x%x", opc);
+		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) |
-	      ((sid & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |  /* slvid */
-	      ((addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
+	      ((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);
 
-	i = 0;
-	do {
+	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));
@@ -255,23 +237,25 @@ static int spmi_write_cmd(struct spmi_controller *ctrl,
 		}
 
 		writel((u32)cpu_to_be32(data),
-		       spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_WDATA0_BASE_ADDR + SPMI_PER_DATAREG_BYTE * i);
-		i++;
-	} while (bc > i * SPMI_PER_DATAREG_BYTE);
+		       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, sid, addr);
+					   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 sid:%d addr:0x%x bc:%ld\n",
-			opc, sid, addr, bc);
+		dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%ld\n",
+			opc, slave_id, slave_addr, bc);
 	else
-		dev_dbg(&ctrl->dev, "%s: id:%d addr:0x%x, wrote value: %*ph\n",
-			__func__, sid, addr, (int)bc, __buf);
+		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;
 }
@@ -281,9 +265,7 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	struct spmi_controller_dev *spmi_controller;
 	struct spmi_controller *ctrl;
 	struct resource *iores;
-	int ret = 0;
-
-	dev_info(&pdev->dev, "HISI SPMI probe\n");
+	int ret;
 
 	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
 	if (!ctrl) {
@@ -293,7 +275,6 @@ static int spmi_controller_probe(struct platform_device *pdev)
 	spmi_controller = spmi_controller_get_drvdata(ctrl);
 	spmi_controller->controller = ctrl;
 
-	/* NOTE: driver uses the static register mapping */
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!iores) {
 		dev_err(&pdev->dev, "can not get resource!\n");
@@ -305,10 +286,7 @@ static int spmi_controller_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "can not remap base addr!\n");
 		return -EADDRNOTAVAIL;
 	}
-	dev_dbg(&pdev->dev, "spmi_add_controller base addr=0x%lx!\n",
-		(unsigned long)spmi_controller->base);
 
-	/* Get properties from the device tree */
 	ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel",
 				   &spmi_controller->channel);
 	if (ret) {
@@ -331,14 +309,8 @@ static int spmi_controller_probe(struct platform_device *pdev)
 
 	ret = spmi_controller_add(ctrl);
 	if (ret)
-		goto err_add_controller;
+		dev_err(&pdev->dev, "spmi_add_controller failed with error %d!\n", ret);
 
-	dev_info(&pdev->dev, "spmi_add_controller initialized\n");
-	return 0;
-
-err_add_controller:
-	dev_err(&pdev->dev, "spmi_add_controller failed!\n");
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
@@ -346,8 +318,8 @@ static int spmi_del_controller(struct platform_device *pdev)
 {
 	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	spmi_controller_remove(ctrl);
+	kfree(ctrl);
 	return 0;
 }
 
@@ -362,7 +334,7 @@ static struct platform_driver spmi_controller_driver = {
 	.probe		= spmi_controller_probe,
 	.remove		= spmi_del_controller,
 	.driver		= {
-		.name	= SPMI_CONTROLLER_NAME,
+		.name	= "hisi_spmi_controller",
 		.of_match_table = spmi_controller_match_table,
 	},
 };
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 11/44] staging: mfd: add a PMIC driver for HiSilicon 6421 SPMI version
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (9 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 10/44] staging: spmi: hisi-spmi-controller: do some code cleanups Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 12/44] staging: mfd: hi6421-spmi-pmic: get rid of unused code Mauro Carvalho Chehab
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mayulong, Mauro Carvalho Chehab,
	Lee Jones, linux-kernel, devel

From: Mayulong <mayulong1@huawei.com>

Add the PMIC SPMI driver for the HiSilicon 6421v600.

[mchehab+huawei@kernel.org: keep just the MFD driver on this patch,
 and renamed filenames to better match other upstream drivers]

 The compete patch is at:
	https://github.com/96boards-hikey/linux/commit/08464419fba2

Signed-off-by: Mayulong <mayulong1@huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 759 ++++++++++++++++++++
 include/linux/mfd/hi6421-spmi-pmic.h        | 165 +++++
 2 files changed, 924 insertions(+)
 create mode 100644 drivers/staging/hikey9xx/hi6421-spmi-pmic.c
 create mode 100644 include/linux/mfd/hi6421-spmi-pmic.h

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
new file mode 100644
index 000000000000..6bb0bc4b203b
--- /dev/null
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -0,0 +1,759 @@
+/*
+ * Device driver for regulators in HISI PMIC IC
+ *
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2011 Hisilicon.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/mfd/hisi_pmic.h>
+#include <linux/irq.h>
+#include <linux/spmi.h>
+#ifndef NO_IRQ
+#define NO_IRQ       0
+#endif
+
+/* 8-bit register offset in PMIC */
+#define HISI_MASK_STATE			0xff
+
+#define HISI_IRQ_KEY_NUM		0
+#define HISI_IRQ_KEY_VALUE		0xc0
+#define HISI_IRQ_KEY_DOWN		7
+#define HISI_IRQ_KEY_UP			6
+
+/*#define HISI_NR_IRQ			25*/
+#define HISI_MASK_FIELD		0xFF
+#define HISI_BITS			8
+#define PMIC_FPGA_FLAG          1
+
+/*define the first group interrupt register number*/
+#define HISI_PMIC_FIRST_GROUP_INT_NUM        2
+
+static struct bit_info g_pmic_vbus = {0};
+#ifndef BIT
+#define BIT(x)		(0x1U << (x))
+#endif
+
+static struct hisi_pmic *g_pmic;
+static unsigned int g_extinterrupt_flag  = 0;
+static struct of_device_id of_hisi_pmic_match_tbl[] = {
+	{
+		.compatible = "hisilicon-hisi-pmic-spmi",
+	},
+	{ /* end */ }
+};
+
+/*
+ * The PMIC register is only 8-bit.
+ * Hisilicon SoC use hardware to map PMIC register into SoC mapping.
+ * At here, we are accessing SoC register with 32-bit.
+ */
+u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg)
+{
+	u32 ret;
+	u8 read_value = 0;
+	struct spmi_device *pdev;
+
+	if (NULL == g_pmic) {
+		pr_err(" g_pmic  is NULL\n");
+		return 0;
+	}
+
+	pdev = to_spmi_device(g_pmic->dev);
+	if (NULL == pdev) {
+		pr_err("%s:pdev get failed!\n", __func__);
+		return 0;
+	}
+
+	ret = spmi_ext_register_readl(pdev, reg, (unsigned char*)&read_value, 1);/*lint !e734 !e732 */
+	if (ret) {
+		pr_err("%s:spmi_ext_register_readl failed!\n", __func__);
+		return ret;
+	}
+	return (u32)read_value;
+}
+EXPORT_SYMBOL(hisi_pmic_read);
+
+void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val)
+{
+	u32 ret;
+	struct spmi_device *pdev;
+
+	if (NULL == g_pmic) {
+		pr_err(" g_pmic  is NULL\n");
+		return;
+	}
+
+	pdev = to_spmi_device(g_pmic->dev);
+	if (NULL == pdev) {
+		pr_err("%s:pdev get failed!\n", __func__);
+		return;
+	}
+
+	ret = spmi_ext_register_writel(pdev, reg, (unsigned char*)&val, 1);/*lint !e734 !e732 */
+	if (ret) {
+		pr_err("%s:spmi_ext_register_writel failed!\n", __func__);
+		return ;
+	}
+}
+EXPORT_SYMBOL(hisi_pmic_write);
+
+#ifdef CONFIG_HISI_DIEID
+u32 hisi_pmic_read_sub_pmu(u8 sid, int reg)
+{
+	u32 ret;
+	u8 read_value = 0;
+	struct spmi_device *pdev;
+
+	if(strstr(saved_command_line, "androidboot.swtype=factory"))
+	{
+		if (NULL == g_pmic) {
+			pr_err(" g_pmic  is NULL\n");
+			return -1;/*lint !e570 */
+		}
+
+		pdev = to_spmi_device(g_pmic->dev);
+		if (NULL == pdev) {
+			pr_err("%s:pdev get failed!\n", __func__);
+			return -1;/*lint !e570 */
+		}
+
+		ret = spmi_ext_register_readl(pdev->ctrl, sid, reg, (unsigned char*)&read_value, 1);/*lint !e734 !e732 */
+		if (ret) {
+			pr_err("%s:spmi_ext_register_readl failed!\n", __func__);
+			return ret;
+		}
+		return (u32)read_value;
+	}
+	return  0;
+}
+EXPORT_SYMBOL(hisi_pmic_read_sub_pmu);
+
+void hisi_pmic_write_sub_pmu(u8 sid, int reg, u32 val)
+{
+	u32 ret;
+	struct spmi_device *pdev;
+	if(strstr(saved_command_line, "androidboot.swtype=factory"))
+	{
+		if (NULL == g_pmic) {
+			pr_err(" g_pmic  is NULL\n");
+			return;
+		}
+
+		pdev = to_spmi_device(g_pmic->dev);
+		if (NULL == pdev) {
+			pr_err("%s:pdev get failed!\n", __func__);
+			return;
+		}
+
+		ret = spmi_ext_register_writel(pdev->ctrl, sid, reg, (unsigned char*)&val, 1);/*lint !e734 !e732 */
+		if (ret) {
+			pr_err("%s:spmi_ext_register_writel failed!\n", __func__);
+			return ;
+		}
+	}
+
+	return ;
+}
+EXPORT_SYMBOL(hisi_pmic_write_sub_pmu);
+#endif
+
+void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg,
+		     u32 mask, u32 bits)
+{
+	u32 data;
+	unsigned long flags;
+
+	if (NULL == g_pmic) {
+		pr_err(" g_pmic  is NULL\n");
+		return;
+	}
+
+	spin_lock_irqsave(&g_pmic->lock, flags);
+	data = hisi_pmic_read(pmic, reg) & ~mask;
+	data |= mask & bits;
+	hisi_pmic_write(pmic, reg, data);
+	spin_unlock_irqrestore(&g_pmic->lock, flags);
+}
+EXPORT_SYMBOL(hisi_pmic_rmw);
+
+unsigned int hisi_pmic_reg_read(int addr)
+{
+	return (unsigned int)hisi_pmic_read(g_pmic, addr);
+}
+EXPORT_SYMBOL(hisi_pmic_reg_read);
+
+void hisi_pmic_reg_write(int addr, int val)
+{
+	hisi_pmic_write(g_pmic, addr, val);
+}
+EXPORT_SYMBOL(hisi_pmic_reg_write);
+
+void hisi_pmic_reg_write_lock(int addr, int val)
+{
+	unsigned long flags;
+
+	if (NULL == g_pmic) {
+		pr_err(" g_pmic  is NULL\n");
+		return;
+	}
+
+	spin_lock_irqsave(&g_pmic->lock, flags);
+	hisi_pmic_write(g_pmic, g_pmic->normal_lock.addr, g_pmic->normal_lock.val);
+	hisi_pmic_write(g_pmic, g_pmic->debug_lock.addr, g_pmic->debug_lock.val);
+	hisi_pmic_write(g_pmic, addr, val);
+	hisi_pmic_write(g_pmic, g_pmic->normal_lock.addr, 0);
+	hisi_pmic_write(g_pmic, g_pmic->debug_lock.addr, 0);
+	spin_unlock_irqrestore(&g_pmic->lock, flags);
+}
+
+int hisi_pmic_array_read(int addr, char *buff, unsigned int len)
+{
+	unsigned int i;
+
+	if ((len > 32) || (NULL == buff)) {
+		return -EINVAL;
+	}
+
+	/*
+	 * Here is a bug in the pmu die.
+	 * the coul driver will read 4 bytes,
+	 * but the ssi bus only read 1 byte, and the pmu die
+	 * will make sampling 1/10669us about vol cur,so the driver
+	 * read the data is not the same sampling
+	 */
+	for (i = 0; i < len; i++)
+	{
+		*(buff + i) = hisi_pmic_reg_read(addr+i);
+	}
+
+	return 0;
+}
+
+int hisi_pmic_array_write(int addr, char *buff, unsigned int len)
+{
+    unsigned int i;
+
+	if ((len > 32) || (NULL == buff)) {
+		return -EINVAL;
+	}
+
+	for (i = 0; i < len; i++)
+	{
+		hisi_pmic_reg_write(addr+i, *(buff + i));
+	}
+
+	return 0;
+}
+
+static irqreturn_t hisi_irq_handler(int irq, void *data)
+{
+	struct hisi_pmic *pmic = (struct hisi_pmic *)data;
+	unsigned long pending;
+	int i, offset;
+
+	for (i = 0; i < pmic->irqarray; i++) {
+		pending = hisi_pmic_reg_read((i + pmic->irq_addr.start_addr));
+		pending &= HISI_MASK_FIELD;
+		if (pending != 0) {
+			pr_info("pending[%d]=0x%lx\n\r", i, pending);
+		}
+
+		hisi_pmic_reg_write((i + pmic->irq_addr.start_addr), pending);
+
+		/*solve powerkey order*/
+		if ((HISI_IRQ_KEY_NUM == i) && ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
+			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]);
+			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]);
+			pending &= (~HISI_IRQ_KEY_VALUE);
+		}
+
+		if (pending) {
+			for_each_set_bit(offset, &pending, HISI_BITS)
+				generic_handle_irq(pmic->irqs[offset + i * HISI_BITS]);/*lint !e679 */
+		}
+	}
+
+	/*Handle the second group irq if analysis the second group irq from dtsi*/
+	if (1 == g_extinterrupt_flag){
+		for (i = 0; i < pmic->irqarray1; i++) {
+			pending = hisi_pmic_reg_read((i + pmic->irq_addr1.start_addr));
+			pending &= HISI_MASK_FIELD;
+			if (pending != 0) {
+				pr_info("pending[%d]=0x%lx\n\r", i, pending);
+			}
+
+			hisi_pmic_reg_write((i + pmic->irq_addr1.start_addr), pending);
+
+			if (pending) {
+				for_each_set_bit(offset, &pending, HISI_BITS)
+					generic_handle_irq(pmic->irqs[offset + (i+HISI_PMIC_FIRST_GROUP_INT_NUM) * HISI_BITS]);/*lint !e679 */
+			}
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void hisi_irq_mask(struct irq_data *d)
+{
+	struct hisi_pmic *pmic = irq_data_get_irq_chip_data(d);
+	u32 data, offset;
+	unsigned long flags;
+
+	if (NULL == g_pmic) {
+		pr_err(" g_pmic  is NULL\n");
+		return;
+	}
+
+	offset = (irqd_to_hwirq(d) >> 3);
+	if (1==g_extinterrupt_flag){
+		if ( offset < HISI_PMIC_FIRST_GROUP_INT_NUM)
+			offset += pmic->irq_mask_addr.start_addr;
+		else/*Change addr when irq num larger than 16 because interrupt addr is nonsequence*/
+			offset = offset+(pmic->irq_mask_addr1.start_addr)-HISI_PMIC_FIRST_GROUP_INT_NUM;
+	}else{
+		offset += pmic->irq_mask_addr.start_addr;
+	}
+	spin_lock_irqsave(&g_pmic->lock, flags);
+	data = hisi_pmic_reg_read(offset);
+	data |= (1 << (irqd_to_hwirq(d) & 0x07));
+	hisi_pmic_reg_write(offset, data);
+	spin_unlock_irqrestore(&g_pmic->lock, flags);
+}
+
+static void hisi_irq_unmask(struct irq_data *d)
+{
+	struct hisi_pmic *pmic = irq_data_get_irq_chip_data(d);
+	u32 data, offset;
+	unsigned long flags;
+
+	if (NULL == g_pmic) {
+		pr_err(" g_pmic  is NULL\n");
+		return;
+	}
+
+	offset = (irqd_to_hwirq(d) >> 3);
+	if (1==g_extinterrupt_flag){
+		if ( offset < HISI_PMIC_FIRST_GROUP_INT_NUM)
+			offset += pmic->irq_mask_addr.start_addr;
+		else
+			offset = offset+(pmic->irq_mask_addr1.start_addr)-HISI_PMIC_FIRST_GROUP_INT_NUM;
+	}else{
+		offset += pmic->irq_mask_addr.start_addr;
+	}
+	spin_lock_irqsave(&g_pmic->lock, flags);
+	data = hisi_pmic_reg_read(offset);
+	data &= ~(1 << (irqd_to_hwirq(d) & 0x07)); /*lint !e502 */
+	hisi_pmic_reg_write(offset, data);
+	spin_unlock_irqrestore(&g_pmic->lock, flags);
+}
+
+static struct irq_chip hisi_pmu_irqchip = {
+	.name		= "hisi-irq",
+	.irq_mask	= hisi_irq_mask,
+	.irq_unmask	= hisi_irq_unmask,
+	.irq_disable	= hisi_irq_mask,
+	.irq_enable	= hisi_irq_unmask,
+};
+
+static int hisi_irq_map(struct irq_domain *d, unsigned int virq,
+			  irq_hw_number_t hw)
+{
+	struct hisi_pmic *pmic = d->host_data;
+
+	irq_set_chip_and_handler_name(virq, &hisi_pmu_irqchip,
+				      handle_simple_irq, "hisi");
+	irq_set_chip_data(virq, pmic);
+	irq_set_irq_type(virq, IRQ_TYPE_NONE);
+
+	return 0;
+}
+
+static struct irq_domain_ops hisi_domain_ops = {
+	.map	= hisi_irq_map,
+	.xlate	= irq_domain_xlate_twocell,
+};
+
+/*lint -e570 -e64*/
+static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *pmic)
+{
+	int ret = 0;
+
+	/*get pmic irq num*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-num",
+						&(pmic->irqnum), 1);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-num property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	/*get pmic irq array number*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-array",
+						&(pmic->irqarray), 1);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-array property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	/*SOC_PMIC_IRQ_MASK_0_ADDR*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-mask-addr",
+						(int *)&pmic->irq_mask_addr, 2);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-mask-addr property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	/*SOC_PMIC_IRQ0_ADDR*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-addr",
+						(int *)&pmic->irq_addr, 2);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-addr property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-vbus",
+						(u32 *)&g_pmic_vbus, 2);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-vbus property\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	/*pmic lock*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-lock",
+						(int *)&pmic->normal_lock, 2);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-lock property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	/*pmic debug lock*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-debug-lock",
+						(int *)&pmic->debug_lock, 2);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-debug-lock property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	return ret;
+}/*lint -restore*/
+
+
+/*lint -e570 -e64*/
+static int get_pmic_device_tree_data1(struct device_node *np, struct hisi_pmic *pmic)
+{
+	int ret = 0;
+
+	/*get pmic irq num*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-num1",
+						&(pmic->irqnum1), 1);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-num1 property set\n");
+		ret = -ENODEV;
+		pmic->irqnum1 = 0;
+		return ret;
+	}
+
+	/*get pmic irq array number*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-array1",
+						&(pmic->irqarray1), 1);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-array1 property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	/*SOC_PMIC_IRQ_MASK_0_ADDR*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-mask-addr1",
+						(int *)&pmic->irq_mask_addr1, 2);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-mask-addr1 property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	/*SOC_PMIC_IRQ0_ADDR*/
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-addr1",
+						(int *)&pmic->irq_addr1, 2);
+	if (ret) {
+		pr_err("no hisilicon,hisi-pmic-irq-addr1 property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+
+	g_extinterrupt_flag = 1;
+	return ret;
+}/*lint -restore*/
+
+int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list)
+{
+	if ( NULL == g_pmic ) {
+		pr_err("[%s]g_pmic is NULL\n", __func__);
+		return -1;
+	}
+
+	if (pmic_irq_list > (unsigned int)g_pmic->irqnum) {
+		pr_err("[%s]input pmic irq number is error.\n", __func__);
+		return -1;
+	}
+	pr_info("%s:g_pmic->irqs[%d]=%d\n", __func__, pmic_irq_list, g_pmic->irqs[pmic_irq_list]);
+	return (int)g_pmic->irqs[pmic_irq_list];
+}
+EXPORT_SYMBOL(hisi_get_pmic_irq_byname);
+
+int hisi_pmic_get_vbus_status(void)
+{
+	if (0 == g_pmic_vbus.addr)
+		return -1;
+
+	if (hisi_pmic_reg_read(g_pmic_vbus.addr) & BIT(g_pmic_vbus.bit))
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(hisi_pmic_get_vbus_status);
+
+static void hisi_pmic_irq_prc(struct hisi_pmic *pmic)
+{
+	int i;
+	for (i = 0 ; i < pmic->irq_mask_addr.array; i++) {
+		hisi_pmic_write(pmic, pmic->irq_mask_addr.start_addr + i, HISI_MASK_STATE);
+	}
+
+	for (i = 0 ; i < pmic->irq_addr.array; i++) {
+		unsigned int pending = hisi_pmic_read(pmic, pmic->irq_addr.start_addr + i);
+		pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n", pmic->irq_addr.start_addr + i, pending);
+		hisi_pmic_write(pmic, pmic->irq_addr.start_addr + i, HISI_MASK_STATE);
+	}
+
+}
+
+static void hisi_pmic_irq1_prc(struct hisi_pmic *pmic)
+{
+	int i;
+	if(1 == g_extinterrupt_flag){
+		for (i = 0 ; i < pmic->irq_mask_addr1.array; i++) {
+			hisi_pmic_write(pmic, pmic->irq_mask_addr1.start_addr + i, HISI_MASK_STATE);
+		}
+
+		for (i = 0 ; i < pmic->irq_addr1.array; i++) {
+			unsigned int pending1 = hisi_pmic_read(pmic, pmic->irq_addr1.start_addr + i);
+			pr_debug("PMU IRQ address1 value:irq[0x%x] = 0x%x\n", pmic->irq_addr1.start_addr + i, pending1);
+			hisi_pmic_write(pmic, pmic->irq_addr1.start_addr + i, HISI_MASK_STATE);
+		}
+	}
+}
+
+static int hisi_pmic_probe(struct spmi_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct hisi_pmic *pmic = NULL;
+	enum of_gpio_flags flags;
+	int ret = 0;
+	int i;
+	unsigned int fpga_flag = 0;
+	unsigned int virq;
+
+	pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
+	if (!pmic) {
+		dev_err(dev, "cannot allocate hisi_pmic device info\n");
+		return -ENOMEM;
+	}
+
+	/*TODO: get pmic dts info*/
+	ret = get_pmic_device_tree_data(np, pmic);
+	if (ret) {
+		dev_err(&pdev->dev, "Error reading hisi pmic dts \n");
+		return ret;
+	}
+
+	/*get pmic dts the second group irq*/
+	ret = get_pmic_device_tree_data1(np, pmic);
+	if (ret) {
+		dev_err(&pdev->dev, "the platform don't support ext-interrupt.\n");
+	}
+
+	/* TODO: get and enable clk request */
+	spin_lock_init(&pmic->lock);
+
+	pmic->dev = dev;
+	g_pmic = pmic;
+	ret = of_property_read_u32_array(np, "hisilicon,pmic_fpga_flag", &fpga_flag, 1);
+	if (ret) {
+		pr_err("no hisilicon,pmic_fpga_flag property set\n");
+	}
+	if (PMIC_FPGA_FLAG == fpga_flag) {
+		goto after_irq_register;
+	}
+
+	pmic->gpio = of_get_gpio_flags(np, 0, &flags);
+	if (pmic->gpio < 0)
+		return pmic->gpio;
+
+	if (!gpio_is_valid(pmic->gpio))
+		return -EINVAL;
+
+	ret = gpio_request_one(pmic->gpio, GPIOF_IN, "pmic");
+	if (ret < 0) {
+		dev_err(dev, "failed to request gpio%d\n", pmic->gpio);
+		return ret;
+	}
+
+	pmic->irq = gpio_to_irq(pmic->gpio);
+
+	/* mask && clear IRQ status */
+	hisi_pmic_irq_prc(pmic);
+	/*clear && mask the new adding irq*/
+	hisi_pmic_irq1_prc(pmic);
+
+	pmic->irqnum += pmic->irqnum1;
+
+	pmic->irqs = (unsigned int *)devm_kmalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
+	if (!pmic->irqs) {
+		pr_err("%s:Failed to alloc memory for pmic irq number!\n", __func__);
+		goto irq_malloc;
+	}
+	memset(pmic->irqs, 0, pmic->irqnum);
+
+	pmic->domain = irq_domain_add_simple(np, pmic->irqnum, 0,
+					     &hisi_domain_ops, pmic);
+	if (!pmic->domain) {
+		dev_err(dev, "failed irq domain add simple!\n");
+		ret = -ENODEV;
+		goto irq_domain;
+	}
+
+	for (i = 0; i < pmic->irqnum; i++) {
+		virq = irq_create_mapping(pmic->domain, i);
+		if (virq == NO_IRQ) {
+			pr_debug("Failed mapping hwirq\n");
+			ret = -ENOSPC;
+			goto irq_create_mapping;
+		}
+		pmic->irqs[i] = virq;
+		pr_info("[%s]. pmic->irqs[%d] = %d\n", __func__, i, pmic->irqs[i]);
+	}
+
+	ret = request_threaded_irq(pmic->irq, hisi_irq_handler, NULL,
+				IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
+				   "pmic", pmic);
+	if (ret < 0) {
+		dev_err(dev, "could not claim pmic %d\n", ret);
+		ret = -ENODEV;
+		goto request_theaded_irq;
+	}
+
+after_irq_register:
+	return 0;
+
+
+request_theaded_irq:
+irq_create_mapping:
+irq_domain:
+irq_malloc:
+	gpio_free(pmic->gpio);
+	g_pmic = NULL;
+	return ret;
+}
+
+static void hisi_pmic_remove(struct spmi_device *pdev)
+{
+
+	struct hisi_pmic *pmic = dev_get_drvdata(&pdev->dev);
+
+	free_irq(pmic->irq, pmic);
+	gpio_free(pmic->gpio);
+	devm_kfree(&pdev->dev, pmic);
+
+}
+static int hisi_pmic_suspend(struct device *dev, pm_message_t state)
+{
+	struct hisi_pmic *pmic = dev_get_drvdata(dev);
+
+	if (NULL == pmic) {
+		pr_err("%s:pmic is NULL\n", __func__);
+		return -ENOMEM;
+	}
+
+	pr_info("%s:+\n", __func__);
+	pr_info("%s:-\n", __func__);
+
+	return 0;
+}/*lint !e715 */
+
+static int hisi_pmic_resume(struct device *dev)
+{
+	struct hisi_pmic *pmic = dev_get_drvdata(dev);
+
+	if (NULL == pmic) {
+		pr_err("%s:pmic is NULL\n", __func__);
+		return -ENOMEM;
+	}
+
+	pr_info("%s:+\n", __func__);
+	pr_info("%s:-\n", __func__);
+
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(spmi, pmic_spmi_id);
+static struct spmi_driver hisi_pmic_driver = {
+	.driver = {
+		.name	= "hisi_pmic",
+		.owner  = THIS_MODULE,
+		.of_match_table = of_hisi_pmic_match_tbl,
+		.suspend = hisi_pmic_suspend,
+		.resume = hisi_pmic_resume,
+	},
+	.probe	= hisi_pmic_probe,
+	.remove	= hisi_pmic_remove,
+};
+
+static int __init hisi_pmic_init(void)
+{
+	return spmi_driver_register(&hisi_pmic_driver);
+}
+
+static void __exit hisi_pmic_exit(void)
+{
+	spmi_driver_unregister(&hisi_pmic_driver);
+}
+
+
+subsys_initcall_sync(hisi_pmic_init);
+module_exit(hisi_pmic_exit);
+
+MODULE_DESCRIPTION("PMIC driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
new file mode 100644
index 000000000000..939b36f617c1
--- /dev/null
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -0,0 +1,165 @@
+/*
+ * Header file for device driver Hi6421 PMIC
+ *
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (C) 2011 Hisilicon.
+ *
+ * Guodong Xu <guodong.xu@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef	__HISI_PMIC_H
+#define	__HISI_PMIC_H
+
+#include <linux/irqdomain.h>
+
+#define HISI_REGS_ENA_PROTECT_TIME	(0) 	/* in microseconds */
+#define HISI_ECO_MODE_ENABLE		(1)
+#define HISI_ECO_MODE_DISABLE		(0)
+
+typedef int (*pmic_ocp_callback)(char *);
+extern int hisi_pmic_special_ocp_register(char *power_name, pmic_ocp_callback handler);
+
+struct irq_mask_info {
+	int start_addr;
+	int array;
+};
+
+struct irq_info {
+	int start_addr;
+	int array;
+};
+
+struct bit_info {
+	int addr;
+	int bit;
+};
+
+struct write_lock {
+	int addr;
+	int val;
+};
+
+struct hisi_pmic {
+	struct resource		*res;
+	struct device		*dev;
+	void __iomem		*regs;
+	spinlock_t		lock;
+	struct irq_domain	*domain;
+	int			irq;
+	int			gpio;
+	unsigned int	*irqs;
+	int			irqnum;
+	int			irqarray;
+	struct irq_mask_info irq_mask_addr;
+	struct irq_info irq_addr;
+	int			irqnum1;
+	int			irqarray1;
+	struct irq_mask_info irq_mask_addr1;
+	struct irq_info irq_addr1;
+	struct write_lock normal_lock;
+	struct write_lock debug_lock;
+};
+
+/* 0:disable; 1:enable */
+unsigned int get_uv_mntn_status(void);
+void clear_uv_mntn_resered_reg_bit(void);
+void set_uv_mntn_resered_reg_bit(void);
+
+#if defined(CONFIG_HISI_PMIC) || defined(CONFIG_HISI_PMIC_PMU_SPMI)
+/* Register Access Helpers */
+u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg);
+void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val);
+void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits);
+unsigned int hisi_pmic_reg_read(int addr);
+void hisi_pmic_reg_write(int addr, int val);
+void hisi_pmic_reg_write_lock(int addr, int val);
+int hisi_pmic_array_read(int addr, char *buff, unsigned int len);
+int hisi_pmic_array_write(int addr, char *buff, unsigned int len);
+extern int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list);
+extern int hisi_pmic_get_vbus_status(void);
+#if defined(CONFIG_HISI_DIEID)
+u32 hisi_pmic_read_sub_pmu(u8 sid ,int reg);
+void hisi_pmic_write_sub_pmu(u8 sid ,int reg, u32 val);
+#endif
+#else
+static inline u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg) { return 0; }
+static inline void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val) {}
+static inline void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits) {}
+static inline unsigned int hisi_pmic_reg_read(int addr) { return 0; }
+static inline void hisi_pmic_reg_write(int addr, int val) {}
+static inline void hisi_pmic_reg_write_lock(int addr, int val) {}
+static inline int hisi_pmic_array_read(int addr, char *buff, unsigned int len) { return 0; }
+static inline int hisi_pmic_array_write(int addr, char *buff, unsigned int len) { return 0; }
+static inline int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list) { return -1; }
+static inline int hisi_pmic_get_vbus_status(void) { return 1; }
+static inline u32 hisi_pmic_read_sub_pmu(u8 sid ,int reg) { return 0; }
+static inline void hisi_pmic_write_sub_pmu(u8 sid ,int reg, u32 val) {}
+#endif
+
+#ifdef CONFIG_HISI_HI6421V500_PMU
+enum pmic_irq_list {
+	POR_D45MR = 0,
+	VBUS_CONNECT,
+	VBUS_DISCONNECT,
+	ALARMON_R,
+	HOLD_6S,
+	HOLD_1S,
+	POWERKEY_UP,
+	POWERKEY_DOWN,
+	OCP_SCP_R,
+	COUL_R,
+	VSYS_OV,
+	VSYS_UV,
+	VSYS_PWROFF_ABS,
+	VSYS_PWROFF_DEB,
+	THSD_OTMP140,
+	THSD_OTMP125,
+	HRESETN,
+	SIM0_HPD_R = 24,
+	SIM0_HPD_F,
+	SIM0_HPD_H,
+	SIM0_HPD_L,
+	SIM1_HPD_R,
+	SIM1_HPD_F,
+	SIM1_HPD_H,
+	SIM1_HPD_L,
+	PMIC_IRQ_LIST_MAX,
+};
+#else
+enum 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,
+};
+#endif
+
+#ifdef CONFIG_HISI_SR_DEBUG
+extern void get_ip_regulator_state(void);
+#endif
+#endif		/* __HISI_PMIC_H */
+
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 12/44] staging: mfd: hi6421-spmi-pmic: get rid of unused code
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (10 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 11/44] staging: mfd: add a PMIC driver for HiSilicon 6421 SPMI version Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 13/44] staging: mfd: hi6421-spmi-pmic: deal with non-static functions Mauro Carvalho Chehab
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
	linux-kernel, devel

There are some checks there which could make sense for
downstream builds, but doesn't make much sense for
upstream ones. They came from the official Hikey970 tree
from Linaro, but even there, the commented-out code is not
set via other Kconfig vars.

So, let's just get rid of that. If needed later, this
patch can be (partially?) reversed.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 63 ---------------------
 include/linux/mfd/hi6421-spmi-pmic.h        | 42 --------------
 2 files changed, 105 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index 6bb0bc4b203b..809381eb6043 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -53,10 +53,6 @@
 #define HISI_PMIC_FIRST_GROUP_INT_NUM        2
 
 static struct bit_info g_pmic_vbus = {0};
-#ifndef BIT
-#define BIT(x)		(0x1U << (x))
-#endif
-
 static struct hisi_pmic *g_pmic;
 static unsigned int g_extinterrupt_flag  = 0;
 static struct of_device_id of_hisi_pmic_match_tbl[] = {
@@ -121,65 +117,6 @@ void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val)
 }
 EXPORT_SYMBOL(hisi_pmic_write);
 
-#ifdef CONFIG_HISI_DIEID
-u32 hisi_pmic_read_sub_pmu(u8 sid, int reg)
-{
-	u32 ret;
-	u8 read_value = 0;
-	struct spmi_device *pdev;
-
-	if(strstr(saved_command_line, "androidboot.swtype=factory"))
-	{
-		if (NULL == g_pmic) {
-			pr_err(" g_pmic  is NULL\n");
-			return -1;/*lint !e570 */
-		}
-
-		pdev = to_spmi_device(g_pmic->dev);
-		if (NULL == pdev) {
-			pr_err("%s:pdev get failed!\n", __func__);
-			return -1;/*lint !e570 */
-		}
-
-		ret = spmi_ext_register_readl(pdev->ctrl, sid, reg, (unsigned char*)&read_value, 1);/*lint !e734 !e732 */
-		if (ret) {
-			pr_err("%s:spmi_ext_register_readl failed!\n", __func__);
-			return ret;
-		}
-		return (u32)read_value;
-	}
-	return  0;
-}
-EXPORT_SYMBOL(hisi_pmic_read_sub_pmu);
-
-void hisi_pmic_write_sub_pmu(u8 sid, int reg, u32 val)
-{
-	u32 ret;
-	struct spmi_device *pdev;
-	if(strstr(saved_command_line, "androidboot.swtype=factory"))
-	{
-		if (NULL == g_pmic) {
-			pr_err(" g_pmic  is NULL\n");
-			return;
-		}
-
-		pdev = to_spmi_device(g_pmic->dev);
-		if (NULL == pdev) {
-			pr_err("%s:pdev get failed!\n", __func__);
-			return;
-		}
-
-		ret = spmi_ext_register_writel(pdev->ctrl, sid, reg, (unsigned char*)&val, 1);/*lint !e734 !e732 */
-		if (ret) {
-			pr_err("%s:spmi_ext_register_writel failed!\n", __func__);
-			return ;
-		}
-	}
-
-	return ;
-}
-EXPORT_SYMBOL(hisi_pmic_write_sub_pmu);
-#endif
 
 void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg,
 		     u32 mask, u32 bits)
diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
index 939b36f617c1..5be9b4d3f207 100644
--- a/include/linux/mfd/hi6421-spmi-pmic.h
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -78,7 +78,6 @@ unsigned int get_uv_mntn_status(void);
 void clear_uv_mntn_resered_reg_bit(void);
 void set_uv_mntn_resered_reg_bit(void);
 
-#if defined(CONFIG_HISI_PMIC) || defined(CONFIG_HISI_PMIC_PMU_SPMI)
 /* Register Access Helpers */
 u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg);
 void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val);
@@ -90,11 +89,6 @@ int hisi_pmic_array_read(int addr, char *buff, unsigned int len);
 int hisi_pmic_array_write(int addr, char *buff, unsigned int len);
 extern int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list);
 extern int hisi_pmic_get_vbus_status(void);
-#if defined(CONFIG_HISI_DIEID)
-u32 hisi_pmic_read_sub_pmu(u8 sid ,int reg);
-void hisi_pmic_write_sub_pmu(u8 sid ,int reg, u32 val);
-#endif
-#else
 static inline u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg) { return 0; }
 static inline void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val) {}
 static inline void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits) {}
@@ -107,38 +101,7 @@ static inline int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list) { return
 static inline int hisi_pmic_get_vbus_status(void) { return 1; }
 static inline u32 hisi_pmic_read_sub_pmu(u8 sid ,int reg) { return 0; }
 static inline void hisi_pmic_write_sub_pmu(u8 sid ,int reg, u32 val) {}
-#endif
 
-#ifdef CONFIG_HISI_HI6421V500_PMU
-enum pmic_irq_list {
-	POR_D45MR = 0,
-	VBUS_CONNECT,
-	VBUS_DISCONNECT,
-	ALARMON_R,
-	HOLD_6S,
-	HOLD_1S,
-	POWERKEY_UP,
-	POWERKEY_DOWN,
-	OCP_SCP_R,
-	COUL_R,
-	VSYS_OV,
-	VSYS_UV,
-	VSYS_PWROFF_ABS,
-	VSYS_PWROFF_DEB,
-	THSD_OTMP140,
-	THSD_OTMP125,
-	HRESETN,
-	SIM0_HPD_R = 24,
-	SIM0_HPD_F,
-	SIM0_HPD_H,
-	SIM0_HPD_L,
-	SIM1_HPD_R,
-	SIM1_HPD_F,
-	SIM1_HPD_H,
-	SIM1_HPD_L,
-	PMIC_IRQ_LIST_MAX,
-};
-#else
 enum pmic_irq_list {
 	OTMP = 0,
 	VBUS_CONNECT,
@@ -156,10 +119,5 @@ enum pmic_irq_list {
 	SIM1_HPD_F,
 	PMIC_IRQ_LIST_MAX,
 };
-#endif
-
-#ifdef CONFIG_HISI_SR_DEBUG
-extern void get_ip_regulator_state(void);
-#endif
 #endif		/* __HISI_PMIC_H */
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 13/44] staging: mfd: hi6421-spmi-pmic: deal with non-static functions
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (11 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 12/44] staging: mfd: hi6421-spmi-pmic: get rid of unused code Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 14/44] staging: mfd: hi6421-spmi-pmic: get rid of the static vars Mauro Carvalho Chehab
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Several functions aren't used outside the mfd driver. So,
either remove or make them static.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 147 ++++----------------
 1 file changed, 24 insertions(+), 123 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index 809381eb6043..8b87d48b88b5 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -73,21 +73,21 @@ u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg)
 	u8 read_value = 0;
 	struct spmi_device *pdev;
 
-	if (NULL == g_pmic) {
-		pr_err(" g_pmic  is NULL\n");
+	if (!g_pmic) {
+		pr_err("%s: g_pmic is NULL\n", __func__);
 		return 0;
 	}
 
 	pdev = to_spmi_device(g_pmic->dev);
-	if (NULL == pdev) {
-		pr_err("%s:pdev get failed!\n", __func__);
+	if (!pdev) {
+		pr_err("%s: pdev get failed!\n", __func__);
 		return 0;
 	}
 
 	ret = spmi_ext_register_readl(pdev, reg, (unsigned char*)&read_value, 1);/*lint !e734 !e732 */
 	if (ret) {
-		pr_err("%s:spmi_ext_register_readl failed!\n", __func__);
-		return ret;
+		pr_err("%s: spmi_ext_register_readl failed!\n", __func__);
+		return 0;
 	}
 	return (u32)read_value;
 }
@@ -98,34 +98,32 @@ void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val)
 	u32 ret;
 	struct spmi_device *pdev;
 
-	if (NULL == g_pmic) {
-		pr_err(" g_pmic  is NULL\n");
+	if (!g_pmic) {
+		pr_err("%s: g_pmic is NULL\n", __func__);
 		return;
 	}
 
 	pdev = to_spmi_device(g_pmic->dev);
-	if (NULL == pdev) {
-		pr_err("%s:pdev get failed!\n", __func__);
+	if (!pdev) {
+		pr_err("%s: pdev get failed!\n", __func__);
 		return;
 	}
 
 	ret = spmi_ext_register_writel(pdev, reg, (unsigned char*)&val, 1);/*lint !e734 !e732 */
 	if (ret) {
-		pr_err("%s:spmi_ext_register_writel failed!\n", __func__);
-		return ;
+		pr_err("%s: spmi_ext_register_writel failed!\n", __func__);
+		return;
 	}
 }
 EXPORT_SYMBOL(hisi_pmic_write);
 
-
-void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg,
-		     u32 mask, u32 bits)
+void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits)
 {
 	u32 data;
 	unsigned long flags;
 
-	if (NULL == g_pmic) {
-		pr_err(" g_pmic  is NULL\n");
+	if (!g_pmic) {
+		pr_err("%s: g_pmic is NULL\n", __func__);
 		return;
 	}
 
@@ -137,75 +135,6 @@ void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg,
 }
 EXPORT_SYMBOL(hisi_pmic_rmw);
 
-unsigned int hisi_pmic_reg_read(int addr)
-{
-	return (unsigned int)hisi_pmic_read(g_pmic, addr);
-}
-EXPORT_SYMBOL(hisi_pmic_reg_read);
-
-void hisi_pmic_reg_write(int addr, int val)
-{
-	hisi_pmic_write(g_pmic, addr, val);
-}
-EXPORT_SYMBOL(hisi_pmic_reg_write);
-
-void hisi_pmic_reg_write_lock(int addr, int val)
-{
-	unsigned long flags;
-
-	if (NULL == g_pmic) {
-		pr_err(" g_pmic  is NULL\n");
-		return;
-	}
-
-	spin_lock_irqsave(&g_pmic->lock, flags);
-	hisi_pmic_write(g_pmic, g_pmic->normal_lock.addr, g_pmic->normal_lock.val);
-	hisi_pmic_write(g_pmic, g_pmic->debug_lock.addr, g_pmic->debug_lock.val);
-	hisi_pmic_write(g_pmic, addr, val);
-	hisi_pmic_write(g_pmic, g_pmic->normal_lock.addr, 0);
-	hisi_pmic_write(g_pmic, g_pmic->debug_lock.addr, 0);
-	spin_unlock_irqrestore(&g_pmic->lock, flags);
-}
-
-int hisi_pmic_array_read(int addr, char *buff, unsigned int len)
-{
-	unsigned int i;
-
-	if ((len > 32) || (NULL == buff)) {
-		return -EINVAL;
-	}
-
-	/*
-	 * Here is a bug in the pmu die.
-	 * the coul driver will read 4 bytes,
-	 * but the ssi bus only read 1 byte, and the pmu die
-	 * will make sampling 1/10669us about vol cur,so the driver
-	 * read the data is not the same sampling
-	 */
-	for (i = 0; i < len; i++)
-	{
-		*(buff + i) = hisi_pmic_reg_read(addr+i);
-	}
-
-	return 0;
-}
-
-int hisi_pmic_array_write(int addr, char *buff, unsigned int len)
-{
-    unsigned int i;
-
-	if ((len > 32) || (NULL == buff)) {
-		return -EINVAL;
-	}
-
-	for (i = 0; i < len; i++)
-	{
-		hisi_pmic_reg_write(addr+i, *(buff + i));
-	}
-
-	return 0;
-}
-
 static irqreturn_t hisi_irq_handler(int irq, void *data)
 {
 	struct hisi_pmic *pmic = (struct hisi_pmic *)data;
@@ -213,13 +142,13 @@ static irqreturn_t hisi_irq_handler(int irq, void *data)
 	int i, offset;
 
 	for (i = 0; i < pmic->irqarray; i++) {
-		pending = hisi_pmic_reg_read((i + pmic->irq_addr.start_addr));
+		pending = hisi_pmic_read(g_pmic, (i + pmic->irq_addr.start_addr));
 		pending &= HISI_MASK_FIELD;
 		if (pending != 0) {
 			pr_info("pending[%d]=0x%lx\n\r", i, pending);
 		}
 
-		hisi_pmic_reg_write((i + pmic->irq_addr.start_addr), pending);
+		hisi_pmic_write(g_pmic, (i + pmic->irq_addr.start_addr), pending);
 
 		/*solve powerkey order*/
 		if ((HISI_IRQ_KEY_NUM == i) && ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
@@ -237,13 +166,13 @@ static irqreturn_t hisi_irq_handler(int irq, void *data)
 	/*Handle the second group irq if analysis the second group irq from dtsi*/
 	if (1 == g_extinterrupt_flag){
 		for (i = 0; i < pmic->irqarray1; i++) {
-			pending = hisi_pmic_reg_read((i + pmic->irq_addr1.start_addr));
+			pending = hisi_pmic_read(g_pmic, (i + pmic->irq_addr1.start_addr));
 			pending &= HISI_MASK_FIELD;
 			if (pending != 0) {
 				pr_info("pending[%d]=0x%lx\n\r", i, pending);
 			}
 
-			hisi_pmic_reg_write((i + pmic->irq_addr1.start_addr), pending);
+			hisi_pmic_write(g_pmic, (i + pmic->irq_addr1.start_addr), pending);
 
 			if (pending) {
 				for_each_set_bit(offset, &pending, HISI_BITS)
@@ -276,9 +205,9 @@ static void hisi_irq_mask(struct irq_data *d)
 		offset += pmic->irq_mask_addr.start_addr;
 	}
 	spin_lock_irqsave(&g_pmic->lock, flags);
-	data = hisi_pmic_reg_read(offset);
+	data = hisi_pmic_read(g_pmic, offset);
 	data |= (1 << (irqd_to_hwirq(d) & 0x07));
-	hisi_pmic_reg_write(offset, data);
+	hisi_pmic_write(g_pmic, offset, data);
 	spin_unlock_irqrestore(&g_pmic->lock, flags);
 }
 
@@ -303,9 +232,9 @@ static void hisi_irq_unmask(struct irq_data *d)
 		offset += pmic->irq_mask_addr.start_addr;
 	}
 	spin_lock_irqsave(&g_pmic->lock, flags);
-	data = hisi_pmic_reg_read(offset);
-	data &= ~(1 << (irqd_to_hwirq(d) & 0x07)); /*lint !e502 */
-	hisi_pmic_reg_write(offset, data);
+	data = hisi_pmic_read(g_pmic, offset);
+	data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
+	hisi_pmic_write(g_pmic, offset, data);
 	spin_unlock_irqrestore(&g_pmic->lock, flags);
 }
 
@@ -452,34 +381,6 @@ static int get_pmic_device_tree_data1(struct device_node *np, struct hisi_pmic *
 	return ret;
 }/*lint -restore*/
 
-int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list)
-{
-	if ( NULL == g_pmic ) {
-		pr_err("[%s]g_pmic is NULL\n", __func__);
-		return -1;
-	}
-
-	if (pmic_irq_list > (unsigned int)g_pmic->irqnum) {
-		pr_err("[%s]input pmic irq number is error.\n", __func__);
-		return -1;
-	}
-	pr_info("%s:g_pmic->irqs[%d]=%d\n", __func__, pmic_irq_list, g_pmic->irqs[pmic_irq_list]);
-	return (int)g_pmic->irqs[pmic_irq_list];
-}
-EXPORT_SYMBOL(hisi_get_pmic_irq_byname);
-
-int hisi_pmic_get_vbus_status(void)
-{
-	if (0 == g_pmic_vbus.addr)
-		return -1;
-
-	if (hisi_pmic_reg_read(g_pmic_vbus.addr) & BIT(g_pmic_vbus.bit))
-		return 1;
-
-	return 0;
-}
-EXPORT_SYMBOL(hisi_pmic_get_vbus_status);
-
 static void hisi_pmic_irq_prc(struct hisi_pmic *pmic)
 {
 	int i;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 14/44] staging: mfd: hi6421-spmi-pmic: get rid of the static vars
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (12 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 13/44] staging: mfd: hi6421-spmi-pmic: deal with non-static functions Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 15/44] staging: mfd: hi6421-spmi-pmic: cleanup hi6421-spmi-pmic.h header Mauro Carvalho Chehab
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
	linux-kernel, devel

There are several static vars inside this driver.

Get rid of them.

While here, add a SPDX header file.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 224 ++++++++------------
 include/linux/mfd/hi6421-spmi-pmic.h        |  20 +-
 2 files changed, 97 insertions(+), 147 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index 8b87d48b88b5..be42fed16bd2 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device driver for regulators in HISI PMIC IC
  *
@@ -52,10 +53,7 @@
 /*define the first group interrupt register number*/
 #define HISI_PMIC_FIRST_GROUP_INT_NUM        2
 
-static struct bit_info g_pmic_vbus = {0};
-static struct hisi_pmic *g_pmic;
-static unsigned int g_extinterrupt_flag  = 0;
-static struct of_device_id of_hisi_pmic_match_tbl[] = {
+static const struct of_device_id of_hisi_pmic_match_tbl[] = {
 	{
 		.compatible = "hisilicon-hisi-pmic-spmi",
 	},
@@ -73,18 +71,14 @@ u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg)
 	u8 read_value = 0;
 	struct spmi_device *pdev;
 
-	if (!g_pmic) {
-		pr_err("%s: g_pmic is NULL\n", __func__);
-		return 0;
-	}
-
-	pdev = to_spmi_device(g_pmic->dev);
+	pdev = to_spmi_device(pmic->dev);
 	if (!pdev) {
 		pr_err("%s: pdev get failed!\n", __func__);
 		return 0;
 	}
 
-	ret = spmi_ext_register_readl(pdev, reg, (unsigned char*)&read_value, 1);/*lint !e734 !e732 */
+	ret = spmi_ext_register_readl(pdev, reg,
+				      (unsigned char *)&read_value, 1);
 	if (ret) {
 		pr_err("%s: spmi_ext_register_readl failed!\n", __func__);
 		return 0;
@@ -98,18 +92,13 @@ void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val)
 	u32 ret;
 	struct spmi_device *pdev;
 
-	if (!g_pmic) {
-		pr_err("%s: g_pmic is NULL\n", __func__);
-		return;
-	}
-
-	pdev = to_spmi_device(g_pmic->dev);
+	pdev = to_spmi_device(pmic->dev);
 	if (!pdev) {
 		pr_err("%s: pdev get failed!\n", __func__);
 		return;
 	}
 
-	ret = spmi_ext_register_writel(pdev, reg, (unsigned char*)&val, 1);/*lint !e734 !e732 */
+	ret = spmi_ext_register_writel(pdev, reg, (unsigned char *)&val, 1);
 	if (ret) {
 		pr_err("%s: spmi_ext_register_writel failed!\n", __func__);
 		return;
@@ -122,16 +111,11 @@ void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits)
 	u32 data;
 	unsigned long flags;
 
-	if (!g_pmic) {
-		pr_err("%s: g_pmic is NULL\n", __func__);
-		return;
-	}
-
-	spin_lock_irqsave(&g_pmic->lock, flags);
+	spin_lock_irqsave(&pmic->lock, flags);
 	data = hisi_pmic_read(pmic, reg) & ~mask;
 	data |= mask & bits;
 	hisi_pmic_write(pmic, reg, data);
-	spin_unlock_irqrestore(&g_pmic->lock, flags);
+	spin_unlock_irqrestore(&pmic->lock, flags);
 }
 EXPORT_SYMBOL(hisi_pmic_rmw);
 
@@ -142,16 +126,15 @@ static irqreturn_t hisi_irq_handler(int irq, void *data)
 	int i, offset;
 
 	for (i = 0; i < pmic->irqarray; i++) {
-		pending = hisi_pmic_read(g_pmic, (i + pmic->irq_addr.start_addr));
+		pending = hisi_pmic_read(pmic, (i + pmic->irq_addr.start_addr));
 		pending &= HISI_MASK_FIELD;
-		if (pending != 0) {
-			pr_info("pending[%d]=0x%lx\n\r", i, pending);
-		}
+		if (pending != 0)
+			pr_debug("pending[%d]=0x%lx\n\r", i, pending);
 
-		hisi_pmic_write(g_pmic, (i + pmic->irq_addr.start_addr), pending);
+		hisi_pmic_write(pmic, (i + pmic->irq_addr.start_addr), pending);
 
-		/*solve powerkey order*/
-		if ((HISI_IRQ_KEY_NUM == i) && ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
+		/* solve powerkey order */
+		if ((i == HISI_IRQ_KEY_NUM) && ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]);
 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]);
 			pending &= (~HISI_IRQ_KEY_VALUE);
@@ -159,25 +142,25 @@ static irqreturn_t hisi_irq_handler(int irq, void *data)
 
 		if (pending) {
 			for_each_set_bit(offset, &pending, HISI_BITS)
-				generic_handle_irq(pmic->irqs[offset + i * HISI_BITS]);/*lint !e679 */
+				generic_handle_irq(pmic->irqs[offset + i * HISI_BITS]);
 		}
 	}
 
 	/*Handle the second group irq if analysis the second group irq from dtsi*/
-	if (1 == g_extinterrupt_flag){
+	if (pmic->g_extinterrupt_flag == 1) {
 		for (i = 0; i < pmic->irqarray1; i++) {
-			pending = hisi_pmic_read(g_pmic, (i + pmic->irq_addr1.start_addr));
+			pending = hisi_pmic_read(pmic, (i + pmic->irq_addr1.start_addr));
 			pending &= HISI_MASK_FIELD;
-			if (pending != 0) {
-				pr_info("pending[%d]=0x%lx\n\r", i, pending);
-			}
+			if (pending != 0)
+				pr_debug("pending[%d]=0x%lx\n\r", i, pending);
 
-			hisi_pmic_write(g_pmic, (i + pmic->irq_addr1.start_addr), pending);
+			hisi_pmic_write(pmic, (i + pmic->irq_addr1.start_addr), pending);
 
-			if (pending) {
-				for_each_set_bit(offset, &pending, HISI_BITS)
-					generic_handle_irq(pmic->irqs[offset + (i+HISI_PMIC_FIRST_GROUP_INT_NUM) * HISI_BITS]);/*lint !e679 */
-			}
+			if (!pending)
+				continue;
+
+			for_each_set_bit(offset, &pending, HISI_BITS)
+				generic_handle_irq(pmic->irqs[offset + (i + HISI_PMIC_FIRST_GROUP_INT_NUM) * HISI_BITS]);
 		}
 	}
 
@@ -190,25 +173,25 @@ static void hisi_irq_mask(struct irq_data *d)
 	u32 data, offset;
 	unsigned long flags;
 
-	if (NULL == g_pmic) {
-		pr_err(" g_pmic  is NULL\n");
-		return;
-	}
-
 	offset = (irqd_to_hwirq(d) >> 3);
-	if (1==g_extinterrupt_flag){
-		if ( offset < HISI_PMIC_FIRST_GROUP_INT_NUM)
+	if (pmic->g_extinterrupt_flag == 1) {
+		if (offset < HISI_PMIC_FIRST_GROUP_INT_NUM) {
 			offset += pmic->irq_mask_addr.start_addr;
-		else/*Change addr when irq num larger than 16 because interrupt addr is nonsequence*/
-			offset = offset+(pmic->irq_mask_addr1.start_addr)-HISI_PMIC_FIRST_GROUP_INT_NUM;
-	}else{
+		} else {
+			/*
+			 * Change addr when irq num larger than 16 because
+			 * interrupt addr is nonsequence
+			 */
+			offset = offset + (pmic->irq_mask_addr1.start_addr) - HISI_PMIC_FIRST_GROUP_INT_NUM;
+		}
+	} else {
 		offset += pmic->irq_mask_addr.start_addr;
 	}
-	spin_lock_irqsave(&g_pmic->lock, flags);
-	data = hisi_pmic_read(g_pmic, offset);
+	spin_lock_irqsave(&pmic->lock, flags);
+	data = hisi_pmic_read(pmic, offset);
 	data |= (1 << (irqd_to_hwirq(d) & 0x07));
-	hisi_pmic_write(g_pmic, offset, data);
-	spin_unlock_irqrestore(&g_pmic->lock, flags);
+	hisi_pmic_write(pmic, offset, data);
+	spin_unlock_irqrestore(&pmic->lock, flags);
 }
 
 static void hisi_irq_unmask(struct irq_data *d)
@@ -217,25 +200,20 @@ static void hisi_irq_unmask(struct irq_data *d)
 	u32 data, offset;
 	unsigned long flags;
 
-	if (NULL == g_pmic) {
-		pr_err(" g_pmic  is NULL\n");
-		return;
-	}
-
 	offset = (irqd_to_hwirq(d) >> 3);
-	if (1==g_extinterrupt_flag){
-		if ( offset < HISI_PMIC_FIRST_GROUP_INT_NUM)
+	if (pmic->g_extinterrupt_flag == 1) {
+		if (offset < HISI_PMIC_FIRST_GROUP_INT_NUM)
 			offset += pmic->irq_mask_addr.start_addr;
 		else
-			offset = offset+(pmic->irq_mask_addr1.start_addr)-HISI_PMIC_FIRST_GROUP_INT_NUM;
-	}else{
+			offset = offset + (pmic->irq_mask_addr1.start_addr) - HISI_PMIC_FIRST_GROUP_INT_NUM;
+	} else {
 		offset += pmic->irq_mask_addr.start_addr;
 	}
-	spin_lock_irqsave(&g_pmic->lock, flags);
-	data = hisi_pmic_read(g_pmic, offset);
+	spin_lock_irqsave(&pmic->lock, flags);
+	data = hisi_pmic_read(pmic, offset);
 	data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
-	hisi_pmic_write(g_pmic, offset, data);
-	spin_unlock_irqrestore(&g_pmic->lock, flags);
+	hisi_pmic_write(pmic, offset, data);
+	spin_unlock_irqrestore(&pmic->lock, flags);
 }
 
 static struct irq_chip hisi_pmu_irqchip = {
@@ -247,7 +225,7 @@ static struct irq_chip hisi_pmu_irqchip = {
 };
 
 static int hisi_irq_map(struct irq_domain *d, unsigned int virq,
-			  irq_hw_number_t hw)
+			irq_hw_number_t hw)
 {
 	struct hisi_pmic *pmic = d->host_data;
 
@@ -259,19 +237,18 @@ static int hisi_irq_map(struct irq_domain *d, unsigned int virq,
 	return 0;
 }
 
-static struct irq_domain_ops hisi_domain_ops = {
+static const struct irq_domain_ops hisi_domain_ops = {
 	.map	= hisi_irq_map,
 	.xlate	= irq_domain_xlate_twocell,
 };
 
-/*lint -e570 -e64*/
 static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *pmic)
 {
 	int ret = 0;
 
 	/*get pmic irq num*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-num",
-						&(pmic->irqnum), 1);
+					 &pmic->irqnum, 1);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-num property set\n");
 		ret = -ENODEV;
@@ -280,7 +257,7 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 
 	/*get pmic irq array number*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-array",
-						&(pmic->irqarray), 1);
+					 &pmic->irqarray, 1);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-array property set\n");
 		ret = -ENODEV;
@@ -289,7 +266,7 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 
 	/*SOC_PMIC_IRQ_MASK_0_ADDR*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-mask-addr",
-						(int *)&pmic->irq_mask_addr, 2);
+					 (int *)&pmic->irq_mask_addr, 2);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-mask-addr property set\n");
 		ret = -ENODEV;
@@ -298,24 +275,16 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 
 	/*SOC_PMIC_IRQ0_ADDR*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-addr",
-						(int *)&pmic->irq_addr, 2);
+					 (int *)&pmic->irq_addr, 2);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-addr property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-vbus",
-						(u32 *)&g_pmic_vbus, 2);
-	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-vbus property\n");
-		ret = -ENODEV;
-		return ret;
-	}
-
 	/*pmic lock*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-lock",
-						(int *)&pmic->normal_lock, 2);
+					 (int *)&pmic->normal_lock, 2);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-lock property set\n");
 		ret = -ENODEV;
@@ -324,7 +293,7 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 
 	/*pmic debug lock*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-debug-lock",
-						(int *)&pmic->debug_lock, 2);
+					 (int *)&pmic->debug_lock, 2);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-debug-lock property set\n");
 		ret = -ENODEV;
@@ -332,17 +301,15 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 	}
 
 	return ret;
-}/*lint -restore*/
+}
 
-
-/*lint -e570 -e64*/
 static int get_pmic_device_tree_data1(struct device_node *np, struct hisi_pmic *pmic)
 {
 	int ret = 0;
 
 	/*get pmic irq num*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-num1",
-						&(pmic->irqnum1), 1);
+					 &pmic->irqnum1, 1);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-num1 property set\n");
 		ret = -ENODEV;
@@ -352,7 +319,7 @@ static int get_pmic_device_tree_data1(struct device_node *np, struct hisi_pmic *
 
 	/*get pmic irq array number*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-array1",
-						&(pmic->irqarray1), 1);
+					 &pmic->irqarray1, 1);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-array1 property set\n");
 		ret = -ENODEV;
@@ -361,7 +328,7 @@ static int get_pmic_device_tree_data1(struct device_node *np, struct hisi_pmic *
 
 	/*SOC_PMIC_IRQ_MASK_0_ADDR*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-mask-addr1",
-						(int *)&pmic->irq_mask_addr1, 2);
+					 (int *)&pmic->irq_mask_addr1, 2);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-mask-addr1 property set\n");
 		ret = -ENODEV;
@@ -370,43 +337,48 @@ static int get_pmic_device_tree_data1(struct device_node *np, struct hisi_pmic *
 
 	/*SOC_PMIC_IRQ0_ADDR*/
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-addr1",
-						(int *)&pmic->irq_addr1, 2);
+					 (int *)&pmic->irq_addr1, 2);
 	if (ret) {
 		pr_err("no hisilicon,hisi-pmic-irq-addr1 property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
-	g_extinterrupt_flag = 1;
+	pmic->g_extinterrupt_flag = 1;
 	return ret;
-}/*lint -restore*/
+}
 
 static void hisi_pmic_irq_prc(struct hisi_pmic *pmic)
 {
 	int i;
-	for (i = 0 ; i < pmic->irq_mask_addr.array; i++) {
+
+	for (i = 0 ; i < pmic->irq_mask_addr.array; i++)
 		hisi_pmic_write(pmic, pmic->irq_mask_addr.start_addr + i, HISI_MASK_STATE);
-	}
 
 	for (i = 0 ; i < pmic->irq_addr.array; i++) {
 		unsigned int pending = hisi_pmic_read(pmic, pmic->irq_addr.start_addr + i);
-		pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n", pmic->irq_addr.start_addr + i, pending);
+
+		pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n",
+			 pmic->irq_addr.start_addr + i, pending);
 		hisi_pmic_write(pmic, pmic->irq_addr.start_addr + i, HISI_MASK_STATE);
 	}
-
 }
 
 static void hisi_pmic_irq1_prc(struct hisi_pmic *pmic)
 {
 	int i;
-	if(1 == g_extinterrupt_flag){
-		for (i = 0 ; i < pmic->irq_mask_addr1.array; i++) {
+	unsigned int pending1;
+
+	if (pmic->g_extinterrupt_flag == 1) {
+		for (i = 0 ; i < pmic->irq_mask_addr1.array; i++)
 			hisi_pmic_write(pmic, pmic->irq_mask_addr1.start_addr + i, HISI_MASK_STATE);
-		}
 
 		for (i = 0 ; i < pmic->irq_addr1.array; i++) {
-			unsigned int pending1 = hisi_pmic_read(pmic, pmic->irq_addr1.start_addr + i);
-			pr_debug("PMU IRQ address1 value:irq[0x%x] = 0x%x\n", pmic->irq_addr1.start_addr + i, pending1);
+			pending1 = hisi_pmic_read(pmic, pmic->irq_addr1.start_addr + i);
+
+			pr_debug("PMU IRQ address1 value:irq[0x%x] = 0x%x\n",
+				 pmic->irq_addr1.start_addr + i, pending1);
+
 			hisi_pmic_write(pmic, pmic->irq_addr1.start_addr + i, HISI_MASK_STATE);
 		}
 	}
@@ -424,36 +396,32 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 	unsigned int virq;
 
 	pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
-	if (!pmic) {
-		dev_err(dev, "cannot allocate hisi_pmic device info\n");
+	if (!pmic)
 		return -ENOMEM;
-	}
 
 	/*TODO: get pmic dts info*/
 	ret = get_pmic_device_tree_data(np, pmic);
 	if (ret) {
-		dev_err(&pdev->dev, "Error reading hisi pmic dts \n");
+		dev_err(&pdev->dev, "Error reading hisi pmic dts\n");
 		return ret;
 	}
 
 	/*get pmic dts the second group irq*/
 	ret = get_pmic_device_tree_data1(np, pmic);
-	if (ret) {
+	if (ret)
 		dev_err(&pdev->dev, "the platform don't support ext-interrupt.\n");
-	}
 
 	/* TODO: get and enable clk request */
 	spin_lock_init(&pmic->lock);
 
 	pmic->dev = dev;
-	g_pmic = pmic;
-	ret = of_property_read_u32_array(np, "hisilicon,pmic_fpga_flag", &fpga_flag, 1);
-	if (ret) {
+	ret = of_property_read_u32_array(np, "hisilicon,pmic_fpga_flag",
+					 &fpga_flag, 1);
+	if (ret)
 		pr_err("no hisilicon,pmic_fpga_flag property set\n");
-	}
-	if (PMIC_FPGA_FLAG == fpga_flag) {
+
+	if (fpga_flag == PMIC_FPGA_FLAG)
 		goto after_irq_register;
-	}
 
 	pmic->gpio = of_get_gpio_flags(np, 0, &flags);
 	if (pmic->gpio < 0)
@@ -477,12 +445,9 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 
 	pmic->irqnum += pmic->irqnum1;
 
-	pmic->irqs = (unsigned int *)devm_kmalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
-	if (!pmic->irqs) {
-		pr_err("%s:Failed to alloc memory for pmic irq number!\n", __func__);
+	pmic->irqs = devm_kzalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
+	if (!pmic->irqs)
 		goto irq_malloc;
-	}
-	memset(pmic->irqs, 0, pmic->irqnum);
 
 	pmic->domain = irq_domain_add_simple(np, pmic->irqnum, 0,
 					     &hisi_domain_ops, pmic);
@@ -504,7 +469,7 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 	}
 
 	ret = request_threaded_irq(pmic->irq, hisi_irq_handler, NULL,
-				IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
+				   IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
 				   "pmic", pmic);
 	if (ret < 0) {
 		dev_err(dev, "could not claim pmic %d\n", ret);
@@ -515,31 +480,28 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 after_irq_register:
 	return 0;
 
-
 request_theaded_irq:
 irq_create_mapping:
 irq_domain:
 irq_malloc:
 	gpio_free(pmic->gpio);
-	g_pmic = NULL;
 	return ret;
 }
 
 static void hisi_pmic_remove(struct spmi_device *pdev)
 {
-
 	struct hisi_pmic *pmic = dev_get_drvdata(&pdev->dev);
 
 	free_irq(pmic->irq, pmic);
 	gpio_free(pmic->gpio);
 	devm_kfree(&pdev->dev, pmic);
-
 }
+
 static int hisi_pmic_suspend(struct device *dev, pm_message_t state)
 {
 	struct hisi_pmic *pmic = dev_get_drvdata(dev);
 
-	if (NULL == pmic) {
+	if (!pmic) {
 		pr_err("%s:pmic is NULL\n", __func__);
 		return -ENOMEM;
 	}
@@ -548,13 +510,13 @@ static int hisi_pmic_suspend(struct device *dev, pm_message_t state)
 	pr_info("%s:-\n", __func__);
 
 	return 0;
-}/*lint !e715 */
+}
 
 static int hisi_pmic_resume(struct device *dev)
 {
 	struct hisi_pmic *pmic = dev_get_drvdata(dev);
 
-	if (NULL == pmic) {
+	if (!pmic) {
 		pr_err("%s:pmic is NULL\n", __func__);
 		return -ENOMEM;
 	}
@@ -588,10 +550,8 @@ static void __exit hisi_pmic_exit(void)
 	spmi_driver_unregister(&hisi_pmic_driver);
 }
 
-
 subsys_initcall_sync(hisi_pmic_init);
 module_exit(hisi_pmic_exit);
 
 MODULE_DESCRIPTION("PMIC driver");
 MODULE_LICENSE("GPL v2");
-
diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
index 5be9b4d3f207..e0a8b50f95fc 100644
--- a/include/linux/mfd/hi6421-spmi-pmic.h
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Header file for device driver Hi6421 PMIC
  *
@@ -5,19 +6,6 @@
  * Copyright (C) 2011 Hisilicon.
  *
  * Guodong Xu <guodong.xu@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #ifndef	__HISI_PMIC_H
@@ -25,12 +13,12 @@
 
 #include <linux/irqdomain.h>
 
-#define HISI_REGS_ENA_PROTECT_TIME	(0) 	/* in microseconds */
+#define HISI_REGS_ENA_PROTECT_TIME	(0)	/* in microseconds */
 #define HISI_ECO_MODE_ENABLE		(1)
 #define HISI_ECO_MODE_DISABLE		(0)
 
 typedef int (*pmic_ocp_callback)(char *);
-extern int hisi_pmic_special_ocp_register(char *power_name, pmic_ocp_callback handler);
+int hisi_pmic_special_ocp_register(char *power_name, pmic_ocp_callback handler);
 
 struct irq_mask_info {
 	int start_addr;
@@ -71,6 +59,8 @@ struct hisi_pmic {
 	struct irq_info irq_addr1;
 	struct write_lock normal_lock;
 	struct write_lock debug_lock;
+
+	unsigned int g_extinterrupt_flag;
 };
 
 /* 0:disable; 1:enable */
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 15/44] staging: mfd: hi6421-spmi-pmic: cleanup hi6421-spmi-pmic.h header
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (13 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 14/44] staging: mfd: hi6421-spmi-pmic: get rid of the static vars Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 16/44] staging: mfd: hi6421-spmi-pmic: change the binding logic Mauro Carvalho Chehab
                   ` (30 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones, linux-kernel

There are several external vars that are defined there, which
are not needed anymore.

Get rid of them.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 include/linux/mfd/hi6421-spmi-pmic.h | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
index e0a8b50f95fc..1f986dd5f31c 100644
--- a/include/linux/mfd/hi6421-spmi-pmic.h
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -63,34 +63,9 @@ struct hisi_pmic {
 	unsigned int g_extinterrupt_flag;
 };
 
-/* 0:disable; 1:enable */
-unsigned int get_uv_mntn_status(void);
-void clear_uv_mntn_resered_reg_bit(void);
-void set_uv_mntn_resered_reg_bit(void);
-
-/* Register Access Helpers */
 u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg);
 void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val);
 void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits);
-unsigned int hisi_pmic_reg_read(int addr);
-void hisi_pmic_reg_write(int addr, int val);
-void hisi_pmic_reg_write_lock(int addr, int val);
-int hisi_pmic_array_read(int addr, char *buff, unsigned int len);
-int hisi_pmic_array_write(int addr, char *buff, unsigned int len);
-extern int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list);
-extern int hisi_pmic_get_vbus_status(void);
-static inline u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg) { return 0; }
-static inline void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val) {}
-static inline void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits) {}
-static inline unsigned int hisi_pmic_reg_read(int addr) { return 0; }
-static inline void hisi_pmic_reg_write(int addr, int val) {}
-static inline void hisi_pmic_reg_write_lock(int addr, int val) {}
-static inline int hisi_pmic_array_read(int addr, char *buff, unsigned int len) { return 0; }
-static inline int hisi_pmic_array_write(int addr, char *buff, unsigned int len) { return 0; }
-static inline int hisi_get_pmic_irq_byname(unsigned int pmic_irq_list) { return -1; }
-static inline int hisi_pmic_get_vbus_status(void) { return 1; }
-static inline u32 hisi_pmic_read_sub_pmu(u8 sid ,int reg) { return 0; }
-static inline void hisi_pmic_write_sub_pmu(u8 sid ,int reg, u32 val) {}
 
 enum pmic_irq_list {
 	OTMP = 0,
@@ -110,4 +85,3 @@ enum pmic_irq_list {
 	PMIC_IRQ_LIST_MAX,
 };
 #endif		/* __HISI_PMIC_H */
-
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 16/44] staging: mfd: hi6421-spmi-pmic: change the binding logic
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (14 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 15/44] staging: mfd: hi6421-spmi-pmic: cleanup hi6421-spmi-pmic.h header Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 17/44] staging: mfd: hi6421-spmi-pmic: get rid of unused OF properties Mauro Carvalho Chehab
                   ` (29 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Change the binding logic to ensure that the MFD driver
will be load after having the SPMI controller registered.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 84 +++++++--------------
 1 file changed, 29 insertions(+), 55 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index be42fed16bd2..939f7bd5d8ba 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -24,13 +24,14 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/mfd/core.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
 #include <linux/of_irq.h>
-#include <linux/mfd/hisi_pmic.h>
+#include <linux/mfd/hi6421-spmi-pmic.h>
 #include <linux/irq.h>
 #include <linux/spmi.h>
 #ifndef NO_IRQ
@@ -53,11 +54,8 @@
 /*define the first group interrupt register number*/
 #define HISI_PMIC_FIRST_GROUP_INT_NUM        2
 
-static const struct of_device_id of_hisi_pmic_match_tbl[] = {
-	{
-		.compatible = "hisilicon-hisi-pmic-spmi",
-	},
-	{ /* end */ }
+static const struct mfd_cell hi6421v600_devs[] = {
+	{ .name = "hi6421v600-regulator", },
 };
 
 /*
@@ -477,6 +475,22 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 		goto request_theaded_irq;
 	}
 
+	dev_set_drvdata(&pdev->dev, pmic);
+
+	/*
+	 * The logic below will rely that the pmic is already stored at
+	 * drvdata.
+	 */
+	dev_dbg(&pdev->dev, "SPMI-PMIC: adding childs for %pOF\n",
+		pdev->dev.of_node);
+	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
+				   hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs),
+				   NULL, 0, NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);
+		return ret;
+	}
+
 after_irq_register:
 	return 0;
 
@@ -497,61 +511,21 @@ static void hisi_pmic_remove(struct spmi_device *pdev)
 	devm_kfree(&pdev->dev, pmic);
 }
 
-static int hisi_pmic_suspend(struct device *dev, pm_message_t state)
-{
-	struct hisi_pmic *pmic = dev_get_drvdata(dev);
+static const struct of_device_id pmic_spmi_id_table[] = {
+	{ .compatible = "hisilicon,hi6421-spmi-pmic" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
 
-	if (!pmic) {
-		pr_err("%s:pmic is NULL\n", __func__);
-		return -ENOMEM;
-	}
-
-	pr_info("%s:+\n", __func__);
-	pr_info("%s:-\n", __func__);
-
-	return 0;
-}
-
-static int hisi_pmic_resume(struct device *dev)
-{
-	struct hisi_pmic *pmic = dev_get_drvdata(dev);
-
-	if (!pmic) {
-		pr_err("%s:pmic is NULL\n", __func__);
-		return -ENOMEM;
-	}
-
-	pr_info("%s:+\n", __func__);
-	pr_info("%s:-\n", __func__);
-
-	return 0;
-}
-
-MODULE_DEVICE_TABLE(spmi, pmic_spmi_id);
 static struct spmi_driver hisi_pmic_driver = {
 	.driver = {
-		.name	= "hisi_pmic",
-		.owner  = THIS_MODULE,
-		.of_match_table = of_hisi_pmic_match_tbl,
-		.suspend = hisi_pmic_suspend,
-		.resume = hisi_pmic_resume,
+		.name	= "hi6421-spmi-pmic",
+		.of_match_table = pmic_spmi_id_table,
 	},
 	.probe	= hisi_pmic_probe,
 	.remove	= hisi_pmic_remove,
 };
+module_spmi_driver(hisi_pmic_driver);
 
-static int __init hisi_pmic_init(void)
-{
-	return spmi_driver_register(&hisi_pmic_driver);
-}
-
-static void __exit hisi_pmic_exit(void)
-{
-	spmi_driver_unregister(&hisi_pmic_driver);
-}
-
-subsys_initcall_sync(hisi_pmic_init);
-module_exit(hisi_pmic_exit);
-
-MODULE_DESCRIPTION("PMIC driver");
+MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver");
 MODULE_LICENSE("GPL v2");
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 17/44] staging: mfd: hi6421-spmi-pmic: get rid of unused OF properties
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (15 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 16/44] staging: mfd: hi6421-spmi-pmic: change the binding logic Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 18/44] staging: mfd: hi6421-spmi-pmic: cleanup " Mauro Carvalho Chehab
                   ` (28 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
	linux-kernel, devel

There are several OF properties that aren't used by Hikey 970,
and some are not even used inside the driver.

So, drop them, as as this makes easier to document what's
actually used.

If latter needed, those could be re-added later.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 145 +-------------------
 include/linux/mfd/hi6421-spmi-pmic.h        |  14 +-
 2 files changed, 7 insertions(+), 152 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index 939f7bd5d8ba..f523b2d844b9 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -49,7 +49,6 @@
 /*#define HISI_NR_IRQ			25*/
 #define HISI_MASK_FIELD		0xFF
 #define HISI_BITS			8
-#define PMIC_FPGA_FLAG          1
 
 /*define the first group interrupt register number*/
 #define HISI_PMIC_FIRST_GROUP_INT_NUM        2
@@ -144,24 +143,6 @@ static irqreturn_t hisi_irq_handler(int irq, void *data)
 		}
 	}
 
-	/*Handle the second group irq if analysis the second group irq from dtsi*/
-	if (pmic->g_extinterrupt_flag == 1) {
-		for (i = 0; i < pmic->irqarray1; i++) {
-			pending = hisi_pmic_read(pmic, (i + pmic->irq_addr1.start_addr));
-			pending &= HISI_MASK_FIELD;
-			if (pending != 0)
-				pr_debug("pending[%d]=0x%lx\n\r", i, pending);
-
-			hisi_pmic_write(pmic, (i + pmic->irq_addr1.start_addr), pending);
-
-			if (!pending)
-				continue;
-
-			for_each_set_bit(offset, &pending, HISI_BITS)
-				generic_handle_irq(pmic->irqs[offset + (i + HISI_PMIC_FIRST_GROUP_INT_NUM) * HISI_BITS]);
-		}
-	}
-
 	return IRQ_HANDLED;
 }
 
@@ -172,19 +153,8 @@ static void hisi_irq_mask(struct irq_data *d)
 	unsigned long flags;
 
 	offset = (irqd_to_hwirq(d) >> 3);
-	if (pmic->g_extinterrupt_flag == 1) {
-		if (offset < HISI_PMIC_FIRST_GROUP_INT_NUM) {
-			offset += pmic->irq_mask_addr.start_addr;
-		} else {
-			/*
-			 * Change addr when irq num larger than 16 because
-			 * interrupt addr is nonsequence
-			 */
-			offset = offset + (pmic->irq_mask_addr1.start_addr) - HISI_PMIC_FIRST_GROUP_INT_NUM;
-		}
-	} else {
-		offset += pmic->irq_mask_addr.start_addr;
-	}
+	offset += pmic->irq_mask_addr.start_addr;
+
 	spin_lock_irqsave(&pmic->lock, flags);
 	data = hisi_pmic_read(pmic, offset);
 	data |= (1 << (irqd_to_hwirq(d) & 0x07));
@@ -199,14 +169,8 @@ static void hisi_irq_unmask(struct irq_data *d)
 	unsigned long flags;
 
 	offset = (irqd_to_hwirq(d) >> 3);
-	if (pmic->g_extinterrupt_flag == 1) {
-		if (offset < HISI_PMIC_FIRST_GROUP_INT_NUM)
-			offset += pmic->irq_mask_addr.start_addr;
-		else
-			offset = offset + (pmic->irq_mask_addr1.start_addr) - HISI_PMIC_FIRST_GROUP_INT_NUM;
-	} else {
-		offset += pmic->irq_mask_addr.start_addr;
-	}
+	offset += pmic->irq_mask_addr.start_addr;
+
 	spin_lock_irqsave(&pmic->lock, flags);
 	data = hisi_pmic_read(pmic, offset);
 	data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
@@ -280,69 +244,6 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 		return ret;
 	}
 
-	/*pmic lock*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-lock",
-					 (int *)&pmic->normal_lock, 2);
-	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-lock property set\n");
-		ret = -ENODEV;
-		return ret;
-	}
-
-	/*pmic debug lock*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-debug-lock",
-					 (int *)&pmic->debug_lock, 2);
-	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-debug-lock property set\n");
-		ret = -ENODEV;
-		return ret;
-	}
-
-	return ret;
-}
-
-static int get_pmic_device_tree_data1(struct device_node *np, struct hisi_pmic *pmic)
-{
-	int ret = 0;
-
-	/*get pmic irq num*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-num1",
-					 &pmic->irqnum1, 1);
-	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-num1 property set\n");
-		ret = -ENODEV;
-		pmic->irqnum1 = 0;
-		return ret;
-	}
-
-	/*get pmic irq array number*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-array1",
-					 &pmic->irqarray1, 1);
-	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-array1 property set\n");
-		ret = -ENODEV;
-		return ret;
-	}
-
-	/*SOC_PMIC_IRQ_MASK_0_ADDR*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-mask-addr1",
-					 (int *)&pmic->irq_mask_addr1, 2);
-	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-mask-addr1 property set\n");
-		ret = -ENODEV;
-		return ret;
-	}
-
-	/*SOC_PMIC_IRQ0_ADDR*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-addr1",
-					 (int *)&pmic->irq_addr1, 2);
-	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-addr1 property set\n");
-		ret = -ENODEV;
-		return ret;
-	}
-
-	pmic->g_extinterrupt_flag = 1;
 	return ret;
 }
 
@@ -362,26 +263,6 @@ static void hisi_pmic_irq_prc(struct hisi_pmic *pmic)
 	}
 }
 
-static void hisi_pmic_irq1_prc(struct hisi_pmic *pmic)
-{
-	int i;
-	unsigned int pending1;
-
-	if (pmic->g_extinterrupt_flag == 1) {
-		for (i = 0 ; i < pmic->irq_mask_addr1.array; i++)
-			hisi_pmic_write(pmic, pmic->irq_mask_addr1.start_addr + i, HISI_MASK_STATE);
-
-		for (i = 0 ; i < pmic->irq_addr1.array; i++) {
-			pending1 = hisi_pmic_read(pmic, pmic->irq_addr1.start_addr + i);
-
-			pr_debug("PMU IRQ address1 value:irq[0x%x] = 0x%x\n",
-				 pmic->irq_addr1.start_addr + i, pending1);
-
-			hisi_pmic_write(pmic, pmic->irq_addr1.start_addr + i, HISI_MASK_STATE);
-		}
-	}
-}
-
 static int hisi_pmic_probe(struct spmi_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -390,7 +271,6 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 	enum of_gpio_flags flags;
 	int ret = 0;
 	int i;
-	unsigned int fpga_flag = 0;
 	unsigned int virq;
 
 	pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
@@ -404,22 +284,10 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 		return ret;
 	}
 
-	/*get pmic dts the second group irq*/
-	ret = get_pmic_device_tree_data1(np, pmic);
-	if (ret)
-		dev_err(&pdev->dev, "the platform don't support ext-interrupt.\n");
-
 	/* TODO: get and enable clk request */
 	spin_lock_init(&pmic->lock);
 
 	pmic->dev = dev;
-	ret = of_property_read_u32_array(np, "hisilicon,pmic_fpga_flag",
-					 &fpga_flag, 1);
-	if (ret)
-		pr_err("no hisilicon,pmic_fpga_flag property set\n");
-
-	if (fpga_flag == PMIC_FPGA_FLAG)
-		goto after_irq_register;
 
 	pmic->gpio = of_get_gpio_flags(np, 0, &flags);
 	if (pmic->gpio < 0)
@@ -438,10 +306,6 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 
 	/* mask && clear IRQ status */
 	hisi_pmic_irq_prc(pmic);
-	/*clear && mask the new adding irq*/
-	hisi_pmic_irq1_prc(pmic);
-
-	pmic->irqnum += pmic->irqnum1;
 
 	pmic->irqs = devm_kzalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
 	if (!pmic->irqs)
@@ -491,7 +355,6 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 		return ret;
 	}
 
-after_irq_register:
 	return 0;
 
 request_theaded_irq:
diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
index 1f986dd5f31c..41b61de48259 100644
--- a/include/linux/mfd/hi6421-spmi-pmic.h
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -48,19 +48,11 @@ struct hisi_pmic {
 	struct irq_domain	*domain;
 	int			irq;
 	int			gpio;
-	unsigned int	*irqs;
+	unsigned int		*irqs;
 	int			irqnum;
 	int			irqarray;
-	struct irq_mask_info irq_mask_addr;
-	struct irq_info irq_addr;
-	int			irqnum1;
-	int			irqarray1;
-	struct irq_mask_info irq_mask_addr1;
-	struct irq_info irq_addr1;
-	struct write_lock normal_lock;
-	struct write_lock debug_lock;
-
-	unsigned int g_extinterrupt_flag;
+	struct irq_mask_info 	irq_mask_addr;
+	struct irq_info		irq_addr;
 };
 
 u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 18/44] staging: mfd: hi6421-spmi-pmic: cleanup OF properties
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (16 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 17/44] staging: mfd: hi6421-spmi-pmic: get rid of unused OF properties Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 19/44] staging: mfd: hi6421-spmi-pmic: change namespace on its functions Mauro Carvalho Chehab
                   ` (27 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Simplify the names of the DT properties and do some cleanups,
in order to better document them.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index f523b2d844b9..aed2d3ec2227 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -209,37 +209,37 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 	int ret = 0;
 
 	/*get pmic irq num*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-num",
+	ret = of_property_read_u32_array(np, "irq-num",
 					 &pmic->irqnum, 1);
 	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-num property set\n");
+		pr_err("no irq-num property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
 	/*get pmic irq array number*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-array",
+	ret = of_property_read_u32_array(np, "irq-array",
 					 &pmic->irqarray, 1);
 	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-array property set\n");
+		pr_err("no irq-array property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
 	/*SOC_PMIC_IRQ_MASK_0_ADDR*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-mask-addr",
+	ret = of_property_read_u32_array(np, "irq-mask-addr",
 					 (int *)&pmic->irq_mask_addr, 2);
 	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-mask-addr property set\n");
+		pr_err("no irq-mask-addr property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
 	/*SOC_PMIC_IRQ0_ADDR*/
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-pmic-irq-addr",
+	ret = of_property_read_u32_array(np, "irq-addr",
 					 (int *)&pmic->irq_addr, 2);
 	if (ret) {
-		pr_err("no hisilicon,hisi-pmic-irq-addr property set\n");
+		pr_err("no irq-addr property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 19/44] staging: mfd: hi6421-spmi-pmic: change namespace on its functions
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (17 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 18/44] staging: mfd: hi6421-spmi-pmic: cleanup " Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 20/44] staging: mfd: hi6421-spmi-pmic: fix some coding style issues Mauro Carvalho Chehab
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
	linux-kernel, devel

Rename the functions used internally inside the driver in
order for them to follow the driver's name.

While here, get rid of some unused definitions at the
header file.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 97 +++++++++++----------
 include/linux/mfd/hi6421-spmi-pmic.h        | 51 ++++-------
 2 files changed, 70 insertions(+), 78 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index aed2d3ec2227..09cedfa1e4bb 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -62,7 +62,7 @@ static const struct mfd_cell hi6421v600_devs[] = {
  * Hisilicon SoC use hardware to map PMIC register into SoC mapping.
  * At here, we are accessing SoC register with 32-bit.
  */
-u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg)
+u32 hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg)
 {
 	u32 ret;
 	u8 read_value = 0;
@@ -82,9 +82,9 @@ u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg)
 	}
 	return (u32)read_value;
 }
-EXPORT_SYMBOL(hisi_pmic_read);
+EXPORT_SYMBOL(hi6421_spmi_pmic_read);
 
-void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val)
+void hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val)
 {
 	u32 ret;
 	struct spmi_device *pdev;
@@ -101,34 +101,36 @@ void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val)
 		return;
 	}
 }
-EXPORT_SYMBOL(hisi_pmic_write);
+EXPORT_SYMBOL(hi6421_spmi_pmic_write);
 
-void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits)
+void hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg,
+			  u32 mask, u32 bits)
 {
 	u32 data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&pmic->lock, flags);
-	data = hisi_pmic_read(pmic, reg) & ~mask;
+	data = hi6421_spmi_pmic_read(pmic, reg) & ~mask;
 	data |= mask & bits;
-	hisi_pmic_write(pmic, reg, data);
+	hi6421_spmi_pmic_write(pmic, reg, data);
 	spin_unlock_irqrestore(&pmic->lock, flags);
 }
-EXPORT_SYMBOL(hisi_pmic_rmw);
+EXPORT_SYMBOL(hi6421_spmi_pmic_rmw);
 
-static irqreturn_t hisi_irq_handler(int irq, void *data)
+static irqreturn_t hi6421_spmi_irq_handler(int irq, void *data)
 {
-	struct hisi_pmic *pmic = (struct hisi_pmic *)data;
+	struct hi6421_spmi_pmic *pmic = (struct hi6421_spmi_pmic *)data;
 	unsigned long pending;
 	int i, offset;
 
 	for (i = 0; i < pmic->irqarray; i++) {
-		pending = hisi_pmic_read(pmic, (i + pmic->irq_addr.start_addr));
+		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr.start_addr));
 		pending &= HISI_MASK_FIELD;
 		if (pending != 0)
 			pr_debug("pending[%d]=0x%lx\n\r", i, pending);
 
-		hisi_pmic_write(pmic, (i + pmic->irq_addr.start_addr), pending);
+		hi6421_spmi_pmic_write(pmic, (i + pmic->irq_addr.start_addr),
+				       pending);
 
 		/* solve powerkey order */
 		if ((i == HISI_IRQ_KEY_NUM) && ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
@@ -146,9 +148,9 @@ static irqreturn_t hisi_irq_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void hisi_irq_mask(struct irq_data *d)
+static void hi6421_spmi_irq_mask(struct irq_data *d)
 {
-	struct hisi_pmic *pmic = irq_data_get_irq_chip_data(d);
+	struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d);
 	u32 data, offset;
 	unsigned long flags;
 
@@ -156,15 +158,15 @@ static void hisi_irq_mask(struct irq_data *d)
 	offset += pmic->irq_mask_addr.start_addr;
 
 	spin_lock_irqsave(&pmic->lock, flags);
-	data = hisi_pmic_read(pmic, offset);
+	data = hi6421_spmi_pmic_read(pmic, offset);
 	data |= (1 << (irqd_to_hwirq(d) & 0x07));
-	hisi_pmic_write(pmic, offset, data);
+	hi6421_spmi_pmic_write(pmic, offset, data);
 	spin_unlock_irqrestore(&pmic->lock, flags);
 }
 
-static void hisi_irq_unmask(struct irq_data *d)
+static void hi6421_spmi_irq_unmask(struct irq_data *d)
 {
-	struct hisi_pmic *pmic = irq_data_get_irq_chip_data(d);
+	struct hi6421_spmi_pmic *pmic = irq_data_get_irq_chip_data(d);
 	u32 data, offset;
 	unsigned long flags;
 
@@ -172,26 +174,26 @@ static void hisi_irq_unmask(struct irq_data *d)
 	offset += pmic->irq_mask_addr.start_addr;
 
 	spin_lock_irqsave(&pmic->lock, flags);
-	data = hisi_pmic_read(pmic, offset);
+	data = hi6421_spmi_pmic_read(pmic, offset);
 	data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
-	hisi_pmic_write(pmic, offset, data);
+	hi6421_spmi_pmic_write(pmic, offset, data);
 	spin_unlock_irqrestore(&pmic->lock, flags);
 }
 
-static struct irq_chip hisi_pmu_irqchip = {
+static struct irq_chip hi6421_spmi_pmu_irqchip = {
 	.name		= "hisi-irq",
-	.irq_mask	= hisi_irq_mask,
-	.irq_unmask	= hisi_irq_unmask,
-	.irq_disable	= hisi_irq_mask,
-	.irq_enable	= hisi_irq_unmask,
+	.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 hisi_irq_map(struct irq_domain *d, unsigned int virq,
+static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq,
 			irq_hw_number_t hw)
 {
-	struct hisi_pmic *pmic = d->host_data;
+	struct hi6421_spmi_pmic *pmic = d->host_data;
 
-	irq_set_chip_and_handler_name(virq, &hisi_pmu_irqchip,
+	irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip,
 				      handle_simple_irq, "hisi");
 	irq_set_chip_data(virq, pmic);
 	irq_set_irq_type(virq, IRQ_TYPE_NONE);
@@ -199,12 +201,13 @@ static int hisi_irq_map(struct irq_domain *d, unsigned int virq,
 	return 0;
 }
 
-static const struct irq_domain_ops hisi_domain_ops = {
-	.map	= hisi_irq_map,
+static const struct irq_domain_ops hi6421_spmi_domain_ops = {
+	.map	= hi6421_spmi_irq_map,
 	.xlate	= irq_domain_xlate_twocell,
 };
 
-static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *pmic)
+static int get_pmic_device_tree_data(struct device_node *np,
+				     struct hi6421_spmi_pmic *pmic)
 {
 	int ret = 0;
 
@@ -247,27 +250,29 @@ static int get_pmic_device_tree_data(struct device_node *np, struct hisi_pmic *p
 	return ret;
 }
 
-static void hisi_pmic_irq_prc(struct hisi_pmic *pmic)
+static void hi6421_spmi_pmic_irq_prc(struct hi6421_spmi_pmic *pmic)
 {
 	int i;
 
 	for (i = 0 ; i < pmic->irq_mask_addr.array; i++)
-		hisi_pmic_write(pmic, pmic->irq_mask_addr.start_addr + i, HISI_MASK_STATE);
+		hi6421_spmi_pmic_write(pmic, pmic->irq_mask_addr.start_addr + i,
+				       HISI_MASK_STATE);
 
 	for (i = 0 ; i < pmic->irq_addr.array; i++) {
-		unsigned int pending = hisi_pmic_read(pmic, pmic->irq_addr.start_addr + i);
+		unsigned int pending = hi6421_spmi_pmic_read(pmic, pmic->irq_addr.start_addr + i);
 
 		pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n",
 			 pmic->irq_addr.start_addr + i, pending);
-		hisi_pmic_write(pmic, pmic->irq_addr.start_addr + i, HISI_MASK_STATE);
+		hi6421_spmi_pmic_write(pmic, pmic->irq_addr.start_addr + i,
+				       HISI_MASK_STATE);
 	}
 }
 
-static int hisi_pmic_probe(struct spmi_device *pdev)
+static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
-	struct hisi_pmic *pmic = NULL;
+	struct hi6421_spmi_pmic *pmic = NULL;
 	enum of_gpio_flags flags;
 	int ret = 0;
 	int i;
@@ -305,14 +310,14 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 	pmic->irq = gpio_to_irq(pmic->gpio);
 
 	/* mask && clear IRQ status */
-	hisi_pmic_irq_prc(pmic);
+	hi6421_spmi_pmic_irq_prc(pmic);
 
 	pmic->irqs = devm_kzalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
 	if (!pmic->irqs)
 		goto irq_malloc;
 
 	pmic->domain = irq_domain_add_simple(np, pmic->irqnum, 0,
-					     &hisi_domain_ops, pmic);
+					     &hi6421_spmi_domain_ops, pmic);
 	if (!pmic->domain) {
 		dev_err(dev, "failed irq domain add simple!\n");
 		ret = -ENODEV;
@@ -330,7 +335,7 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 		pr_info("[%s]. pmic->irqs[%d] = %d\n", __func__, i, pmic->irqs[i]);
 	}
 
-	ret = request_threaded_irq(pmic->irq, hisi_irq_handler, NULL,
+	ret = request_threaded_irq(pmic->irq, hi6421_spmi_irq_handler, NULL,
 				   IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
 				   "pmic", pmic);
 	if (ret < 0) {
@@ -365,9 +370,9 @@ static int hisi_pmic_probe(struct spmi_device *pdev)
 	return ret;
 }
 
-static void hisi_pmic_remove(struct spmi_device *pdev)
+static void hi6421_spmi_pmic_remove(struct spmi_device *pdev)
 {
-	struct hisi_pmic *pmic = dev_get_drvdata(&pdev->dev);
+	struct hi6421_spmi_pmic *pmic = dev_get_drvdata(&pdev->dev);
 
 	free_irq(pmic->irq, pmic);
 	gpio_free(pmic->gpio);
@@ -380,15 +385,15 @@ static const struct of_device_id pmic_spmi_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
 
-static struct spmi_driver hisi_pmic_driver = {
+static struct spmi_driver hi6421_spmi_pmic_driver = {
 	.driver = {
 		.name	= "hi6421-spmi-pmic",
 		.of_match_table = pmic_spmi_id_table,
 	},
-	.probe	= hisi_pmic_probe,
-	.remove	= hisi_pmic_remove,
+	.probe	= hi6421_spmi_pmic_probe,
+	.remove	= hi6421_spmi_pmic_remove,
 };
-module_spmi_driver(hisi_pmic_driver);
+module_spmi_driver(hi6421_spmi_pmic_driver);
 
 MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
index 41b61de48259..d12ad7484018 100644
--- a/include/linux/mfd/hi6421-spmi-pmic.h
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -17,49 +17,36 @@
 #define HISI_ECO_MODE_ENABLE		(1)
 #define HISI_ECO_MODE_DISABLE		(0)
 
-typedef int (*pmic_ocp_callback)(char *);
-int hisi_pmic_special_ocp_register(char *power_name, pmic_ocp_callback handler);
-
-struct irq_mask_info {
+struct hi6421_spmi_irq_mask_info {
 	int start_addr;
 	int array;
 };
 
-struct irq_info {
+struct hi6421_spmi_irq_info {
 	int start_addr;
 	int array;
 };
 
-struct bit_info {
-	int addr;
-	int bit;
-};
-
-struct write_lock {
-	int addr;
-	int val;
-};
-
-struct hisi_pmic {
-	struct resource		*res;
-	struct device		*dev;
-	void __iomem		*regs;
-	spinlock_t		lock;
-	struct irq_domain	*domain;
-	int			irq;
-	int			gpio;
-	unsigned int		*irqs;
-	int			irqnum;
-	int			irqarray;
-	struct irq_mask_info 	irq_mask_addr;
-	struct irq_info		irq_addr;
+struct hi6421_spmi_pmic {
+	struct resource				*res;
+	struct device				*dev;
+	void __iomem				*regs;
+	spinlock_t				lock;
+	struct irq_domain			*domain;
+	int					irq;
+	int					gpio;
+	unsigned int				*irqs;
+	int					irqnum;
+	int					irqarray;
+	struct hi6421_spmi_irq_mask_info 	irq_mask_addr;
+	struct hi6421_spmi_irq_info		irq_addr;
 };
 
-u32 hisi_pmic_read(struct hisi_pmic *pmic, int reg);
-void hisi_pmic_write(struct hisi_pmic *pmic, int reg, u32 val);
-void hisi_pmic_rmw(struct hisi_pmic *pmic, int reg, u32 mask, u32 bits);
+u32 hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg);
+void hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val);
+void hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg, u32 mask, u32 bits);
 
-enum pmic_irq_list {
+enum hi6421_spmi_pmic_irq_list {
 	OTMP = 0,
 	VBUS_CONNECT,
 	VBUS_DISCONNECT,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 20/44] staging: mfd: hi6421-spmi-pmic: fix some coding style issues
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (18 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 19/44] staging: mfd: hi6421-spmi-pmic: change namespace on its functions Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 21/44] staging: mfd: hi6421-spmi-pmic: add it to the building system Mauro Carvalho Chehab
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
	linux-kernel, devel

Checkpatch complains about some minor issues inside this
driver that were not addressed by the previous patch.

Address them.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 4 ++--
 include/linux/mfd/hi6421-spmi-pmic.h        | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index 09cedfa1e4bb..d8b84d64041e 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -189,7 +189,7 @@ static struct irq_chip hi6421_spmi_pmu_irqchip = {
 };
 
 static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq,
-			irq_hw_number_t hw)
+			       irq_hw_number_t hw)
 {
 	struct hi6421_spmi_pmic *pmic = d->host_data;
 
@@ -350,7 +350,7 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
 	 * The logic below will rely that the pmic is already stored at
 	 * drvdata.
 	 */
-	dev_dbg(&pdev->dev, "SPMI-PMIC: adding childs for %pOF\n",
+	dev_dbg(&pdev->dev, "SPMI-PMIC: adding children for %pOF\n",
 		pdev->dev.of_node);
 	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
 				   hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs),
diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
index d12ad7484018..403fd8bb45fa 100644
--- a/include/linux/mfd/hi6421-spmi-pmic.h
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -38,7 +38,7 @@ struct hi6421_spmi_pmic {
 	unsigned int				*irqs;
 	int					irqnum;
 	int					irqarray;
-	struct hi6421_spmi_irq_mask_info 	irq_mask_addr;
+	struct hi6421_spmi_irq_mask_info	irq_mask_addr;
 	struct hi6421_spmi_irq_info		irq_addr;
 };
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 21/44] staging: mfd: hi6421-spmi-pmic: add it to the building system
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (19 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 20/44] staging: mfd: hi6421-spmi-pmic: fix some coding style issues Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 22/44] staging: mfd: hi6421-spmi-pmic: cleanup the code Mauro Carvalho Chehab
                   ` (24 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Now that the driver is ready, place it at the build system.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/Kconfig  | 17 +++++++++++++++++
 drivers/staging/hikey9xx/Makefile |  3 ++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig
index 31eb01b5ef2b..7ca083b7e94d 100644
--- a/drivers/staging/hikey9xx/Kconfig
+++ b/drivers/staging/hikey9xx/Kconfig
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
+# to be placed at drivers/spmi
 config SPMI_HISI3670
 	tristate "Hisilicon 3670 SPMI Controller"
 	select IRQ_DOMAIN_HIERARCHY
@@ -8,3 +9,19 @@ config SPMI_HISI3670
 	  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"
+	depends on OF
+	select MFD_CORE
+	select REGMAP_MMIO
+	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
index e8085abce444..79de37da7a8f 100644
--- a/drivers/staging/hikey9xx/Makefile
+++ b/drivers/staging/hikey9xx/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o
+obj-$(CONFIG_SPMI_HISI3670)	+= hisi-spmi-controller.o
+obj-$(CONFIG_MFD_HI6421_SPMI)	+= hi6421-spmi-pmic.o
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 22/44] staging: mfd: hi6421-spmi-pmic: cleanup the code
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (20 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 21/44] staging: mfd: hi6421-spmi-pmic: add it to the building system Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 23/44] staging: regulator: add a regulator driver for HiSilicon 6421v600 SPMI PMIC Mauro Carvalho Chehab
                   ` (23 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
	linux-kernel, devel, Jonathan Cameron

There are several small cleanups that can be done in order to
make the code more prepared to be upstreamed.

Suggested-by: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421-spmi-pmic.c | 151 +++++++++-----------
 include/linux/mfd/hi6421-spmi-pmic.h        |  12 +-
 2 files changed, 74 insertions(+), 89 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index d8b84d64041e..9d73458ca65a 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -17,26 +17,23 @@
  *
  */
 
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/mfd/core.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
+#include <linux/mfd/hi6421-spmi-pmic.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/of.h>
 #include <linux/of_irq.h>
-#include <linux/mfd/hi6421-spmi-pmic.h>
-#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/spmi.h>
-#ifndef NO_IRQ
-#define NO_IRQ       0
-#endif
 
 /* 8-bit register offset in PMIC */
 #define HISI_MASK_STATE			0xff
@@ -46,12 +43,11 @@
 #define HISI_IRQ_KEY_DOWN		7
 #define HISI_IRQ_KEY_UP			6
 
-/*#define HISI_NR_IRQ			25*/
-#define HISI_MASK_FIELD		0xFF
+#define HISI_MASK_FIELD			0xFF
 #define HISI_BITS			8
 
 /*define the first group interrupt register number*/
-#define HISI_PMIC_FIRST_GROUP_INT_NUM        2
+#define HISI_PMIC_FIRST_GROUP_INT_NUM	2
 
 static const struct mfd_cell hi6421v600_devs[] = {
 	{ .name = "hi6421v600-regulator", },
@@ -62,58 +58,60 @@ static const struct mfd_cell hi6421v600_devs[] = {
  * Hisilicon SoC use hardware to map PMIC register into SoC mapping.
  * At here, we are accessing SoC register with 32-bit.
  */
-u32 hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg)
+int hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg)
 {
-	u32 ret;
+	struct spmi_device *pdev;
 	u8 read_value = 0;
-	struct spmi_device *pdev;
+	u32 ret;
 
 	pdev = to_spmi_device(pmic->dev);
 	if (!pdev) {
 		pr_err("%s: pdev get failed!\n", __func__);
-		return 0;
+		return -ENODEV;
 	}
 
-	ret = spmi_ext_register_readl(pdev, reg,
-				      (unsigned char *)&read_value, 1);
+	ret = spmi_ext_register_readl(pdev, reg, &read_value, 1);
 	if (ret) {
 		pr_err("%s: spmi_ext_register_readl failed!\n", __func__);
-		return 0;
+		return ret;
 	}
-	return (u32)read_value;
+	return read_value;
 }
 EXPORT_SYMBOL(hi6421_spmi_pmic_read);
 
-void hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val)
+int hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val)
 {
-	u32 ret;
 	struct spmi_device *pdev;
+	u32 ret;
 
 	pdev = to_spmi_device(pmic->dev);
 	if (!pdev) {
 		pr_err("%s: pdev get failed!\n", __func__);
-		return;
+		return -ENODEV;
 	}
 
 	ret = spmi_ext_register_writel(pdev, reg, (unsigned char *)&val, 1);
-	if (ret) {
+	if (ret)
 		pr_err("%s: spmi_ext_register_writel failed!\n", __func__);
-		return;
-	}
+
+	return ret;
 }
 EXPORT_SYMBOL(hi6421_spmi_pmic_write);
 
-void hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg,
-			  u32 mask, u32 bits)
+int hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg,
+			 u32 mask, u32 bits)
 {
+	unsigned long flags;
 	u32 data;
-	unsigned long flags;
+	int ret;
 
 	spin_lock_irqsave(&pmic->lock, flags);
 	data = hi6421_spmi_pmic_read(pmic, reg) & ~mask;
 	data |= mask & bits;
-	hi6421_spmi_pmic_write(pmic, reg, data);
+	ret = hi6421_spmi_pmic_write(pmic, reg, data);
 	spin_unlock_irqrestore(&pmic->lock, flags);
+
+	return ret;
 }
 EXPORT_SYMBOL(hi6421_spmi_pmic_rmw);
 
@@ -124,16 +122,16 @@ static irqreturn_t hi6421_spmi_irq_handler(int irq, void *data)
 	int i, offset;
 
 	for (i = 0; i < pmic->irqarray; i++) {
-		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr.start_addr));
+		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr));
 		pending &= HISI_MASK_FIELD;
 		if (pending != 0)
 			pr_debug("pending[%d]=0x%lx\n\r", i, pending);
 
-		hi6421_spmi_pmic_write(pmic, (i + pmic->irq_addr.start_addr),
-				       pending);
+		hi6421_spmi_pmic_write(pmic, (i + pmic->irq_addr), pending);
 
 		/* solve powerkey order */
-		if ((i == HISI_IRQ_KEY_NUM) && ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
+		if ((i == HISI_IRQ_KEY_NUM) &&
+		    ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]);
 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]);
 			pending &= (~HISI_IRQ_KEY_VALUE);
@@ -155,7 +153,7 @@ static void hi6421_spmi_irq_mask(struct irq_data *d)
 	unsigned long flags;
 
 	offset = (irqd_to_hwirq(d) >> 3);
-	offset += pmic->irq_mask_addr.start_addr;
+	offset += pmic->irq_mask_addr;
 
 	spin_lock_irqsave(&pmic->lock, flags);
 	data = hi6421_spmi_pmic_read(pmic, offset);
@@ -171,7 +169,7 @@ static void hi6421_spmi_irq_unmask(struct irq_data *d)
 	unsigned long flags;
 
 	offset = (irqd_to_hwirq(d) >> 3);
-	offset += pmic->irq_mask_addr.start_addr;
+	offset += pmic->irq_mask_addr;
 
 	spin_lock_irqsave(&pmic->lock, flags);
 	data = hi6421_spmi_pmic_read(pmic, offset);
@@ -211,36 +209,32 @@ static int get_pmic_device_tree_data(struct device_node *np,
 {
 	int ret = 0;
 
-	/*get pmic irq num*/
-	ret = of_property_read_u32_array(np, "irq-num",
-					 &pmic->irqnum, 1);
+	/* IRQ number */
+	ret = of_property_read_u32(np, "irq-num", &pmic->irqnum);
 	if (ret) {
 		pr_err("no irq-num property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
-	/*get pmic irq array number*/
-	ret = of_property_read_u32_array(np, "irq-array",
-					 &pmic->irqarray, 1);
+	/* Size of IRQ array */
+	ret = of_property_read_u32(np, "irq-array", &pmic->irqarray);
 	if (ret) {
 		pr_err("no irq-array property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
-	/*SOC_PMIC_IRQ_MASK_0_ADDR*/
-	ret = of_property_read_u32_array(np, "irq-mask-addr",
-					 (int *)&pmic->irq_mask_addr, 2);
+	/* SOC_PMIC_IRQ_MASK_0_ADDR */
+	ret = of_property_read_u32(np, "irq-mask-addr", &pmic->irq_mask_addr);
 	if (ret) {
 		pr_err("no irq-mask-addr property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 
-	/*SOC_PMIC_IRQ0_ADDR*/
-	ret = of_property_read_u32_array(np, "irq-addr",
-					 (int *)&pmic->irq_addr, 2);
+	/* SOC_PMIC_IRQ0_ADDR */
+	ret = of_property_read_u32(np, "irq-addr", &pmic->irq_addr);
 	if (ret) {
 		pr_err("no irq-addr property set\n");
 		ret = -ENODEV;
@@ -252,18 +246,18 @@ static int get_pmic_device_tree_data(struct device_node *np,
 
 static void hi6421_spmi_pmic_irq_prc(struct hi6421_spmi_pmic *pmic)
 {
-	int i;
+	int i, pending;
 
-	for (i = 0 ; i < pmic->irq_mask_addr.array; i++)
-		hi6421_spmi_pmic_write(pmic, pmic->irq_mask_addr.start_addr + i,
+	for (i = 0 ; i < pmic->irqarray; i++)
+		hi6421_spmi_pmic_write(pmic, pmic->irq_mask_addr + i,
 				       HISI_MASK_STATE);
 
-	for (i = 0 ; i < pmic->irq_addr.array; i++) {
-		unsigned int pending = hi6421_spmi_pmic_read(pmic, pmic->irq_addr.start_addr + i);
+	for (i = 0 ; i < pmic->irqarray; i++) {
+		pending = hi6421_spmi_pmic_read(pmic, pmic->irq_addr + i);
 
 		pr_debug("PMU IRQ address value:irq[0x%x] = 0x%x\n",
-			 pmic->irq_addr.start_addr + i, pending);
-		hi6421_spmi_pmic_write(pmic, pmic->irq_addr.start_addr + i,
+			 pmic->irq_addr + i, pending);
+		hi6421_spmi_pmic_write(pmic, pmic->irq_addr + i,
 				       HISI_MASK_STATE);
 	}
 }
@@ -272,36 +266,32 @@ 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 *pmic = NULL;
-	enum of_gpio_flags flags;
-	int ret = 0;
-	int i;
+	struct hi6421_spmi_pmic *pmic;
 	unsigned int virq;
+	int ret, i;
 
 	pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
 	if (!pmic)
 		return -ENOMEM;
 
-	/*TODO: get pmic dts info*/
 	ret = get_pmic_device_tree_data(np, pmic);
 	if (ret) {
-		dev_err(&pdev->dev, "Error reading hisi pmic dts\n");
+		dev_err(dev, "Error reading hisi pmic dts\n");
 		return ret;
 	}
 
-	/* TODO: get and enable clk request */
 	spin_lock_init(&pmic->lock);
 
 	pmic->dev = dev;
 
-	pmic->gpio = of_get_gpio_flags(np, 0, &flags);
+	pmic->gpio = of_get_gpio(np, 0);
 	if (pmic->gpio < 0)
 		return pmic->gpio;
 
 	if (!gpio_is_valid(pmic->gpio))
 		return -EINVAL;
 
-	ret = gpio_request_one(pmic->gpio, GPIOF_IN, "pmic");
+	ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN, "pmic");
 	if (ret < 0) {
 		dev_err(dev, "failed to request gpio%d\n", pmic->gpio);
 		return ret;
@@ -309,7 +299,6 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
 
 	pmic->irq = gpio_to_irq(pmic->gpio);
 
-	/* mask && clear IRQ status */
 	hi6421_spmi_pmic_irq_prc(pmic);
 
 	pmic->irqs = devm_kzalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
@@ -321,27 +310,27 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
 	if (!pmic->domain) {
 		dev_err(dev, "failed irq domain add simple!\n");
 		ret = -ENODEV;
-		goto irq_domain;
+		goto irq_malloc;
 	}
 
 	for (i = 0; i < pmic->irqnum; i++) {
 		virq = irq_create_mapping(pmic->domain, i);
-		if (virq == NO_IRQ) {
-			pr_debug("Failed mapping hwirq\n");
+		if (!virq) {
+			dev_err(dev, "Failed mapping hwirq\n");
 			ret = -ENOSPC;
-			goto irq_create_mapping;
+			goto irq_malloc;
 		}
 		pmic->irqs[i] = virq;
-		pr_info("[%s]. pmic->irqs[%d] = %d\n", __func__, i, pmic->irqs[i]);
+		dev_dbg(dev, "%s: pmic->irqs[%d] = %d\n",
+			__func__, i, pmic->irqs[i]);
 	}
 
 	ret = request_threaded_irq(pmic->irq, hi6421_spmi_irq_handler, NULL,
 				   IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
 				   "pmic", pmic);
 	if (ret < 0) {
-		dev_err(dev, "could not claim pmic %d\n", ret);
-		ret = -ENODEV;
-		goto request_theaded_irq;
+		dev_err(dev, "could not claim pmic IRQ: error %d\n", ret);
+		goto irq_malloc;
 	}
 
 	dev_set_drvdata(&pdev->dev, pmic);
@@ -355,18 +344,14 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
 	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
 				   hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs),
 				   NULL, 0, NULL);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);
-		return ret;
-	}
+	if (!ret)
+		return 0;
 
-	return 0;
+	dev_err(dev, "Failed to add child devices: %d\n", ret);
 
-request_theaded_irq:
-irq_create_mapping:
-irq_domain:
 irq_malloc:
-	gpio_free(pmic->gpio);
+	free_irq(pmic->irq, pmic);
+
 	return ret;
 }
 
@@ -375,8 +360,6 @@ static void hi6421_spmi_pmic_remove(struct spmi_device *pdev)
 	struct hi6421_spmi_pmic *pmic = dev_get_drvdata(&pdev->dev);
 
 	free_irq(pmic->irq, pmic);
-	gpio_free(pmic->gpio);
-	devm_kfree(&pdev->dev, pmic);
 }
 
 static const struct of_device_id pmic_spmi_id_table[] = {
diff --git a/include/linux/mfd/hi6421-spmi-pmic.h b/include/linux/mfd/hi6421-spmi-pmic.h
index 403fd8bb45fa..ff3adfa7b3ec 100644
--- a/include/linux/mfd/hi6421-spmi-pmic.h
+++ b/include/linux/mfd/hi6421-spmi-pmic.h
@@ -36,15 +36,17 @@ struct hi6421_spmi_pmic {
 	int					irq;
 	int					gpio;
 	unsigned int				*irqs;
+
 	int					irqnum;
 	int					irqarray;
-	struct hi6421_spmi_irq_mask_info	irq_mask_addr;
-	struct hi6421_spmi_irq_info		irq_addr;
+	int					irq_mask_addr;
+	int					irq_addr;
 };
 
-u32 hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg);
-void hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val);
-void hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg, u32 mask, u32 bits);
+int hi6421_spmi_pmic_read(struct hi6421_spmi_pmic *pmic, int reg);
+int hi6421_spmi_pmic_write(struct hi6421_spmi_pmic *pmic, int reg, u32 val);
+int hi6421_spmi_pmic_rmw(struct hi6421_spmi_pmic *pmic, int reg,
+			 u32 mask, u32 bits);
 
 enum hi6421_spmi_pmic_irq_list {
 	OTMP = 0,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 23/44] staging: regulator: add a regulator driver for HiSilicon 6421v600 SPMI PMIC
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (21 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 22/44] staging: mfd: hi6421-spmi-pmic: cleanup the code Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 24/44] staging: regulator: hi6421v600-regulator: get rid of unused code Mauro Carvalho Chehab
                   ` (22 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mayulong, Mauro Carvalho Chehab,
	linux-kernel, devel

From: Mayulong <mayulong1@huawei.com>

Add the regulator driver for the LDO lines provided by the
HiSilicon 6421v600 SPMI PMIC device.

[mchehab+huawei@kernel.org: keep just the regulator driver on this patch,
 renaming it to better fit at upstream namespace]

The compete patch is at:
	https://github.com/96boards-hikey/linux/commit/08464419fba2

Signed-off-by: Mayulong <mayulong1@huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 741 ++++++++++++++++++
 1 file changed, 741 insertions(+)
 create mode 100644 drivers/staging/hikey9xx/hi6421v600-regulator.c

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
new file mode 100644
index 000000000000..941bfe32bf5b
--- /dev/null
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -0,0 +1,741 @@
+/*
+ * Device driver for regulators in Hisi IC
+ *
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2011 Hisilicon.
+ *
+ * Guodong Xu <guodong.xu@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/mfd/hisi_pmic.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/version.h>
+#ifdef CONFIG_HISI_PMIC_DEBUG
+#include <linux/debugfs.h>
+#endif
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/spmi.h>
+
+#if 1
+#define BRAND_DEBUG(args...) pr_debug(args);
+#else
+#define BRAND_DEBUG(args...)
+#endif
+
+struct hisi_regulator_register_info {
+	u32 ctrl_reg;
+	u32 enable_mask;
+	u32 eco_mode_mask;
+	u32 vset_reg;
+	u32 vset_mask;
+};
+
+struct hisi_regulator {
+	const char *name;
+	struct hisi_regulator_register_info register_info;
+	struct timeval last_off_time;
+	u32 off_on_delay;
+	u32 eco_uA;
+	struct regulator_desc rdesc;
+	int (*dt_parse)(struct hisi_regulator *, struct spmi_device *);
+};
+
+static DEFINE_MUTEX(enable_mutex);
+struct timeval last_enabled;
+
+
+static inline struct hisi_pmic *rdev_to_pmic(struct regulator_dev *dev)
+{
+	/* regulator_dev parent to->
+	 * hisi regulator platform device_dev parent to->
+	 * hisi pmic platform device_dev
+	 */
+	return dev_get_drvdata(rdev_get_dev(dev)->parent->parent);
+}
+
+/* helper function to ensure when it returns it is at least 'delay_us'
+ * microseconds after 'since'.
+ */
+static void ensured_time_after(struct timeval since, u32 delay_us)
+{
+	struct timeval now;
+	u64 elapsed_ns64, delay_ns64;
+	u32 actual_us32;
+
+	delay_ns64 = delay_us * NSEC_PER_USEC;
+	do_gettimeofday(&now);
+	elapsed_ns64 = timeval_to_ns(&now) - timeval_to_ns(&since);
+	if (delay_ns64 > elapsed_ns64) {
+		actual_us32 = ((u32)(delay_ns64 - elapsed_ns64) /
+							NSEC_PER_USEC);
+		if (actual_us32 >= 1000) {
+			mdelay(actual_us32 / 1000); /*lint !e647 */
+			udelay(actual_us32 % 1000);
+		} else if (actual_us32 > 0) {
+			udelay(actual_us32);
+		}
+	}
+	return;
+}
+
+static int hisi_regulator_is_enabled(struct regulator_dev *dev)
+{
+	u32 reg_val;
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+
+	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
+	BRAND_DEBUG("<[%s]: ctrl_reg=0x%x,enable_state=%d>\n", __func__, sreg->register_info.ctrl_reg,\
+			(reg_val & sreg->register_info.enable_mask));
+
+	return ((reg_val & sreg->register_info.enable_mask) != 0);
+}
+
+static int hisi_regulator_enable(struct regulator_dev *dev)
+{
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+
+	/* keep a distance of off_on_delay from last time disabled */
+	ensured_time_after(sreg->last_off_time, sreg->off_on_delay);
+
+	BRAND_DEBUG("<[%s]: off_on_delay=%dus>\n", __func__, sreg->off_on_delay);
+
+	/* cannot enable more than one regulator at one time */
+	mutex_lock(&enable_mutex);
+	ensured_time_after(last_enabled, HISI_REGS_ENA_PROTECT_TIME);
+
+	/* set enable register */
+	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
+				sreg->register_info.enable_mask,
+				sreg->register_info.enable_mask);
+	BRAND_DEBUG("<[%s]: ctrl_reg=0x%x,enable_mask=0x%x>\n", __func__, sreg->register_info.ctrl_reg,\
+			sreg->register_info.enable_mask);
+
+	do_gettimeofday(&last_enabled);
+	mutex_unlock(&enable_mutex);
+
+	return 0;
+}
+
+static int hisi_regulator_disable(struct regulator_dev *dev)
+{
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+
+	/* set enable register to 0 */
+	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
+				sreg->register_info.enable_mask, 0);
+
+	do_gettimeofday(&sreg->last_off_time);
+
+	return 0;
+}
+
+static int hisi_regulator_get_voltage(struct regulator_dev *dev)
+{
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	u32 reg_val, selector;
+
+	/* get voltage selector */
+	reg_val = hisi_pmic_read(pmic, sreg->register_info.vset_reg);
+	BRAND_DEBUG("<[%s]: vset_reg=0x%x>\n", __func__, sreg->register_info.vset_reg);
+
+	selector = (reg_val & sreg->register_info.vset_mask) >>
+				(ffs(sreg->register_info.vset_mask) - 1);
+
+	return sreg->rdesc.ops->list_voltage(dev, selector);
+}
+
+static int hisi_regulator_set_voltage(struct regulator_dev *dev,
+				int min_uV, int max_uV, unsigned *selector)
+{
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	u32 vsel;
+	int ret = 0;
+
+	for (vsel = 0; vsel < sreg->rdesc.n_voltages; vsel++) {
+		int uV = sreg->rdesc.volt_table[vsel];
+		/* Break at the first in-range value */
+		if (min_uV <= uV && uV <= max_uV)
+			break;
+	}
+
+	/* unlikely to happen. sanity test done by regulator core */
+	if (unlikely(vsel == sreg->rdesc.n_voltages))
+		return -EINVAL;
+
+	*selector = vsel;
+	/* set voltage selector */
+	hisi_pmic_rmw(pmic, sreg->register_info.vset_reg,
+		sreg->register_info.vset_mask,
+		vsel << (ffs(sreg->register_info.vset_mask) - 1));
+
+	BRAND_DEBUG("<[%s]: vset_reg=0x%x, vset_mask=0x%x, value=0x%x>\n", __func__,\
+			sreg->register_info.vset_reg,\
+			sreg->register_info.vset_mask,\
+			vsel << (ffs(sreg->register_info.vset_mask) - 1)\
+			);
+
+	return ret;
+}
+
+static unsigned int hisi_regulator_get_mode(struct regulator_dev *dev)
+{
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	u32 reg_val;
+
+	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
+	BRAND_DEBUG("<[%s]: reg_val=%d, ctrl_reg=0x%x, eco_mode_mask=0x%x>\n", __func__, reg_val,\
+			sreg->register_info.ctrl_reg,\
+			sreg->register_info.eco_mode_mask\
+		   );
+
+	if (reg_val & sreg->register_info.eco_mode_mask)
+		return REGULATOR_MODE_IDLE;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int hisi_regulator_set_mode(struct regulator_dev *dev,
+						unsigned int mode)
+{
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	u32 eco_mode;
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		eco_mode = HISI_ECO_MODE_DISABLE;
+		break;
+	case REGULATOR_MODE_IDLE:
+		eco_mode = HISI_ECO_MODE_ENABLE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set mode */
+	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
+		sreg->register_info.eco_mode_mask,
+		eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1));
+
+	BRAND_DEBUG("<[%s]: ctrl_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n", __func__,\
+			sreg->register_info.ctrl_reg,\
+			sreg->register_info.eco_mode_mask,\
+			eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1)\
+		   );
+	return 0;
+}
+
+
+unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *dev,
+			int input_uV, int output_uV, int load_uA)
+{
+	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+
+	if ((load_uA == 0) || ((unsigned int)load_uA > sreg->eco_uA))
+		return REGULATOR_MODE_NORMAL;
+	else
+		return REGULATOR_MODE_IDLE;
+}
+
+static int hisi_dt_parse_common(struct hisi_regulator *sreg,
+					struct spmi_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct regulator_desc *rdesc = &sreg->rdesc;
+	unsigned int register_info[3] = {0};
+	int ret = 0;
+
+	/* parse .register_info.ctrl_reg */
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-ctrl",
+						register_info, 3);
+	if (ret) {
+		dev_err(dev, "no hisilicon,hisi-ctrl property set\n");
+		goto dt_parse_common_end;
+	}
+	sreg->register_info.ctrl_reg = register_info[0];
+	sreg->register_info.enable_mask = register_info[1];
+	sreg->register_info.eco_mode_mask = register_info[2];
+
+	/* parse .register_info.vset_reg */
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset",
+						register_info, 2);
+	if (ret) {
+		dev_err(dev, "no hisilicon,hisi-vset property set\n");
+		goto dt_parse_common_end;
+	}
+	sreg->register_info.vset_reg = register_info[0];
+	sreg->register_info.vset_mask = register_info[1];
+
+	/* parse .off-on-delay */
+	ret = of_property_read_u32(np, "hisilicon,hisi-off-on-delay-us",
+						&sreg->off_on_delay);
+	if (ret) {
+		dev_err(dev, "no hisilicon,hisi-off-on-delay-us property set\n");
+		goto dt_parse_common_end;
+	}
+
+	/* parse .enable_time */
+	ret = of_property_read_u32(np, "hisilicon,hisi-enable-time-us",
+				   &rdesc->enable_time);
+	if (ret) {
+		dev_err(dev, "no hisilicon,hisi-enable-time-us property set\n");
+		goto dt_parse_common_end;
+	}
+
+	/* parse .eco_uA */
+	ret = of_property_read_u32(np, "hisilicon,hisi-eco-microamp",
+				   &sreg->eco_uA);
+	if (ret) {
+		sreg->eco_uA = 0;
+		ret = 0;
+	}
+
+dt_parse_common_end:
+	return ret;
+}
+
+static int hisi_dt_parse_ldo(struct hisi_regulator *sreg,
+				struct spmi_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct regulator_desc *rdesc = &sreg->rdesc;
+	unsigned int *v_table;
+	int ret = 0;
+
+	/* parse .n_voltages, and .volt_table */
+	ret = of_property_read_u32(np, "hisilicon,hisi-n-voltages",
+				   &rdesc->n_voltages);
+	if (ret) {
+		dev_err(dev, "no hisilicon,hisi-n-voltages property set\n");
+		goto dt_parse_ldo_end;
+	}
+
+	/* alloc space for .volt_table */
+	v_table = devm_kzalloc(dev, sizeof(unsigned int) * rdesc->n_voltages,
+								GFP_KERNEL);
+	if (unlikely(!v_table)) {
+		ret = -ENOMEM;
+		dev_err(dev, "no memory for .volt_table\n");
+		goto dt_parse_ldo_end;
+	}
+
+	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset-table",
+						v_table, rdesc->n_voltages);
+	if (ret) {
+		dev_err(dev, "no hisilicon,hisi-vset-table property set\n");
+		goto dt_parse_ldo_end1;
+	}
+	rdesc->volt_table = v_table;
+
+	/* parse hisi regulator's dt common part */
+	ret = hisi_dt_parse_common(sreg, pdev);
+	if (ret) {
+		dev_err(dev, "failure in hisi_dt_parse_common\n");
+		goto dt_parse_ldo_end1;
+	}
+
+	return ret;
+
+dt_parse_ldo_end1:
+dt_parse_ldo_end:
+	return ret;
+}
+
+static struct regulator_ops hisi_ldo_rops = {
+	.is_enabled = hisi_regulator_is_enabled,
+	.enable = hisi_regulator_enable,
+	.disable = hisi_regulator_disable,
+	.list_voltage = regulator_list_voltage_table,
+	.get_voltage = hisi_regulator_get_voltage,
+	.set_voltage = hisi_regulator_set_voltage,
+	.get_mode = hisi_regulator_get_mode,
+	.set_mode = hisi_regulator_set_mode,
+	.get_optimum_mode = hisi_regulator_get_optimum_mode,
+};
+
+static const struct hisi_regulator hisi_regulator_ldo = {
+	.rdesc = {
+	.ops = &hisi_ldo_rops,
+		.type = REGULATOR_VOLTAGE,
+		.owner = THIS_MODULE,
+		},
+	.dt_parse = hisi_dt_parse_ldo,
+};
+
+static struct of_device_id of_hisi_regulator_match_tbl[] = {
+	{
+		.compatible = "hisilicon-hisi-ldo",
+		.data = &hisi_regulator_ldo,
+	},
+	{ /* end */ }
+};
+
+#ifdef CONFIG_HISI_PMIC_DEBUG
+extern void get_current_regulator_dev(struct seq_file *s);
+extern void set_regulator_state(char *ldo_name, int value);
+extern void get_regulator_state(char *ldo_name);
+extern int set_regulator_voltage(char *ldo_name, unsigned int vol_value);
+
+u32 pmu_atoi(char *s)
+{
+	char *p = s;
+	char c;
+	u64 ret = 0;
+	if (s == NULL)
+		return 0;
+	while ((c = *p++) != '\0') {
+		if ('0' <= c && c <= '9') {
+			ret *= 10;
+			ret += (u64)((unsigned char)c - '0');
+			if (ret > U32_MAX)
+				return 0;
+		} else {
+			break;
+		}
+	}
+	return (u32)ret;
+}
+static int dbg_hisi_regulator_show(struct seq_file *s, void *data)
+{
+	seq_printf(s, "\n\r");
+	seq_printf(s, "%-13s %-15s %-15s %-15s %-15s\n\r",
+			"LDO_NAME", "ON/OFF", "Use_count", "Open_count", "Always_on");
+	seq_printf(s, "-----------------------------------------"
+			"-----------------------------------------------\n\r");
+	get_current_regulator_dev(s);
+	return 0;
+}
+
+static int dbg_hisi_regulator_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dbg_hisi_regulator_show, inode->i_private);
+}
+
+static const struct file_operations debug_regulator_state_fops = {
+	.open		= dbg_hisi_regulator_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int dbg_control_regulator_show(struct seq_file *s, void *data)
+{
+	printk("                                                                             \n\r \
+		---------------------------------------------------------------------------------\n\r \
+		|usage:                                                                         |\n\r \
+		|	S = state	R = read	V = voltage                                         |\n\r \
+		|	set ldo state and voltage                                                   |\n\r \
+		|	get ldo state and current voltage                                           |\n\r \
+		|example:                                                                       |\n\r \
+		|	echo S ldo16 0   > control_regulator	:disable ldo16                      |\n\r \
+		|	echo S ldo16 1   > control_regulator	:enable ldo16                       |\n\r \
+		|	echo R ldo16     > control_regulator	:get ldo16 state and voltage        |\n\r \
+		|	echo V ldo16 xxx > control_regulator	:set ldo16 voltage                  |\n\r \
+		---------------------------------------------------------------------------------\n\r");
+	return 0;
+}
+static ssize_t dbg_control_regulator_set_value(struct file *filp, const char __user *buffer,
+	size_t count, loff_t *ppos)
+{
+	char tmp[128] = {0};
+	char ptr[128] = {0};
+	char *vol = NULL;
+	char num = 0;
+	unsigned int i;
+	int next_flag = 1;
+
+	if (count >= 128) {
+		pr_info("error! buffer size big than internal buffer\n");
+		return -EFAULT;
+	}
+
+	if (copy_from_user(tmp, buffer, count)) {
+		pr_info("error!\n");
+		return -EFAULT;
+	}
+
+	if (tmp[0] == 'R' || tmp[0] == 'r') {
+		for (i = 2; i < (count - 1); i++) {
+			ptr[i - 2] = tmp[i];
+		}
+		ptr[i - 2] = '\0';
+		get_regulator_state(ptr);
+	} else if (tmp[0] == 'S' || tmp[0] == 's') {
+		for (i = 2; i < (count - 1); i++) {
+			if (tmp[i] == ' ') {
+				next_flag = 0;
+				ptr[i - 2] = '\0';
+				continue;
+			}
+			if (next_flag) {
+				ptr[i - 2] = tmp[i];
+			} else {
+				num = tmp[i] - 48;
+			}
+		}
+		set_regulator_state(ptr, num);
+	} else if (tmp[0] == 'V' || tmp[0] == 'v') {
+		for (i = 2; i < (count - 1); i++) {
+			if (tmp[i] == ' ') {
+				next_flag = 0;
+				ptr[i - 2] = '\0';
+				continue;
+			}
+			if (next_flag) {
+				ptr[i - 2] = tmp[i];
+			} else {
+				vol = &tmp[i];
+				break;
+			}
+		}
+		set_regulator_voltage(ptr, pmu_atoi(vol));
+	}
+
+	*ppos += count;
+
+	return count;
+}
+
+static int dbg_control_regulator_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return single_open(file, dbg_control_regulator_show, &inode->i_private);
+}
+
+static const struct file_operations set_control_regulator_fops = {
+	.open		= dbg_control_regulator_open,
+	.read		= seq_read,
+	.write		= dbg_control_regulator_set_value,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+#endif
+
+static int hisi_regulator_probe(struct spmi_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct regulator_desc *rdesc;
+	struct regulator_dev *rdev;
+	struct hisi_regulator *sreg = NULL;
+	struct regulator_init_data *initdata;
+	struct regulator_config config = { };
+	const struct of_device_id *match;
+	struct regulation_constraints *constraint;
+	const char *supplyname = NULL;
+#ifdef CONFIG_HISI_PMIC_DEBUG
+	struct dentry *d;
+	static int debugfs_flag;
+#endif
+	unsigned int temp_modes;
+
+	const struct hisi_regulator *template = NULL;
+	int ret = 0;
+	/* to check which type of regulator this is */
+	match = of_match_device(of_hisi_regulator_match_tbl, &pdev->dev);
+	if (NULL == match) {
+		pr_err("get hisi regulator fail!\n\r");
+		return -EINVAL;
+	}
+
+	template = match->data;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0))
+	initdata = of_get_regulator_init_data(dev, np, NULL);
+#else
+	initdata = of_get_regulator_init_data(dev, np);
+#endif
+	if (NULL == initdata) {
+		pr_err("get regulator init data error !\n");
+		return -EINVAL;
+	}
+
+	/* hisi regulator supports two modes */
+	constraint = &initdata->constraints;
+
+	ret = of_property_read_u32_array(np, "hisilicon,valid-modes-mask",
+						&(constraint->valid_modes_mask), 1);
+	if (ret) {
+		pr_err("no hisilicon,valid-modes-mask property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+	ret = of_property_read_u32_array(np, "hisilicon,valid-idle-mask",
+						&temp_modes, 1);
+	if (ret) {
+		pr_err("no hisilicon,valid-modes-mask property set\n");
+		ret = -ENODEV;
+		return ret;
+	}
+	constraint->valid_ops_mask |= temp_modes;
+
+	sreg = kmemdup(template, sizeof(*sreg), GFP_KERNEL);
+	if (!sreg) {
+		pr_err("template kememdup is fail. \n");
+		return -ENOMEM;
+	}
+	sreg->name = initdata->constraints.name;
+	rdesc = &sreg->rdesc;
+	rdesc->name = sreg->name;
+	rdesc->min_uV = initdata->constraints.min_uV;
+	supplyname = of_get_property(np, "hisilicon,supply_name", NULL);
+	if (supplyname != NULL) {
+		initdata->supply_regulator = supplyname;
+	}
+
+	/* to parse device tree data for regulator specific */
+	ret = sreg->dt_parse(sreg, pdev);
+	if (ret) {
+		dev_err(dev, "device tree parameter parse error!\n");
+		goto hisi_probe_end;
+	}
+
+	config.dev = &pdev->dev;
+	config.init_data = initdata;
+	config.driver_data = sreg;
+	config.of_node = pdev->dev.of_node;
+
+	/* register regulator */
+	rdev = regulator_register(rdesc, &config);
+	if (IS_ERR(rdev)) {
+		dev_err(dev, "failed to register %s\n",
+			rdesc->name);
+		ret = PTR_ERR(rdev);
+		goto hisi_probe_end;
+	}
+
+	BRAND_DEBUG("[%s]:valid_modes_mask[0x%x], valid_ops_mask[0x%x]\n", rdesc->name,\
+			constraint->valid_modes_mask, constraint->valid_ops_mask);
+
+	dev_set_drvdata(dev, rdev);
+#ifdef CONFIG_HISI_PMIC_DEBUG
+	if (debugfs_flag == 0) {
+		d = debugfs_create_dir("hisi_regulator_debugfs", NULL);
+		if (!d) {
+			dev_err(dev, "failed to create hisi regulator debugfs dir !\n");
+			ret = -ENOMEM;
+			goto hisi_probe_fail;
+		}
+		(void) debugfs_create_file("regulator_state", S_IRUSR,
+						d, NULL, &debug_regulator_state_fops);
+
+		(void) debugfs_create_file("control_regulator", S_IRUSR,
+						d, NULL, &set_control_regulator_fops);
+		debugfs_flag = 1;
+	}
+#endif
+
+#ifdef CONFIG_HISI_PMIC_DEBUG
+hisi_probe_fail:
+	if (ret)
+		regulator_unregister(rdev);
+#endif
+hisi_probe_end:
+	if (ret)
+		kfree(sreg);
+	return ret;
+}
+
+static void hisi_regulator_remove(struct spmi_device *pdev)
+{
+	struct regulator_dev *rdev = dev_get_drvdata(&pdev->dev);
+	struct hisi_regulator *sreg = rdev_get_drvdata(rdev);
+
+	regulator_unregister(rdev);
+
+	/* TODO: should i worry about that? devm_kzalloc */
+	if (sreg->rdesc.volt_table)
+		devm_kfree(&pdev->dev, (unsigned int *)sreg->rdesc.volt_table);
+
+	kfree(sreg);
+}
+static int hisi_regulator_suspend(struct device *dev, pm_message_t state)
+{
+	struct hisi_regulator *hisi_regulator = dev_get_drvdata(dev);
+
+	if (NULL == hisi_regulator) {
+		pr_err("%s:regulator is NULL\n", __func__);
+		return -ENOMEM;
+	}
+
+	pr_info("%s:+\n", __func__);
+	pr_info("%s:-\n", __func__);
+
+	return 0;
+}/*lint !e715 */
+
+static int hisi_regulator_resume(struct device *dev)
+{
+	struct hisi_regulator *hisi_regulator = dev_get_drvdata(dev);
+
+	if (NULL == hisi_regulator) {
+		pr_err("%s:regulator is NULL\n", __func__);
+		return -ENOMEM;
+	}
+
+	pr_info("%s:+\n", __func__);
+	pr_info("%s:-\n", __func__);
+
+	return 0;
+}
+
+static struct spmi_driver hisi_pmic_driver = {
+	.driver = {
+		.name	= "hisi_regulator",
+		.owner  = THIS_MODULE,
+		.of_match_table = of_hisi_regulator_match_tbl,
+		.suspend = hisi_regulator_suspend,
+		.resume = hisi_regulator_resume,
+	},
+	.probe	= hisi_regulator_probe,
+	.remove	= hisi_regulator_remove,
+};
+
+static int __init hisi_regulator_init(void)
+{
+	return spmi_driver_register(&hisi_pmic_driver);
+}
+
+static void __exit hisi_regulator_exit(void)
+{
+	spmi_driver_unregister(&hisi_pmic_driver);
+}
+
+fs_initcall(hisi_regulator_init);
+module_exit(hisi_regulator_exit);
+
+MODULE_DESCRIPTION("Hisi regulator driver");
+MODULE_LICENSE("GPL v2");
+
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 24/44] staging: regulator: hi6421v600-regulator: get rid of unused code
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (22 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 23/44] staging: regulator: add a regulator driver for HiSilicon 6421v600 SPMI PMIC Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 25/44] staging: regulator: hi6421v600-regulator: port it to upstream Mauro Carvalho Chehab
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Get rid of the sysfs code and other parts of the driver
which aren't needed upstream.

If needed later, this patch can be (partially?) reversed.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 196 +-----------------
 1 file changed, 8 insertions(+), 188 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 941bfe32bf5b..7bc0ae27b110 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -34,19 +34,10 @@
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/version.h>
-#ifdef CONFIG_HISI_PMIC_DEBUG
-#include <linux/debugfs.h>
-#endif
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/spmi.h>
 
-#if 1
-#define BRAND_DEBUG(args...) pr_debug(args);
-#else
-#define BRAND_DEBUG(args...)
-#endif
-
 struct hisi_regulator_register_info {
 	u32 ctrl_reg;
 	u32 enable_mask;
@@ -110,7 +101,7 @@ static int hisi_regulator_is_enabled(struct regulator_dev *dev)
 	struct hisi_pmic *pmic = rdev_to_pmic(dev);
 
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
-	BRAND_DEBUG("<[%s]: ctrl_reg=0x%x,enable_state=%d>\n", __func__, sreg->register_info.ctrl_reg,\
+	pr_debug("<[%s]: ctrl_reg=0x%x,enable_state=%d>\n", __func__, sreg->register_info.ctrl_reg,\
 			(reg_val & sreg->register_info.enable_mask));
 
 	return ((reg_val & sreg->register_info.enable_mask) != 0);
@@ -124,7 +115,7 @@ static int hisi_regulator_enable(struct regulator_dev *dev)
 	/* keep a distance of off_on_delay from last time disabled */
 	ensured_time_after(sreg->last_off_time, sreg->off_on_delay);
 
-	BRAND_DEBUG("<[%s]: off_on_delay=%dus>\n", __func__, sreg->off_on_delay);
+	pr_debug("<[%s]: off_on_delay=%dus>\n", __func__, sreg->off_on_delay);
 
 	/* cannot enable more than one regulator at one time */
 	mutex_lock(&enable_mutex);
@@ -134,7 +125,7 @@ static int hisi_regulator_enable(struct regulator_dev *dev)
 	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
 				sreg->register_info.enable_mask,
 				sreg->register_info.enable_mask);
-	BRAND_DEBUG("<[%s]: ctrl_reg=0x%x,enable_mask=0x%x>\n", __func__, sreg->register_info.ctrl_reg,\
+	pr_debug("<[%s]: ctrl_reg=0x%x,enable_mask=0x%x>\n", __func__, sreg->register_info.ctrl_reg,\
 			sreg->register_info.enable_mask);
 
 	do_gettimeofday(&last_enabled);
@@ -165,7 +156,7 @@ static int hisi_regulator_get_voltage(struct regulator_dev *dev)
 
 	/* get voltage selector */
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.vset_reg);
-	BRAND_DEBUG("<[%s]: vset_reg=0x%x>\n", __func__, sreg->register_info.vset_reg);
+	pr_debug("<[%s]: vset_reg=0x%x>\n", __func__, sreg->register_info.vset_reg);
 
 	selector = (reg_val & sreg->register_info.vset_mask) >>
 				(ffs(sreg->register_info.vset_mask) - 1);
@@ -198,7 +189,7 @@ static int hisi_regulator_set_voltage(struct regulator_dev *dev,
 		sreg->register_info.vset_mask,
 		vsel << (ffs(sreg->register_info.vset_mask) - 1));
 
-	BRAND_DEBUG("<[%s]: vset_reg=0x%x, vset_mask=0x%x, value=0x%x>\n", __func__,\
+	pr_debug("<[%s]: vset_reg=0x%x, vset_mask=0x%x, value=0x%x>\n", __func__,\
 			sreg->register_info.vset_reg,\
 			sreg->register_info.vset_mask,\
 			vsel << (ffs(sreg->register_info.vset_mask) - 1)\
@@ -214,7 +205,7 @@ static unsigned int hisi_regulator_get_mode(struct regulator_dev *dev)
 	u32 reg_val;
 
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
-	BRAND_DEBUG("<[%s]: reg_val=%d, ctrl_reg=0x%x, eco_mode_mask=0x%x>\n", __func__, reg_val,\
+	pr_debug("<[%s]: reg_val=%d, ctrl_reg=0x%x, eco_mode_mask=0x%x>\n", __func__, reg_val,\
 			sreg->register_info.ctrl_reg,\
 			sreg->register_info.eco_mode_mask\
 		   );
@@ -248,7 +239,7 @@ static int hisi_regulator_set_mode(struct regulator_dev *dev,
 		sreg->register_info.eco_mode_mask,
 		eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1));
 
-	BRAND_DEBUG("<[%s]: ctrl_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n", __func__,\
+	pr_debug("<[%s]: ctrl_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n", __func__,\
 			sreg->register_info.ctrl_reg,\
 			sreg->register_info.eco_mode_mask,\
 			eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1)\
@@ -403,147 +394,6 @@ static struct of_device_id of_hisi_regulator_match_tbl[] = {
 	{ /* end */ }
 };
 
-#ifdef CONFIG_HISI_PMIC_DEBUG
-extern void get_current_regulator_dev(struct seq_file *s);
-extern void set_regulator_state(char *ldo_name, int value);
-extern void get_regulator_state(char *ldo_name);
-extern int set_regulator_voltage(char *ldo_name, unsigned int vol_value);
-
-u32 pmu_atoi(char *s)
-{
-	char *p = s;
-	char c;
-	u64 ret = 0;
-	if (s == NULL)
-		return 0;
-	while ((c = *p++) != '\0') {
-		if ('0' <= c && c <= '9') {
-			ret *= 10;
-			ret += (u64)((unsigned char)c - '0');
-			if (ret > U32_MAX)
-				return 0;
-		} else {
-			break;
-		}
-	}
-	return (u32)ret;
-}
-static int dbg_hisi_regulator_show(struct seq_file *s, void *data)
-{
-	seq_printf(s, "\n\r");
-	seq_printf(s, "%-13s %-15s %-15s %-15s %-15s\n\r",
-			"LDO_NAME", "ON/OFF", "Use_count", "Open_count", "Always_on");
-	seq_printf(s, "-----------------------------------------"
-			"-----------------------------------------------\n\r");
-	get_current_regulator_dev(s);
-	return 0;
-}
-
-static int dbg_hisi_regulator_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, dbg_hisi_regulator_show, inode->i_private);
-}
-
-static const struct file_operations debug_regulator_state_fops = {
-	.open		= dbg_hisi_regulator_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static int dbg_control_regulator_show(struct seq_file *s, void *data)
-{
-	printk("                                                                             \n\r \
-		---------------------------------------------------------------------------------\n\r \
-		|usage:                                                                         |\n\r \
-		|	S = state	R = read	V = voltage                                         |\n\r \
-		|	set ldo state and voltage                                                   |\n\r \
-		|	get ldo state and current voltage                                           |\n\r \
-		|example:                                                                       |\n\r \
-		|	echo S ldo16 0   > control_regulator	:disable ldo16                      |\n\r \
-		|	echo S ldo16 1   > control_regulator	:enable ldo16                       |\n\r \
-		|	echo R ldo16     > control_regulator	:get ldo16 state and voltage        |\n\r \
-		|	echo V ldo16 xxx > control_regulator	:set ldo16 voltage                  |\n\r \
-		---------------------------------------------------------------------------------\n\r");
-	return 0;
-}
-static ssize_t dbg_control_regulator_set_value(struct file *filp, const char __user *buffer,
-	size_t count, loff_t *ppos)
-{
-	char tmp[128] = {0};
-	char ptr[128] = {0};
-	char *vol = NULL;
-	char num = 0;
-	unsigned int i;
-	int next_flag = 1;
-
-	if (count >= 128) {
-		pr_info("error! buffer size big than internal buffer\n");
-		return -EFAULT;
-	}
-
-	if (copy_from_user(tmp, buffer, count)) {
-		pr_info("error!\n");
-		return -EFAULT;
-	}
-
-	if (tmp[0] == 'R' || tmp[0] == 'r') {
-		for (i = 2; i < (count - 1); i++) {
-			ptr[i - 2] = tmp[i];
-		}
-		ptr[i - 2] = '\0';
-		get_regulator_state(ptr);
-	} else if (tmp[0] == 'S' || tmp[0] == 's') {
-		for (i = 2; i < (count - 1); i++) {
-			if (tmp[i] == ' ') {
-				next_flag = 0;
-				ptr[i - 2] = '\0';
-				continue;
-			}
-			if (next_flag) {
-				ptr[i - 2] = tmp[i];
-			} else {
-				num = tmp[i] - 48;
-			}
-		}
-		set_regulator_state(ptr, num);
-	} else if (tmp[0] == 'V' || tmp[0] == 'v') {
-		for (i = 2; i < (count - 1); i++) {
-			if (tmp[i] == ' ') {
-				next_flag = 0;
-				ptr[i - 2] = '\0';
-				continue;
-			}
-			if (next_flag) {
-				ptr[i - 2] = tmp[i];
-			} else {
-				vol = &tmp[i];
-				break;
-			}
-		}
-		set_regulator_voltage(ptr, pmu_atoi(vol));
-	}
-
-	*ppos += count;
-
-	return count;
-}
-
-static int dbg_control_regulator_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return single_open(file, dbg_control_regulator_show, &inode->i_private);
-}
-
-static const struct file_operations set_control_regulator_fops = {
-	.open		= dbg_control_regulator_open,
-	.read		= seq_read,
-	.write		= dbg_control_regulator_set_value,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-#endif
-
 static int hisi_regulator_probe(struct spmi_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -556,10 +406,6 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 	const struct of_device_id *match;
 	struct regulation_constraints *constraint;
 	const char *supplyname = NULL;
-#ifdef CONFIG_HISI_PMIC_DEBUG
-	struct dentry *d;
-	static int debugfs_flag;
-#endif
 	unsigned int temp_modes;
 
 	const struct hisi_regulator *template = NULL;
@@ -572,11 +418,7 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 	}
 
 	template = match->data;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0))
 	initdata = of_get_regulator_init_data(dev, np, NULL);
-#else
-	initdata = of_get_regulator_init_data(dev, np);
-#endif
 	if (NULL == initdata) {
 		pr_err("get regulator init data error !\n");
 		return -EINVAL;
@@ -636,32 +478,10 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 		goto hisi_probe_end;
 	}
 
-	BRAND_DEBUG("[%s]:valid_modes_mask[0x%x], valid_ops_mask[0x%x]\n", rdesc->name,\
+	pr_debug("[%s]:valid_modes_mask[0x%x], valid_ops_mask[0x%x]\n", rdesc->name,\
 			constraint->valid_modes_mask, constraint->valid_ops_mask);
 
 	dev_set_drvdata(dev, rdev);
-#ifdef CONFIG_HISI_PMIC_DEBUG
-	if (debugfs_flag == 0) {
-		d = debugfs_create_dir("hisi_regulator_debugfs", NULL);
-		if (!d) {
-			dev_err(dev, "failed to create hisi regulator debugfs dir !\n");
-			ret = -ENOMEM;
-			goto hisi_probe_fail;
-		}
-		(void) debugfs_create_file("regulator_state", S_IRUSR,
-						d, NULL, &debug_regulator_state_fops);
-
-		(void) debugfs_create_file("control_regulator", S_IRUSR,
-						d, NULL, &set_control_regulator_fops);
-		debugfs_flag = 1;
-	}
-#endif
-
-#ifdef CONFIG_HISI_PMIC_DEBUG
-hisi_probe_fail:
-	if (ret)
-		regulator_unregister(rdev);
-#endif
 hisi_probe_end:
 	if (ret)
 		kfree(sreg);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 25/44] staging: regulator: hi6421v600-regulator: port it to upstream
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (23 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 24/44] staging: regulator: hi6421v600-regulator: get rid of unused code Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 26/44] staging: regulator: hi6421v600-regulator: coding style fixups Mauro Carvalho Chehab
                   ` (20 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

The driver was originally written for Kernel 4.9. It needs to
be ported to upstream:

	- Got rid of timeval;
	- Removed a bogus dependency;
	- Did cleanups at the header file.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 34 +++----------------
 1 file changed, 5 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 7bc0ae27b110..904cb64b1dcd 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -49,7 +49,6 @@ struct hisi_regulator_register_info {
 struct hisi_regulator {
 	const char *name;
 	struct hisi_regulator_register_info register_info;
-	struct timeval last_off_time;
 	u32 off_on_delay;
 	u32 eco_uA;
 	struct regulator_desc rdesc;
@@ -57,8 +56,6 @@ struct hisi_regulator {
 };
 
 static DEFINE_MUTEX(enable_mutex);
-struct timeval last_enabled;
-
 
 static inline struct hisi_pmic *rdev_to_pmic(struct regulator_dev *dev)
 {
@@ -72,27 +69,6 @@ static inline struct hisi_pmic *rdev_to_pmic(struct regulator_dev *dev)
 /* helper function to ensure when it returns it is at least 'delay_us'
  * microseconds after 'since'.
  */
-static void ensured_time_after(struct timeval since, u32 delay_us)
-{
-	struct timeval now;
-	u64 elapsed_ns64, delay_ns64;
-	u32 actual_us32;
-
-	delay_ns64 = delay_us * NSEC_PER_USEC;
-	do_gettimeofday(&now);
-	elapsed_ns64 = timeval_to_ns(&now) - timeval_to_ns(&since);
-	if (delay_ns64 > elapsed_ns64) {
-		actual_us32 = ((u32)(delay_ns64 - elapsed_ns64) /
-							NSEC_PER_USEC);
-		if (actual_us32 >= 1000) {
-			mdelay(actual_us32 / 1000); /*lint !e647 */
-			udelay(actual_us32 % 1000);
-		} else if (actual_us32 > 0) {
-			udelay(actual_us32);
-		}
-	}
-	return;
-}
 
 static int hisi_regulator_is_enabled(struct regulator_dev *dev)
 {
@@ -113,13 +89,16 @@ static int hisi_regulator_enable(struct regulator_dev *dev)
 	struct hisi_pmic *pmic = rdev_to_pmic(dev);
 
 	/* keep a distance of off_on_delay from last time disabled */
-	ensured_time_after(sreg->last_off_time, sreg->off_on_delay);
+	usleep_range(sreg->off_on_delay, sreg->off_on_delay + 1000);
 
 	pr_debug("<[%s]: off_on_delay=%dus>\n", __func__, sreg->off_on_delay);
 
 	/* cannot enable more than one regulator at one time */
 	mutex_lock(&enable_mutex);
-	ensured_time_after(last_enabled, HISI_REGS_ENA_PROTECT_TIME);
+	usleep_range(HISI_REGS_ENA_PROTECT_TIME,
+		     HISI_REGS_ENA_PROTECT_TIME + 1000);
+
+
 
 	/* set enable register */
 	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
@@ -128,7 +107,6 @@ static int hisi_regulator_enable(struct regulator_dev *dev)
 	pr_debug("<[%s]: ctrl_reg=0x%x,enable_mask=0x%x>\n", __func__, sreg->register_info.ctrl_reg,\
 			sreg->register_info.enable_mask);
 
-	do_gettimeofday(&last_enabled);
 	mutex_unlock(&enable_mutex);
 
 	return 0;
@@ -143,8 +121,6 @@ static int hisi_regulator_disable(struct regulator_dev *dev)
 	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
 				sreg->register_info.enable_mask, 0);
 
-	do_gettimeofday(&sreg->last_off_time);
-
 	return 0;
 }
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 26/44] staging: regulator: hi6421v600-regulator: coding style fixups
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (24 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 25/44] staging: regulator: hi6421v600-regulator: port it to upstream Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 27/44] staging: regulator: hi6421v600-regulator: change the binding logic Mauro Carvalho Chehab
                   ` (19 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

There are several issues on those drivers related to their
coding style. Solve most of them.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 110 +++++++++---------
 1 file changed, 56 insertions(+), 54 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 904cb64b1dcd..5f6e4ba4b99e 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device driver for regulators in Hisi IC
  *
@@ -52,7 +53,7 @@ struct hisi_regulator {
 	u32 off_on_delay;
 	u32 eco_uA;
 	struct regulator_desc rdesc;
-	int (*dt_parse)(struct hisi_regulator *, struct spmi_device *);
+	int (*dt_parse)(struct hisi_regulator *reg, struct spmi_device *spmi);
 };
 
 static DEFINE_MUTEX(enable_mutex);
@@ -77,8 +78,9 @@ static int hisi_regulator_is_enabled(struct regulator_dev *dev)
 	struct hisi_pmic *pmic = rdev_to_pmic(dev);
 
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
-	pr_debug("<[%s]: ctrl_reg=0x%x,enable_state=%d>\n", __func__, sreg->register_info.ctrl_reg,\
-			(reg_val & sreg->register_info.enable_mask));
+	pr_debug("<[%s]: ctrl_reg=0x%x,enable_state=%d>\n",
+		 __func__, sreg->register_info.ctrl_reg,
+		(reg_val & sreg->register_info.enable_mask));
 
 	return ((reg_val & sreg->register_info.enable_mask) != 0);
 }
@@ -98,14 +100,13 @@ static int hisi_regulator_enable(struct regulator_dev *dev)
 	usleep_range(HISI_REGS_ENA_PROTECT_TIME,
 		     HISI_REGS_ENA_PROTECT_TIME + 1000);
 
-
-
 	/* set enable register */
 	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
-				sreg->register_info.enable_mask,
+		      sreg->register_info.enable_mask,
 				sreg->register_info.enable_mask);
-	pr_debug("<[%s]: ctrl_reg=0x%x,enable_mask=0x%x>\n", __func__, sreg->register_info.ctrl_reg,\
-			sreg->register_info.enable_mask);
+	pr_debug("<[%s]: ctrl_reg=0x%x,enable_mask=0x%x>\n",
+		 __func__, sreg->register_info.ctrl_reg,
+		 sreg->register_info.enable_mask);
 
 	mutex_unlock(&enable_mutex);
 
@@ -119,7 +120,7 @@ static int hisi_regulator_disable(struct regulator_dev *dev)
 
 	/* set enable register to 0 */
 	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
-				sreg->register_info.enable_mask, 0);
+		      sreg->register_info.enable_mask, 0);
 
 	return 0;
 }
@@ -132,7 +133,8 @@ static int hisi_regulator_get_voltage(struct regulator_dev *dev)
 
 	/* get voltage selector */
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.vset_reg);
-	pr_debug("<[%s]: vset_reg=0x%x>\n", __func__, sreg->register_info.vset_reg);
+	pr_debug("<[%s]: vset_reg=0x%x>\n",
+		 __func__, sreg->register_info.vset_reg);
 
 	selector = (reg_val & sreg->register_info.vset_mask) >>
 				(ffs(sreg->register_info.vset_mask) - 1);
@@ -141,7 +143,7 @@ static int hisi_regulator_get_voltage(struct regulator_dev *dev)
 }
 
 static int hisi_regulator_set_voltage(struct regulator_dev *dev,
-				int min_uV, int max_uV, unsigned *selector)
+				      int min_uV, int max_uV, unsigned int *selector)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
 	struct hisi_pmic *pmic = rdev_to_pmic(dev);
@@ -162,14 +164,14 @@ static int hisi_regulator_set_voltage(struct regulator_dev *dev,
 	*selector = vsel;
 	/* set voltage selector */
 	hisi_pmic_rmw(pmic, sreg->register_info.vset_reg,
-		sreg->register_info.vset_mask,
+		      sreg->register_info.vset_mask,
 		vsel << (ffs(sreg->register_info.vset_mask) - 1));
 
-	pr_debug("<[%s]: vset_reg=0x%x, vset_mask=0x%x, value=0x%x>\n", __func__,\
-			sreg->register_info.vset_reg,\
-			sreg->register_info.vset_mask,\
-			vsel << (ffs(sreg->register_info.vset_mask) - 1)\
-			);
+	pr_debug("<[%s]: vset_reg=0x%x, vset_mask=0x%x, value=0x%x>\n",
+		 __func__,
+		 sreg->register_info.vset_reg,
+		 sreg->register_info.vset_mask,
+		 vsel << (ffs(sreg->register_info.vset_mask) - 1));
 
 	return ret;
 }
@@ -181,10 +183,10 @@ static unsigned int hisi_regulator_get_mode(struct regulator_dev *dev)
 	u32 reg_val;
 
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
-	pr_debug("<[%s]: reg_val=%d, ctrl_reg=0x%x, eco_mode_mask=0x%x>\n", __func__, reg_val,\
-			sreg->register_info.ctrl_reg,\
-			sreg->register_info.eco_mode_mask\
-		   );
+	pr_debug("<[%s]: reg_val=%d, ctrl_reg=0x%x, eco_mode_mask=0x%x>\n",
+		 __func__, reg_val,
+		sreg->register_info.ctrl_reg,
+		sreg->register_info.eco_mode_mask);
 
 	if (reg_val & sreg->register_info.eco_mode_mask)
 		return REGULATOR_MODE_IDLE;
@@ -193,7 +195,7 @@ static unsigned int hisi_regulator_get_mode(struct regulator_dev *dev)
 }
 
 static int hisi_regulator_set_mode(struct regulator_dev *dev,
-						unsigned int mode)
+				   unsigned int mode)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
 	struct hisi_pmic *pmic = rdev_to_pmic(dev);
@@ -212,31 +214,31 @@ static int hisi_regulator_set_mode(struct regulator_dev *dev,
 
 	/* set mode */
 	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
+		      sreg->register_info.eco_mode_mask,
+		eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1));
+
+	pr_debug("<[%s]: ctrl_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n",
+		 __func__,
+		sreg->register_info.ctrl_reg,
 		sreg->register_info.eco_mode_mask,
 		eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1));
-
-	pr_debug("<[%s]: ctrl_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n", __func__,\
-			sreg->register_info.ctrl_reg,\
-			sreg->register_info.eco_mode_mask,\
-			eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1)\
-		   );
 	return 0;
 }
 
-
-unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *dev,
-			int input_uV, int output_uV, int load_uA)
+static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *dev,
+						    int input_uV, int output_uV,
+						    int load_uA)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
 
-	if ((load_uA == 0) || ((unsigned int)load_uA > sreg->eco_uA))
+	if (load_uA || ((unsigned int)load_uA > sreg->eco_uA))
 		return REGULATOR_MODE_NORMAL;
 	else
 		return REGULATOR_MODE_IDLE;
 }
 
 static int hisi_dt_parse_common(struct hisi_regulator *sreg,
-					struct spmi_device *pdev)
+				struct spmi_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -246,7 +248,7 @@ static int hisi_dt_parse_common(struct hisi_regulator *sreg,
 
 	/* parse .register_info.ctrl_reg */
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-ctrl",
-						register_info, 3);
+					 register_info, 3);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-ctrl property set\n");
 		goto dt_parse_common_end;
@@ -257,7 +259,7 @@ static int hisi_dt_parse_common(struct hisi_regulator *sreg,
 
 	/* parse .register_info.vset_reg */
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset",
-						register_info, 2);
+					 register_info, 2);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-vset property set\n");
 		goto dt_parse_common_end;
@@ -267,7 +269,7 @@ static int hisi_dt_parse_common(struct hisi_regulator *sreg,
 
 	/* parse .off-on-delay */
 	ret = of_property_read_u32(np, "hisilicon,hisi-off-on-delay-us",
-						&sreg->off_on_delay);
+				   &sreg->off_on_delay);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-off-on-delay-us property set\n");
 		goto dt_parse_common_end;
@@ -294,7 +296,7 @@ static int hisi_dt_parse_common(struct hisi_regulator *sreg,
 }
 
 static int hisi_dt_parse_ldo(struct hisi_regulator *sreg,
-				struct spmi_device *pdev)
+			     struct spmi_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -312,7 +314,7 @@ static int hisi_dt_parse_ldo(struct hisi_regulator *sreg,
 
 	/* alloc space for .volt_table */
 	v_table = devm_kzalloc(dev, sizeof(unsigned int) * rdesc->n_voltages,
-								GFP_KERNEL);
+			       GFP_KERNEL);
 	if (unlikely(!v_table)) {
 		ret = -ENOMEM;
 		dev_err(dev, "no memory for .volt_table\n");
@@ -320,7 +322,7 @@ static int hisi_dt_parse_ldo(struct hisi_regulator *sreg,
 	}
 
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset-table",
-						v_table, rdesc->n_voltages);
+					 v_table, rdesc->n_voltages);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-vset-table property set\n");
 		goto dt_parse_ldo_end1;
@@ -362,7 +364,7 @@ static const struct hisi_regulator hisi_regulator_ldo = {
 	.dt_parse = hisi_dt_parse_ldo,
 };
 
-static struct of_device_id of_hisi_regulator_match_tbl[] = {
+static const struct of_device_id of_hisi_regulator_match_tbl[] = {
 	{
 		.compatible = "hisilicon-hisi-ldo",
 		.data = &hisi_regulator_ldo,
@@ -388,14 +390,14 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 	int ret = 0;
 	/* to check which type of regulator this is */
 	match = of_match_device(of_hisi_regulator_match_tbl, &pdev->dev);
-	if (NULL == match) {
+	if (!match) {
 		pr_err("get hisi regulator fail!\n\r");
 		return -EINVAL;
 	}
 
 	template = match->data;
 	initdata = of_get_regulator_init_data(dev, np, NULL);
-	if (NULL == initdata) {
+	if (!initdata) {
 		pr_err("get regulator init data error !\n");
 		return -EINVAL;
 	}
@@ -404,14 +406,14 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 	constraint = &initdata->constraints;
 
 	ret = of_property_read_u32_array(np, "hisilicon,valid-modes-mask",
-						&(constraint->valid_modes_mask), 1);
+					 &constraint->valid_modes_mask, 1);
 	if (ret) {
 		pr_err("no hisilicon,valid-modes-mask property set\n");
 		ret = -ENODEV;
 		return ret;
 	}
 	ret = of_property_read_u32_array(np, "hisilicon,valid-idle-mask",
-						&temp_modes, 1);
+					 &temp_modes, 1);
 	if (ret) {
 		pr_err("no hisilicon,valid-modes-mask property set\n");
 		ret = -ENODEV;
@@ -420,18 +422,16 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 	constraint->valid_ops_mask |= temp_modes;
 
 	sreg = kmemdup(template, sizeof(*sreg), GFP_KERNEL);
-	if (!sreg) {
-		pr_err("template kememdup is fail. \n");
+	if (!sreg)
 		return -ENOMEM;
-	}
+
 	sreg->name = initdata->constraints.name;
 	rdesc = &sreg->rdesc;
 	rdesc->name = sreg->name;
 	rdesc->min_uV = initdata->constraints.min_uV;
 	supplyname = of_get_property(np, "hisilicon,supply_name", NULL);
-	if (supplyname != NULL) {
+	if (supplyname)
 		initdata->supply_regulator = supplyname;
-	}
 
 	/* to parse device tree data for regulator specific */
 	ret = sreg->dt_parse(sreg, pdev);
@@ -454,8 +454,9 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 		goto hisi_probe_end;
 	}
 
-	pr_debug("[%s]:valid_modes_mask[0x%x], valid_ops_mask[0x%x]\n", rdesc->name,\
-			constraint->valid_modes_mask, constraint->valid_ops_mask);
+	pr_debug("[%s]:valid_modes_mask[0x%x], valid_ops_mask[0x%x]\n",
+		 rdesc->name,
+		 constraint->valid_modes_mask, constraint->valid_ops_mask);
 
 	dev_set_drvdata(dev, rdev);
 hisi_probe_end:
@@ -477,11 +478,12 @@ static void hisi_regulator_remove(struct spmi_device *pdev)
 
 	kfree(sreg);
 }
+
 static int hisi_regulator_suspend(struct device *dev, pm_message_t state)
 {
 	struct hisi_regulator *hisi_regulator = dev_get_drvdata(dev);
 
-	if (NULL == hisi_regulator) {
+	if (!hisi_regulator) {
 		pr_err("%s:regulator is NULL\n", __func__);
 		return -ENOMEM;
 	}
@@ -490,13 +492,13 @@ static int hisi_regulator_suspend(struct device *dev, pm_message_t state)
 	pr_info("%s:-\n", __func__);
 
 	return 0;
-}/*lint !e715 */
+}
 
 static int hisi_regulator_resume(struct device *dev)
 {
 	struct hisi_regulator *hisi_regulator = dev_get_drvdata(dev);
 
-	if (NULL == hisi_regulator) {
+	if (!hisi_regulator) {
 		pr_err("%s:regulator is NULL\n", __func__);
 		return -ENOMEM;
 	}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 27/44] staging: regulator: hi6421v600-regulator: change the binding logic
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (25 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 26/44] staging: regulator: hi6421v600-regulator: coding style fixups Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 28/44] staging: regulator: hi6421v600-regulator: cleanup struct hisi_regulator Mauro Carvalho Chehab
                   ` (18 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Change the binding logic to ensure that the PMIC SPMI
driver will run before the regulator code and add it to the
building system.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 186 +++++++++---------
 1 file changed, 91 insertions(+), 95 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 5f6e4ba4b99e..9aaafcbb1a36 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -31,7 +31,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
-#include <linux/mfd/hisi_pmic.h>
+#include <linux/mfd/hi6421-spmi-pmic.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/version.h>
@@ -53,20 +53,11 @@ struct hisi_regulator {
 	u32 off_on_delay;
 	u32 eco_uA;
 	struct regulator_desc rdesc;
-	int (*dt_parse)(struct hisi_regulator *reg, struct spmi_device *spmi);
+	struct hisi_pmic *pmic;
 };
 
 static DEFINE_MUTEX(enable_mutex);
 
-static inline struct hisi_pmic *rdev_to_pmic(struct regulator_dev *dev)
-{
-	/* regulator_dev parent to->
-	 * hisi regulator platform device_dev parent to->
-	 * hisi pmic platform device_dev
-	 */
-	return dev_get_drvdata(rdev_get_dev(dev)->parent->parent);
-}
-
 /* helper function to ensure when it returns it is at least 'delay_us'
  * microseconds after 'since'.
  */
@@ -75,7 +66,7 @@ static int hisi_regulator_is_enabled(struct regulator_dev *dev)
 {
 	u32 reg_val;
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
-	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	struct hisi_pmic *pmic = sreg->pmic;
 
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
 	pr_debug("<[%s]: ctrl_reg=0x%x,enable_state=%d>\n",
@@ -88,7 +79,7 @@ static int hisi_regulator_is_enabled(struct regulator_dev *dev)
 static int hisi_regulator_enable(struct regulator_dev *dev)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
-	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	struct hisi_pmic *pmic = sreg->pmic;
 
 	/* keep a distance of off_on_delay from last time disabled */
 	usleep_range(sreg->off_on_delay, sreg->off_on_delay + 1000);
@@ -116,7 +107,7 @@ static int hisi_regulator_enable(struct regulator_dev *dev)
 static int hisi_regulator_disable(struct regulator_dev *dev)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
-	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	struct hisi_pmic *pmic = sreg->pmic;
 
 	/* set enable register to 0 */
 	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
@@ -128,7 +119,7 @@ static int hisi_regulator_disable(struct regulator_dev *dev)
 static int hisi_regulator_get_voltage(struct regulator_dev *dev)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
-	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	struct hisi_pmic *pmic = sreg->pmic;
 	u32 reg_val, selector;
 
 	/* get voltage selector */
@@ -146,7 +137,7 @@ static int hisi_regulator_set_voltage(struct regulator_dev *dev,
 				      int min_uV, int max_uV, unsigned int *selector)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
-	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	struct hisi_pmic *pmic = sreg->pmic;
 	u32 vsel;
 	int ret = 0;
 
@@ -179,7 +170,7 @@ static int hisi_regulator_set_voltage(struct regulator_dev *dev,
 static unsigned int hisi_regulator_get_mode(struct regulator_dev *dev)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
-	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	struct hisi_pmic *pmic = sreg->pmic;
 	u32 reg_val;
 
 	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
@@ -198,7 +189,7 @@ static int hisi_regulator_set_mode(struct regulator_dev *dev,
 				   unsigned int mode)
 {
 	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
-	struct hisi_pmic *pmic = rdev_to_pmic(dev);
+	struct hisi_pmic *pmic = sreg->pmic;
 	u32 eco_mode;
 
 	switch (mode) {
@@ -238,7 +229,7 @@ static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *dev,
 }
 
 static int hisi_dt_parse_common(struct hisi_regulator *sreg,
-				struct spmi_device *pdev)
+				struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -296,7 +287,7 @@ static int hisi_dt_parse_common(struct hisi_regulator *sreg,
 }
 
 static int hisi_dt_parse_ldo(struct hisi_regulator *sreg,
-			     struct spmi_device *pdev)
+			     struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -355,47 +346,32 @@ static struct regulator_ops hisi_ldo_rops = {
 	.get_optimum_mode = hisi_regulator_get_optimum_mode,
 };
 
-static const struct hisi_regulator hisi_regulator_ldo = {
-	.rdesc = {
-	.ops = &hisi_ldo_rops,
-		.type = REGULATOR_VOLTAGE,
-		.owner = THIS_MODULE,
-		},
-	.dt_parse = hisi_dt_parse_ldo,
-};
+/*
+ * Used only for parsing the DT properties
+ */
 
-static const struct of_device_id of_hisi_regulator_match_tbl[] = {
+static const struct of_device_id of_hisi_pmic_match_tbl[] = {
 	{
-		.compatible = "hisilicon-hisi-ldo",
-		.data = &hisi_regulator_ldo,
+		.compatible = "hisilicon,hi6421-spmi-pmic-ldo",
 	},
-	{ /* end */ }
+	{ }
 };
 
-static int hisi_regulator_probe(struct spmi_device *pdev)
+static int hisi_regulator_probe_ldo(struct platform_device *pdev,
+				    struct device_node *np,
+				    struct hisi_pmic *pmic)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
 	struct regulator_desc *rdesc;
 	struct regulator_dev *rdev;
 	struct hisi_regulator *sreg = NULL;
 	struct regulator_init_data *initdata;
 	struct regulator_config config = { };
-	const struct of_device_id *match;
 	struct regulation_constraints *constraint;
 	const char *supplyname = NULL;
 	unsigned int temp_modes;
-
-	const struct hisi_regulator *template = NULL;
 	int ret = 0;
-	/* to check which type of regulator this is */
-	match = of_match_device(of_hisi_regulator_match_tbl, &pdev->dev);
-	if (!match) {
-		pr_err("get hisi regulator fail!\n\r");
-		return -EINVAL;
-	}
 
-	template = match->data;
 	initdata = of_get_regulator_init_data(dev, np, NULL);
 	if (!initdata) {
 		pr_err("get regulator init data error !\n");
@@ -421,20 +397,25 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 	}
 	constraint->valid_ops_mask |= temp_modes;
 
-	sreg = kmemdup(template, sizeof(*sreg), GFP_KERNEL);
+	sreg = kzalloc(sizeof(*sreg), GFP_KERNEL);
 	if (!sreg)
 		return -ENOMEM;
 
 	sreg->name = initdata->constraints.name;
+	sreg->pmic = pmic;
 	rdesc = &sreg->rdesc;
+
 	rdesc->name = sreg->name;
+	rdesc->ops = &hisi_ldo_rops;
+	rdesc->type = REGULATOR_VOLTAGE;
 	rdesc->min_uV = initdata->constraints.min_uV;
+
 	supplyname = of_get_property(np, "hisilicon,supply_name", NULL);
 	if (supplyname)
 		initdata->supply_regulator = supplyname;
 
-	/* to parse device tree data for regulator specific */
-	ret = sreg->dt_parse(sreg, pdev);
+	/* parse device tree data for regulator specific */
+	ret = hisi_dt_parse_ldo(sreg, pdev);
 	if (ret) {
 		dev_err(dev, "device tree parameter parse error!\n");
 		goto hisi_probe_end;
@@ -465,7 +446,59 @@ static int hisi_regulator_probe(struct spmi_device *pdev)
 	return ret;
 }
 
-static void hisi_regulator_remove(struct spmi_device *pdev)
+
+static int hisi_regulator_probe(struct platform_device *pdev)
+{
+	struct device *pmic_dev = pdev->dev.parent;
+	struct device_node *np = pmic_dev->of_node;
+	struct device_node *regulators, *child;
+	struct platform_device *new_pdev;
+	struct hisi_pmic *pmic;
+	int ret;
+
+	dev_dbg(&pdev->dev, "probing hi6421v600 regulator\n");
+	/*
+	 * This driver is meant to be called by hi6421-spmi-core,
+	 * which should first set drvdata. If this doesn't happen, hit
+	 * a warn on and return.
+	 */
+	pmic = dev_get_drvdata(pmic_dev);
+	if (WARN_ON(!pmic))
+		return -ENODEV;
+
+	regulators = of_get_child_by_name(np, "regulators");
+	if (!regulators) {
+		dev_err(&pdev->dev, "regulator node not found\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * Parse all LDO regulator nodes
+	 */
+	for_each_child_of_node(regulators, child) {
+		dev_dbg(&pdev->dev, "adding child %pOF\n", child);
+
+		new_pdev = platform_device_alloc(child->name, -1);
+		new_pdev->dev.parent = pmic_dev;
+		new_pdev->dev.of_node = of_node_get(child);
+
+		ret = platform_device_add(new_pdev);
+		if (ret < 0) {
+			platform_device_put(new_pdev);
+			continue;
+		}
+
+		ret = hisi_regulator_probe_ldo(new_pdev, child, pmic);
+		if (ret < 0)
+			platform_device_put(new_pdev);
+	}
+
+	of_node_put(regulators);
+
+	return 0;
+}
+
+static int hisi_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = dev_get_drvdata(&pdev->dev);
 	struct hisi_regulator *sreg = rdev_get_drvdata(rdev);
@@ -477,63 +510,26 @@ static void hisi_regulator_remove(struct spmi_device *pdev)
 		devm_kfree(&pdev->dev, (unsigned int *)sreg->rdesc.volt_table);
 
 	kfree(sreg);
-}
-
-static int hisi_regulator_suspend(struct device *dev, pm_message_t state)
-{
-	struct hisi_regulator *hisi_regulator = dev_get_drvdata(dev);
-
-	if (!hisi_regulator) {
-		pr_err("%s:regulator is NULL\n", __func__);
-		return -ENOMEM;
-	}
-
-	pr_info("%s:+\n", __func__);
-	pr_info("%s:-\n", __func__);
 
 	return 0;
 }
 
-static int hisi_regulator_resume(struct device *dev)
-{
-	struct hisi_regulator *hisi_regulator = dev_get_drvdata(dev);
-
-	if (!hisi_regulator) {
-		pr_err("%s:regulator is NULL\n", __func__);
-		return -ENOMEM;
-	}
-
-	pr_info("%s:+\n", __func__);
-	pr_info("%s:-\n", __func__);
-
-	return 0;
-}
+static const struct platform_device_id hi6421v600_regulator_table[] = {
+	{ .name = "hi6421v600-regulator" },
+	{},
+};
+MODULE_DEVICE_TABLE(platform, hi6421v600_regulator_table);
 
-static struct spmi_driver hisi_pmic_driver = {
+static struct platform_driver hi6421v600_regulator_driver = {
+	.id_table = hi6421v600_regulator_table,
 	.driver = {
-		.name	= "hisi_regulator",
-		.owner  = THIS_MODULE,
-		.of_match_table = of_hisi_regulator_match_tbl,
-		.suspend = hisi_regulator_suspend,
-		.resume = hisi_regulator_resume,
+		.name	= "hi6421v600-regulator",
 	},
 	.probe	= hisi_regulator_probe,
 	.remove	= hisi_regulator_remove,
 };
+module_platform_driver(hi6421v600_regulator_driver);
 
-static int __init hisi_regulator_init(void)
-{
-	return spmi_driver_register(&hisi_pmic_driver);
-}
-
-static void __exit hisi_regulator_exit(void)
-{
-	spmi_driver_unregister(&hisi_pmic_driver);
-}
-
-fs_initcall(hisi_regulator_init);
-module_exit(hisi_regulator_exit);
-
-MODULE_DESCRIPTION("Hisi regulator driver");
+MODULE_DESCRIPTION("Hi6421v600 regulator driver");
 MODULE_LICENSE("GPL v2");
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 28/44] staging: regulator: hi6421v600-regulator: cleanup struct hisi_regulator
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (26 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 27/44] staging: regulator: hi6421v600-regulator: change the binding logic Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 29/44] staging: regulator: hi6421v600-regulator: cleanup debug messages Mauro Carvalho Chehab
                   ` (17 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

There are several fields on this struct that can be removed,
as they already exists at struct regulator_desc.

Remove them, cleaning up the code in the process.

While here, rename it to hi6421v600_regulator_info, in order
to better match the driver's name.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 226 +++++++-----------
 1 file changed, 92 insertions(+), 134 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 9aaafcbb1a36..7d82d11f4b52 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -39,21 +39,11 @@
 #include <linux/uaccess.h>
 #include <linux/spmi.h>
 
-struct hisi_regulator_register_info {
-	u32 ctrl_reg;
-	u32 enable_mask;
-	u32 eco_mode_mask;
-	u32 vset_reg;
-	u32 vset_mask;
-};
-
-struct hisi_regulator {
-	const char *name;
-	struct hisi_regulator_register_info register_info;
-	u32 off_on_delay;
-	u32 eco_uA;
+struct hi6421v600_regulator {
 	struct regulator_desc rdesc;
 	struct hisi_pmic *pmic;
+	u8 eco_mode_mask;
+	u32 eco_uA;
 };
 
 static DEFINE_MUTEX(enable_mutex);
@@ -62,29 +52,29 @@ static DEFINE_MUTEX(enable_mutex);
  * microseconds after 'since'.
  */
 
-static int hisi_regulator_is_enabled(struct regulator_dev *dev)
+static int hisi_regulator_is_enabled(struct regulator_dev *rdev)
 {
 	u32 reg_val;
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 
-	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
-	pr_debug("<[%s]: ctrl_reg=0x%x,enable_state=%d>\n",
-		 __func__, sreg->register_info.ctrl_reg,
-		(reg_val & sreg->register_info.enable_mask));
+	reg_val = hisi_pmic_read(pmic, rdev->desc->enable_reg);
+	pr_debug("<[%s]: enable_reg=0x%x,enable_state=%d>\n",
+		 __func__, rdev->desc->enable_reg,
+		(reg_val & rdev->desc->enable_mask));
 
-	return ((reg_val & sreg->register_info.enable_mask) != 0);
+	return ((reg_val & rdev->desc->enable_mask) != 0);
 }
 
-static int hisi_regulator_enable(struct regulator_dev *dev)
+static int hisi_regulator_enable(struct regulator_dev *rdev)
 {
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 
 	/* keep a distance of off_on_delay from last time disabled */
-	usleep_range(sreg->off_on_delay, sreg->off_on_delay + 1000);
+	usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 1000);
 
-	pr_debug("<[%s]: off_on_delay=%dus>\n", __func__, sreg->off_on_delay);
+	pr_debug("<[%s]: off_on_delay=%dus>\n", __func__, rdev->desc->off_on_delay);
 
 	/* cannot enable more than one regulator at one time */
 	mutex_lock(&enable_mutex);
@@ -92,103 +82,103 @@ static int hisi_regulator_enable(struct regulator_dev *dev)
 		     HISI_REGS_ENA_PROTECT_TIME + 1000);
 
 	/* set enable register */
-	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
-		      sreg->register_info.enable_mask,
-				sreg->register_info.enable_mask);
-	pr_debug("<[%s]: ctrl_reg=0x%x,enable_mask=0x%x>\n",
-		 __func__, sreg->register_info.ctrl_reg,
-		 sreg->register_info.enable_mask);
+	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
+		      rdev->desc->enable_mask,
+				rdev->desc->enable_mask);
+	pr_debug("<[%s]: enable_reg=0x%x,enable_mask=0x%x>\n",
+		 __func__, rdev->desc->enable_reg,
+		 rdev->desc->enable_mask);
 
 	mutex_unlock(&enable_mutex);
 
 	return 0;
 }
 
-static int hisi_regulator_disable(struct regulator_dev *dev)
+static int hisi_regulator_disable(struct regulator_dev *rdev)
 {
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 
 	/* set enable register to 0 */
-	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
-		      sreg->register_info.enable_mask, 0);
+	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
+		      rdev->desc->enable_mask, 0);
 
 	return 0;
 }
 
-static int hisi_regulator_get_voltage(struct regulator_dev *dev)
+static int hisi_regulator_get_voltage(struct regulator_dev *rdev)
 {
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 	u32 reg_val, selector;
 
 	/* get voltage selector */
-	reg_val = hisi_pmic_read(pmic, sreg->register_info.vset_reg);
-	pr_debug("<[%s]: vset_reg=0x%x>\n",
-		 __func__, sreg->register_info.vset_reg);
+	reg_val = hisi_pmic_read(pmic, rdev->desc->vsel_reg);
+	pr_debug("<[%s]: vsel_reg=0x%x>\n",
+		 __func__, rdev->desc->vsel_reg);
 
-	selector = (reg_val & sreg->register_info.vset_mask) >>
-				(ffs(sreg->register_info.vset_mask) - 1);
+	selector = (reg_val & rdev->desc->vsel_mask) >>
+				(ffs(rdev->desc->vsel_mask) - 1);
 
-	return sreg->rdesc.ops->list_voltage(dev, selector);
+	return rdev->desc->ops->list_voltage(rdev, selector);
 }
 
-static int hisi_regulator_set_voltage(struct regulator_dev *dev,
+static int hisi_regulator_set_voltage(struct regulator_dev *rdev,
 				      int min_uV, int max_uV, unsigned int *selector)
 {
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 	u32 vsel;
 	int ret = 0;
 
-	for (vsel = 0; vsel < sreg->rdesc.n_voltages; vsel++) {
-		int uV = sreg->rdesc.volt_table[vsel];
+	for (vsel = 0; vsel < rdev->desc->n_voltages; vsel++) {
+		int uV = rdev->desc->volt_table[vsel];
 		/* Break at the first in-range value */
 		if (min_uV <= uV && uV <= max_uV)
 			break;
 	}
 
 	/* unlikely to happen. sanity test done by regulator core */
-	if (unlikely(vsel == sreg->rdesc.n_voltages))
+	if (unlikely(vsel == rdev->desc->n_voltages))
 		return -EINVAL;
 
 	*selector = vsel;
 	/* set voltage selector */
-	hisi_pmic_rmw(pmic, sreg->register_info.vset_reg,
-		      sreg->register_info.vset_mask,
-		vsel << (ffs(sreg->register_info.vset_mask) - 1));
+	hisi_pmic_rmw(pmic, rdev->desc->vsel_reg,
+		      rdev->desc->vsel_mask,
+		vsel << (ffs(rdev->desc->vsel_mask) - 1));
 
-	pr_debug("<[%s]: vset_reg=0x%x, vset_mask=0x%x, value=0x%x>\n",
+	pr_debug("<[%s]: vsel_reg=0x%x, vsel_mask=0x%x, value=0x%x>\n",
 		 __func__,
-		 sreg->register_info.vset_reg,
-		 sreg->register_info.vset_mask,
-		 vsel << (ffs(sreg->register_info.vset_mask) - 1));
+		 rdev->desc->vsel_reg,
+		 rdev->desc->vsel_mask,
+		 vsel << (ffs(rdev->desc->vsel_mask) - 1));
 
 	return ret;
 }
 
-static unsigned int hisi_regulator_get_mode(struct regulator_dev *dev)
+static unsigned int hisi_regulator_get_mode(struct regulator_dev *rdev)
 {
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 	u32 reg_val;
 
-	reg_val = hisi_pmic_read(pmic, sreg->register_info.ctrl_reg);
-	pr_debug("<[%s]: reg_val=%d, ctrl_reg=0x%x, eco_mode_mask=0x%x>\n",
+	reg_val = hisi_pmic_read(pmic, rdev->desc->enable_reg);
+	pr_debug("<[%s]: reg_val=%d, enable_reg=0x%x, eco_mode_mask=0x%x>\n",
 		 __func__, reg_val,
-		sreg->register_info.ctrl_reg,
-		sreg->register_info.eco_mode_mask);
+		rdev->desc->enable_reg,
+		sreg->eco_mode_mask);
 
-	if (reg_val & sreg->register_info.eco_mode_mask)
+	if (reg_val & sreg->eco_mode_mask)
 		return REGULATOR_MODE_IDLE;
 	else
 		return REGULATOR_MODE_NORMAL;
 }
 
-static int hisi_regulator_set_mode(struct regulator_dev *dev,
+static int hisi_regulator_set_mode(struct regulator_dev *rdev,
 				   unsigned int mode)
 {
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 	u32 eco_mode;
 
@@ -204,23 +194,23 @@ static int hisi_regulator_set_mode(struct regulator_dev *dev,
 	}
 
 	/* set mode */
-	hisi_pmic_rmw(pmic, sreg->register_info.ctrl_reg,
-		      sreg->register_info.eco_mode_mask,
-		eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1));
+	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
+		      sreg->eco_mode_mask,
+		eco_mode << (ffs(sreg->eco_mode_mask) - 1));
 
-	pr_debug("<[%s]: ctrl_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n",
+	pr_debug("<[%s]: enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n",
 		 __func__,
-		sreg->register_info.ctrl_reg,
-		sreg->register_info.eco_mode_mask,
-		eco_mode << (ffs(sreg->register_info.eco_mode_mask) - 1));
+		rdev->desc->enable_reg,
+		sreg->eco_mode_mask,
+		eco_mode << (ffs(sreg->eco_mode_mask) - 1));
 	return 0;
 }
 
-static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *dev,
+static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *rdev,
 						    int input_uV, int output_uV,
 						    int load_uA)
 {
-	struct hisi_regulator *sreg = rdev_get_drvdata(dev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 
 	if (load_uA || ((unsigned int)load_uA > sreg->eco_uA))
 		return REGULATOR_MODE_NORMAL;
@@ -228,42 +218,43 @@ static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *dev,
 		return REGULATOR_MODE_IDLE;
 }
 
-static int hisi_dt_parse_common(struct hisi_regulator *sreg,
-				struct platform_device *pdev)
+static int hisi_dt_parse(struct platform_device *pdev,
+			 struct hi6421v600_regulator *sreg,
+			 struct regulator_desc *rdesc)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
-	struct regulator_desc *rdesc = &sreg->rdesc;
 	unsigned int register_info[3] = {0};
-	int ret = 0;
+	unsigned int *v_table;
+	int ret;
 
-	/* parse .register_info.ctrl_reg */
+	/* parse .register_info.enable_reg */
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-ctrl",
 					 register_info, 3);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-ctrl property set\n");
-		goto dt_parse_common_end;
+		return ret;
 	}
-	sreg->register_info.ctrl_reg = register_info[0];
-	sreg->register_info.enable_mask = register_info[1];
-	sreg->register_info.eco_mode_mask = register_info[2];
+	rdesc->enable_reg = register_info[0];
+	rdesc->enable_mask = register_info[1];
+	sreg->eco_mode_mask = register_info[2];
 
-	/* parse .register_info.vset_reg */
+	/* parse .register_info.vsel_reg */
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset",
 					 register_info, 2);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-vset property set\n");
-		goto dt_parse_common_end;
+		return ret;
 	}
-	sreg->register_info.vset_reg = register_info[0];
-	sreg->register_info.vset_mask = register_info[1];
+	rdesc->vsel_reg = register_info[0];
+	rdesc->vsel_mask = register_info[1];
 
 	/* parse .off-on-delay */
 	ret = of_property_read_u32(np, "hisilicon,hisi-off-on-delay-us",
-				   &sreg->off_on_delay);
+				   &rdesc->off_on_delay);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-off-on-delay-us property set\n");
-		goto dt_parse_common_end;
+		return ret;
 	}
 
 	/* parse .enable_time */
@@ -271,7 +262,7 @@ static int hisi_dt_parse_common(struct hisi_regulator *sreg,
 				   &rdesc->enable_time);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-enable-time-us property set\n");
-		goto dt_parse_common_end;
+		return ret;
 	}
 
 	/* parse .eco_uA */
@@ -282,56 +273,24 @@ static int hisi_dt_parse_common(struct hisi_regulator *sreg,
 		ret = 0;
 	}
 
-dt_parse_common_end:
-	return ret;
-}
+	/* parse volt_table */
 
-static int hisi_dt_parse_ldo(struct hisi_regulator *sreg,
-			     struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	struct regulator_desc *rdesc = &sreg->rdesc;
-	unsigned int *v_table;
-	int ret = 0;
+	rdesc->n_voltages = of_property_count_u32_elems(np, "hisilicon,hisi-vset-table");
 
-	/* parse .n_voltages, and .volt_table */
-	ret = of_property_read_u32(np, "hisilicon,hisi-n-voltages",
-				   &rdesc->n_voltages);
-	if (ret) {
-		dev_err(dev, "no hisilicon,hisi-n-voltages property set\n");
-		goto dt_parse_ldo_end;
-	}
-
-	/* alloc space for .volt_table */
 	v_table = devm_kzalloc(dev, sizeof(unsigned int) * rdesc->n_voltages,
 			       GFP_KERNEL);
-	if (unlikely(!v_table)) {
-		ret = -ENOMEM;
-		dev_err(dev, "no memory for .volt_table\n");
-		goto dt_parse_ldo_end;
-	}
+	if (unlikely(!v_table))
+		return  -ENOMEM;
+	rdesc->volt_table = v_table;
 
 	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset-table",
 					 v_table, rdesc->n_voltages);
 	if (ret) {
 		dev_err(dev, "no hisilicon,hisi-vset-table property set\n");
-		goto dt_parse_ldo_end1;
+		return ret;
 	}
-	rdesc->volt_table = v_table;
 
-	/* parse hisi regulator's dt common part */
-	ret = hisi_dt_parse_common(sreg, pdev);
-	if (ret) {
-		dev_err(dev, "failure in hisi_dt_parse_common\n");
-		goto dt_parse_ldo_end1;
-	}
-
-	return ret;
-
-dt_parse_ldo_end1:
-dt_parse_ldo_end:
-	return ret;
+	return 0;
 }
 
 static struct regulator_ops hisi_ldo_rops = {
@@ -364,7 +323,7 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	struct device *dev = &pdev->dev;
 	struct regulator_desc *rdesc;
 	struct regulator_dev *rdev;
-	struct hisi_regulator *sreg = NULL;
+	struct hi6421v600_regulator *sreg = NULL;
 	struct regulator_init_data *initdata;
 	struct regulator_config config = { };
 	struct regulation_constraints *constraint;
@@ -401,11 +360,10 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	if (!sreg)
 		return -ENOMEM;
 
-	sreg->name = initdata->constraints.name;
 	sreg->pmic = pmic;
 	rdesc = &sreg->rdesc;
 
-	rdesc->name = sreg->name;
+	rdesc->name = initdata->constraints.name;
 	rdesc->ops = &hisi_ldo_rops;
 	rdesc->type = REGULATOR_VOLTAGE;
 	rdesc->min_uV = initdata->constraints.min_uV;
@@ -415,7 +373,7 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 		initdata->supply_regulator = supplyname;
 
 	/* parse device tree data for regulator specific */
-	ret = hisi_dt_parse_ldo(sreg, pdev);
+	ret = hisi_dt_parse(pdev, sreg, rdesc);
 	if (ret) {
 		dev_err(dev, "device tree parameter parse error!\n");
 		goto hisi_probe_end;
@@ -501,13 +459,13 @@ static int hisi_regulator_probe(struct platform_device *pdev)
 static int hisi_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = dev_get_drvdata(&pdev->dev);
-	struct hisi_regulator *sreg = rdev_get_drvdata(rdev);
+	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 
 	regulator_unregister(rdev);
 
 	/* TODO: should i worry about that? devm_kzalloc */
-	if (sreg->rdesc.volt_table)
-		devm_kfree(&pdev->dev, (unsigned int *)sreg->rdesc.volt_table);
+	if (rdev->desc->volt_table)
+		devm_kfree(&pdev->dev, (unsigned int *)rdev->desc->volt_table);
 
 	kfree(sreg);
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 29/44] staging: regulator: hi6421v600-regulator: cleanup debug messages
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (27 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 28/44] staging: regulator: hi6421v600-regulator: cleanup struct hisi_regulator Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 30/44] staging: regulator: hi6421v600-regulator: use shorter names for OF properties Mauro Carvalho Chehab
                   ` (16 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

- use dev_foo() instead of pr_foo();
- cleanup the messages, making them more standard and easier
  to understand.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 76 ++++++++++++-------
 1 file changed, 47 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 7d82d11f4b52..2d1096ecb277 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -59,9 +59,11 @@ static int hisi_regulator_is_enabled(struct regulator_dev *rdev)
 	struct hisi_pmic *pmic = sreg->pmic;
 
 	reg_val = hisi_pmic_read(pmic, rdev->desc->enable_reg);
-	pr_debug("<[%s]: enable_reg=0x%x,enable_state=%d>\n",
+
+	dev_dbg(&rdev->dev,
+		"%s: enable_reg=0x%x, val= 0x%x, enable_state=%d\n",
 		 __func__, rdev->desc->enable_reg,
-		(reg_val & rdev->desc->enable_mask));
+		reg_val, (reg_val & rdev->desc->enable_mask));
 
 	return ((reg_val & rdev->desc->enable_mask) != 0);
 }
@@ -74,7 +76,8 @@ static int hisi_regulator_enable(struct regulator_dev *rdev)
 	/* keep a distance of off_on_delay from last time disabled */
 	usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 1000);
 
-	pr_debug("<[%s]: off_on_delay=%dus>\n", __func__, rdev->desc->off_on_delay);
+	dev_dbg(&rdev->dev, "%s: off_on_delay=%d us\n",
+		__func__, rdev->desc->off_on_delay);
 
 	/* cannot enable more than one regulator at one time */
 	mutex_lock(&enable_mutex);
@@ -85,7 +88,7 @@ static int hisi_regulator_enable(struct regulator_dev *rdev)
 	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
 		      rdev->desc->enable_mask,
 				rdev->desc->enable_mask);
-	pr_debug("<[%s]: enable_reg=0x%x,enable_mask=0x%x>\n",
+	dev_dbg(&rdev->dev, "%s: enable_reg=0x%x, enable_mask=0x%x\n",
 		 __func__, rdev->desc->enable_reg,
 		 rdev->desc->enable_mask);
 
@@ -111,16 +114,20 @@ static int hisi_regulator_get_voltage(struct regulator_dev *rdev)
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 	u32 reg_val, selector;
+	int vol;
 
 	/* get voltage selector */
 	reg_val = hisi_pmic_read(pmic, rdev->desc->vsel_reg);
-	pr_debug("<[%s]: vsel_reg=0x%x>\n",
-		 __func__, rdev->desc->vsel_reg);
-
 	selector = (reg_val & rdev->desc->vsel_mask) >>
 				(ffs(rdev->desc->vsel_mask) - 1);
 
-	return rdev->desc->ops->list_voltage(rdev, selector);
+	vol = rdev->desc->ops->list_voltage(rdev, selector);
+
+	dev_dbg(&rdev->dev,
+		"%s: vsel_reg=0x%x, val=0x%x, entry=0x%x, voltage=%d mV\n",
+		 __func__, rdev->desc->vsel_reg, reg_val, selector, vol/ 1000);
+
+	return vol;
 }
 
 static int hisi_regulator_set_voltage(struct regulator_dev *rdev,
@@ -129,10 +136,14 @@ static int hisi_regulator_set_voltage(struct regulator_dev *rdev,
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 	u32 vsel;
-	int ret = 0;
+	int uV, ret = 0;
 
 	for (vsel = 0; vsel < rdev->desc->n_voltages; vsel++) {
-		int uV = rdev->desc->volt_table[vsel];
+		uV = rdev->desc->volt_table[vsel];
+		dev_dbg(&rdev->dev,
+			"%s: min %d, max %d, value[%u] = %d\n",
+			__func__, min_uV, max_uV, vsel, uV);
+
 		/* Break at the first in-range value */
 		if (min_uV <= uV && uV <= max_uV)
 			break;
@@ -146,13 +157,14 @@ static int hisi_regulator_set_voltage(struct regulator_dev *rdev,
 	/* set voltage selector */
 	hisi_pmic_rmw(pmic, rdev->desc->vsel_reg,
 		      rdev->desc->vsel_mask,
-		vsel << (ffs(rdev->desc->vsel_mask) - 1));
+		      vsel << (ffs(rdev->desc->vsel_mask) - 1));
 
-	pr_debug("<[%s]: vsel_reg=0x%x, vsel_mask=0x%x, value=0x%x>\n",
+	dev_dbg(&rdev->dev,
+		"%s: vsel_reg=0x%x, vsel_mask=0x%x, value=0x%x, voltage=%d mV\n",
 		 __func__,
 		 rdev->desc->vsel_reg,
 		 rdev->desc->vsel_mask,
-		 vsel << (ffs(rdev->desc->vsel_mask) - 1));
+		 vsel << (ffs(rdev->desc->vsel_mask) - 1), uV / 1000);
 
 	return ret;
 }
@@ -162,17 +174,21 @@ static unsigned int hisi_regulator_get_mode(struct regulator_dev *rdev)
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
 	u32 reg_val;
+	unsigned int mode;
 
 	reg_val = hisi_pmic_read(pmic, rdev->desc->enable_reg);
-	pr_debug("<[%s]: reg_val=%d, enable_reg=0x%x, eco_mode_mask=0x%x>\n",
-		 __func__, reg_val,
-		rdev->desc->enable_reg,
-		sreg->eco_mode_mask);
 
 	if (reg_val & sreg->eco_mode_mask)
-		return REGULATOR_MODE_IDLE;
+		mode = REGULATOR_MODE_IDLE;
 	else
-		return REGULATOR_MODE_NORMAL;
+		mode = REGULATOR_MODE_NORMAL;
+
+	dev_dbg(&rdev->dev,
+		"%s: enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n",
+		 __func__, rdev->desc->enable_reg, sreg->eco_mode_mask, reg_val,
+		 mode == REGULATOR_MODE_IDLE ? "idle" : "normal");
+
+	return mode;
 }
 
 static int hisi_regulator_set_mode(struct regulator_dev *rdev,
@@ -198,7 +214,8 @@ static int hisi_regulator_set_mode(struct regulator_dev *rdev,
 		      sreg->eco_mode_mask,
 		eco_mode << (ffs(sreg->eco_mode_mask) - 1));
 
-	pr_debug("<[%s]: enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x>\n",
+	dev_dbg(&rdev->dev,
+		"%s: enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n",
 		 __func__,
 		rdev->desc->enable_reg,
 		sreg->eco_mode_mask,
@@ -212,10 +229,13 @@ static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *rdev,
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 
-	if (load_uA || ((unsigned int)load_uA > sreg->eco_uA))
+	if (load_uA || ((unsigned int)load_uA > sreg->eco_uA)) {
+		dev_dbg(&rdev->dev, "%s: normal mode", __func__);
 		return REGULATOR_MODE_NORMAL;
-	else
+	} else {
+		dev_dbg(&rdev->dev, "%s: idle mode", __func__);
 		return REGULATOR_MODE_IDLE;
+	}
 }
 
 static int hisi_dt_parse(struct platform_device *pdev,
@@ -333,7 +353,7 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 
 	initdata = of_get_regulator_init_data(dev, np, NULL);
 	if (!initdata) {
-		pr_err("get regulator init data error !\n");
+		dev_err(dev, "failed to get regulator data\n");
 		return -EINVAL;
 	}
 
@@ -343,14 +363,14 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	ret = of_property_read_u32_array(np, "hisilicon,valid-modes-mask",
 					 &constraint->valid_modes_mask, 1);
 	if (ret) {
-		pr_err("no hisilicon,valid-modes-mask property set\n");
+		dev_err(dev, "no valid modes mask\n");
 		ret = -ENODEV;
 		return ret;
 	}
 	ret = of_property_read_u32_array(np, "hisilicon,valid-idle-mask",
 					 &temp_modes, 1);
 	if (ret) {
-		pr_err("no hisilicon,valid-modes-mask property set\n");
+		dev_err(dev, "no valid idle mask\n");
 		ret = -ENODEV;
 		return ret;
 	}
@@ -374,10 +394,8 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 
 	/* parse device tree data for regulator specific */
 	ret = hisi_dt_parse(pdev, sreg, rdesc);
-	if (ret) {
-		dev_err(dev, "device tree parameter parse error!\n");
+	if (ret)
 		goto hisi_probe_end;
-	}
 
 	config.dev = &pdev->dev;
 	config.init_data = initdata;
@@ -393,7 +411,7 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 		goto hisi_probe_end;
 	}
 
-	pr_debug("[%s]:valid_modes_mask[0x%x], valid_ops_mask[0x%x]\n",
+	dev_dbg(dev, "%s:valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n",
 		 rdesc->name,
 		 constraint->valid_modes_mask, constraint->valid_ops_mask);
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 30/44] staging: regulator: hi6421v600-regulator: use shorter names for OF properties
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (28 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 29/44] staging: regulator: hi6421v600-regulator: cleanup debug messages Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 31/44] staging: regulator: hi6421v600-regulator: better handle modes Mauro Carvalho Chehab
                   ` (15 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Simplify the names of the OF properties, in order to make
them similar to other drivers and to make easier to understand
what each property means.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 52 ++++++++-----------
 1 file changed, 21 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 2d1096ecb277..e4a64893a7ad 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -196,14 +196,14 @@ static int hisi_regulator_set_mode(struct regulator_dev *rdev,
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hisi_pmic *pmic = sreg->pmic;
-	u32 eco_mode;
+	u32 val;
 
 	switch (mode) {
 	case REGULATOR_MODE_NORMAL:
-		eco_mode = HISI_ECO_MODE_DISABLE;
+		val = 0;
 		break;
 	case REGULATOR_MODE_IDLE:
-		eco_mode = HISI_ECO_MODE_ENABLE;
+		val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1);
 		break;
 	default:
 		return -EINVAL;
@@ -211,15 +211,12 @@ static int hisi_regulator_set_mode(struct regulator_dev *rdev,
 
 	/* set mode */
 	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
-		      sreg->eco_mode_mask,
-		eco_mode << (ffs(sreg->eco_mode_mask) - 1));
+		      sreg->eco_mode_mask, val);
 
 	dev_dbg(&rdev->dev,
 		"%s: enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n",
-		 __func__,
-		rdev->desc->enable_reg,
-		sreg->eco_mode_mask,
-		eco_mode << (ffs(sreg->eco_mode_mask) - 1));
+		 __func__, rdev->desc->enable_reg, sreg->eco_mode_mask, val);
+
 	return 0;
 }
 
@@ -249,10 +246,10 @@ static int hisi_dt_parse(struct platform_device *pdev,
 	int ret;
 
 	/* parse .register_info.enable_reg */
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-ctrl",
+	ret = of_property_read_u32_array(np, "hi6421-ctrl",
 					 register_info, 3);
 	if (ret) {
-		dev_err(dev, "no hisilicon,hisi-ctrl property set\n");
+		dev_err(dev, "no hi6421-ctrl property set\n");
 		return ret;
 	}
 	rdesc->enable_reg = register_info[0];
@@ -260,33 +257,33 @@ static int hisi_dt_parse(struct platform_device *pdev,
 	sreg->eco_mode_mask = register_info[2];
 
 	/* parse .register_info.vsel_reg */
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset",
+	ret = of_property_read_u32_array(np, "hi6421-vsel",
 					 register_info, 2);
 	if (ret) {
-		dev_err(dev, "no hisilicon,hisi-vset property set\n");
+		dev_err(dev, "no hi6421-vsel property set\n");
 		return ret;
 	}
 	rdesc->vsel_reg = register_info[0];
 	rdesc->vsel_mask = register_info[1];
 
 	/* parse .off-on-delay */
-	ret = of_property_read_u32(np, "hisilicon,hisi-off-on-delay-us",
+	ret = of_property_read_u32(np, "off-on-delay-us",
 				   &rdesc->off_on_delay);
 	if (ret) {
-		dev_err(dev, "no hisilicon,hisi-off-on-delay-us property set\n");
+		dev_err(dev, "no off-on-delay-us property set\n");
 		return ret;
 	}
 
 	/* parse .enable_time */
-	ret = of_property_read_u32(np, "hisilicon,hisi-enable-time-us",
+	ret = of_property_read_u32(np, "startup-delay-us",
 				   &rdesc->enable_time);
 	if (ret) {
-		dev_err(dev, "no hisilicon,hisi-enable-time-us property set\n");
+		dev_err(dev, "no startup-delay-us property set\n");
 		return ret;
 	}
 
 	/* parse .eco_uA */
-	ret = of_property_read_u32(np, "hisilicon,hisi-eco-microamp",
+	ret = of_property_read_u32(np, "eco-microamp",
 				   &sreg->eco_uA);
 	if (ret) {
 		sreg->eco_uA = 0;
@@ -295,7 +292,7 @@ static int hisi_dt_parse(struct platform_device *pdev,
 
 	/* parse volt_table */
 
-	rdesc->n_voltages = of_property_count_u32_elems(np, "hisilicon,hisi-vset-table");
+	rdesc->n_voltages = of_property_count_u32_elems(np, "voltage-table");
 
 	v_table = devm_kzalloc(dev, sizeof(unsigned int) * rdesc->n_voltages,
 			       GFP_KERNEL);
@@ -303,10 +300,10 @@ static int hisi_dt_parse(struct platform_device *pdev,
 		return  -ENOMEM;
 	rdesc->volt_table = v_table;
 
-	ret = of_property_read_u32_array(np, "hisilicon,hisi-vset-table",
+	ret = of_property_read_u32_array(np, "voltage-table",
 					 v_table, rdesc->n_voltages);
 	if (ret) {
-		dev_err(dev, "no hisilicon,hisi-vset-table property set\n");
+		dev_err(dev, "no voltage-table property set\n");
 		return ret;
 	}
 
@@ -329,13 +326,6 @@ static struct regulator_ops hisi_ldo_rops = {
  * Used only for parsing the DT properties
  */
 
-static const struct of_device_id of_hisi_pmic_match_tbl[] = {
-	{
-		.compatible = "hisilicon,hi6421-spmi-pmic-ldo",
-	},
-	{ }
-};
-
 static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 				    struct device_node *np,
 				    struct hisi_pmic *pmic)
@@ -360,14 +350,14 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	/* hisi regulator supports two modes */
 	constraint = &initdata->constraints;
 
-	ret = of_property_read_u32_array(np, "hisilicon,valid-modes-mask",
+	ret = of_property_read_u32_array(np, "valid-modes-mask",
 					 &constraint->valid_modes_mask, 1);
 	if (ret) {
 		dev_err(dev, "no valid modes mask\n");
 		ret = -ENODEV;
 		return ret;
 	}
-	ret = of_property_read_u32_array(np, "hisilicon,valid-idle-mask",
+	ret = of_property_read_u32_array(np, "valid-idle-mask",
 					 &temp_modes, 1);
 	if (ret) {
 		dev_err(dev, "no valid idle mask\n");
@@ -388,7 +378,7 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	rdesc->type = REGULATOR_VOLTAGE;
 	rdesc->min_uV = initdata->constraints.min_uV;
 
-	supplyname = of_get_property(np, "hisilicon,supply_name", NULL);
+	supplyname = of_get_property(np, "supply_name", NULL);
 	if (supplyname)
 		initdata->supply_regulator = supplyname;
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 31/44] staging: regulator: hi6421v600-regulator: better handle modes
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (29 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 30/44] staging: regulator: hi6421v600-regulator: use shorter names for OF properties Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 32/44] staging: regulator: hi6421v600-regulator: change namespace Mauro Carvalho Chehab
                   ` (14 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Instead of implementing a custom set of properties, set
valid_modes_mask based on having or not a mask for enabling
the eco_mode.

This makes the code clearer, and remove some uneeded props
from DT.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 32 ++++++-------------
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index e4a64893a7ad..bde7fa4d7e8f 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -338,7 +338,6 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	struct regulator_config config = { };
 	struct regulation_constraints *constraint;
 	const char *supplyname = NULL;
-	unsigned int temp_modes;
 	int ret = 0;
 
 	initdata = of_get_regulator_init_data(dev, np, NULL);
@@ -347,25 +346,6 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
-	/* hisi regulator supports two modes */
-	constraint = &initdata->constraints;
-
-	ret = of_property_read_u32_array(np, "valid-modes-mask",
-					 &constraint->valid_modes_mask, 1);
-	if (ret) {
-		dev_err(dev, "no valid modes mask\n");
-		ret = -ENODEV;
-		return ret;
-	}
-	ret = of_property_read_u32_array(np, "valid-idle-mask",
-					 &temp_modes, 1);
-	if (ret) {
-		dev_err(dev, "no valid idle mask\n");
-		ret = -ENODEV;
-		return ret;
-	}
-	constraint->valid_ops_mask |= temp_modes;
-
 	sreg = kzalloc(sizeof(*sreg), GFP_KERNEL);
 	if (!sreg)
 		return -ENOMEM;
@@ -387,6 +367,15 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	if (ret)
 		goto hisi_probe_end;
 
+	/* hisi regulator supports two modes */
+	constraint = &initdata->constraints;
+
+	constraint->valid_modes_mask = REGULATOR_MODE_NORMAL;
+	if (sreg->eco_mode_mask) {
+		constraint->valid_modes_mask |= REGULATOR_MODE_IDLE;
+		constraint->valid_ops_mask |= REGULATOR_CHANGE_MODE;
+	}
+
 	config.dev = &pdev->dev;
 	config.init_data = initdata;
 	config.driver_data = sreg;
@@ -401,8 +390,7 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 		goto hisi_probe_end;
 	}
 
-	dev_dbg(dev, "%s:valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n",
-		 rdesc->name,
+	dev_dbg(dev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n",
 		 constraint->valid_modes_mask, constraint->valid_ops_mask);
 
 	dev_set_drvdata(dev, rdev);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 32/44] staging: regulator: hi6421v600-regulator: change namespace
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (30 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 31/44] staging: regulator: hi6421v600-regulator: better handle modes Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 33/44] staging: regulator: hi6421v600-regulator: convert to use get/set voltage_sel Mauro Carvalho Chehab
                   ` (13 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Rename the functions used internally inside the driver in
order for them to follow the driver's name.

While here, get rid of some unused definitions at the
header file.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 94 +++++++++----------
 1 file changed, 47 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index bde7fa4d7e8f..f77ecea78597 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -41,7 +41,7 @@
 
 struct hi6421v600_regulator {
 	struct regulator_desc rdesc;
-	struct hisi_pmic *pmic;
+	struct hi6421_spmi_pmic *pmic;
 	u8 eco_mode_mask;
 	u32 eco_uA;
 };
@@ -52,13 +52,13 @@ static DEFINE_MUTEX(enable_mutex);
  * microseconds after 'since'.
  */
 
-static int hisi_regulator_is_enabled(struct regulator_dev *rdev)
+static int hi6421_spmi_regulator_is_enabled(struct regulator_dev *rdev)
 {
 	u32 reg_val;
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
-	struct hisi_pmic *pmic = sreg->pmic;
+	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 
-	reg_val = hisi_pmic_read(pmic, rdev->desc->enable_reg);
+	reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg);
 
 	dev_dbg(&rdev->dev,
 		"%s: enable_reg=0x%x, val= 0x%x, enable_state=%d\n",
@@ -68,10 +68,10 @@ static int hisi_regulator_is_enabled(struct regulator_dev *rdev)
 	return ((reg_val & rdev->desc->enable_mask) != 0);
 }
 
-static int hisi_regulator_enable(struct regulator_dev *rdev)
+static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
-	struct hisi_pmic *pmic = sreg->pmic;
+	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 
 	/* keep a distance of off_on_delay from last time disabled */
 	usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 1000);
@@ -85,7 +85,7 @@ static int hisi_regulator_enable(struct regulator_dev *rdev)
 		     HISI_REGS_ENA_PROTECT_TIME + 1000);
 
 	/* set enable register */
-	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
+	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
 		      rdev->desc->enable_mask,
 				rdev->desc->enable_mask);
 	dev_dbg(&rdev->dev, "%s: enable_reg=0x%x, enable_mask=0x%x\n",
@@ -97,27 +97,27 @@ static int hisi_regulator_enable(struct regulator_dev *rdev)
 	return 0;
 }
 
-static int hisi_regulator_disable(struct regulator_dev *rdev)
+static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
-	struct hisi_pmic *pmic = sreg->pmic;
+	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 
 	/* set enable register to 0 */
-	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
+	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
 		      rdev->desc->enable_mask, 0);
 
 	return 0;
 }
 
-static int hisi_regulator_get_voltage(struct regulator_dev *rdev)
+static int hi6421_spmi_regulator_get_voltage(struct regulator_dev *rdev)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
-	struct hisi_pmic *pmic = sreg->pmic;
+	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 	u32 reg_val, selector;
 	int vol;
 
 	/* get voltage selector */
-	reg_val = hisi_pmic_read(pmic, rdev->desc->vsel_reg);
+	reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->vsel_reg);
 	selector = (reg_val & rdev->desc->vsel_mask) >>
 				(ffs(rdev->desc->vsel_mask) - 1);
 
@@ -130,11 +130,11 @@ static int hisi_regulator_get_voltage(struct regulator_dev *rdev)
 	return vol;
 }
 
-static int hisi_regulator_set_voltage(struct regulator_dev *rdev,
+static int hi6421_spmi_regulator_set_voltage(struct regulator_dev *rdev,
 				      int min_uV, int max_uV, unsigned int *selector)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
-	struct hisi_pmic *pmic = sreg->pmic;
+	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 	u32 vsel;
 	int uV, ret = 0;
 
@@ -155,7 +155,7 @@ static int hisi_regulator_set_voltage(struct regulator_dev *rdev,
 
 	*selector = vsel;
 	/* set voltage selector */
-	hisi_pmic_rmw(pmic, rdev->desc->vsel_reg,
+	hi6421_spmi_pmic_rmw(pmic, rdev->desc->vsel_reg,
 		      rdev->desc->vsel_mask,
 		      vsel << (ffs(rdev->desc->vsel_mask) - 1));
 
@@ -169,14 +169,14 @@ static int hisi_regulator_set_voltage(struct regulator_dev *rdev,
 	return ret;
 }
 
-static unsigned int hisi_regulator_get_mode(struct regulator_dev *rdev)
+static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
-	struct hisi_pmic *pmic = sreg->pmic;
+	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 	u32 reg_val;
 	unsigned int mode;
 
-	reg_val = hisi_pmic_read(pmic, rdev->desc->enable_reg);
+	reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg);
 
 	if (reg_val & sreg->eco_mode_mask)
 		mode = REGULATOR_MODE_IDLE;
@@ -191,11 +191,11 @@ static unsigned int hisi_regulator_get_mode(struct regulator_dev *rdev)
 	return mode;
 }
 
-static int hisi_regulator_set_mode(struct regulator_dev *rdev,
+static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
 				   unsigned int mode)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
-	struct hisi_pmic *pmic = sreg->pmic;
+	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 	u32 val;
 
 	switch (mode) {
@@ -210,8 +210,8 @@ static int hisi_regulator_set_mode(struct regulator_dev *rdev,
 	}
 
 	/* set mode */
-	hisi_pmic_rmw(pmic, rdev->desc->enable_reg,
-		      sreg->eco_mode_mask, val);
+	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
+			     sreg->eco_mode_mask, val);
 
 	dev_dbg(&rdev->dev,
 		"%s: enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n",
@@ -220,7 +220,7 @@ static int hisi_regulator_set_mode(struct regulator_dev *rdev,
 	return 0;
 }
 
-static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *rdev,
+static unsigned int hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
 						    int input_uV, int output_uV,
 						    int load_uA)
 {
@@ -235,7 +235,7 @@ static unsigned int hisi_regulator_get_optimum_mode(struct regulator_dev *rdev,
 	}
 }
 
-static int hisi_dt_parse(struct platform_device *pdev,
+static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 			 struct hi6421v600_regulator *sreg,
 			 struct regulator_desc *rdesc)
 {
@@ -310,25 +310,25 @@ static int hisi_dt_parse(struct platform_device *pdev,
 	return 0;
 }
 
-static struct regulator_ops hisi_ldo_rops = {
-	.is_enabled = hisi_regulator_is_enabled,
-	.enable = hisi_regulator_enable,
-	.disable = hisi_regulator_disable,
+static struct regulator_ops hi6421_spmi_ldo_rops = {
+	.is_enabled = hi6421_spmi_regulator_is_enabled,
+	.enable = hi6421_spmi_regulator_enable,
+	.disable = hi6421_spmi_regulator_disable,
 	.list_voltage = regulator_list_voltage_table,
-	.get_voltage = hisi_regulator_get_voltage,
-	.set_voltage = hisi_regulator_set_voltage,
-	.get_mode = hisi_regulator_get_mode,
-	.set_mode = hisi_regulator_set_mode,
-	.get_optimum_mode = hisi_regulator_get_optimum_mode,
+	.get_voltage = hi6421_spmi_regulator_get_voltage,
+	.set_voltage = hi6421_spmi_regulator_set_voltage,
+	.get_mode = hi6421_spmi_regulator_get_mode,
+	.set_mode = hi6421_spmi_regulator_set_mode,
+	.get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode,
 };
 
 /*
  * Used only for parsing the DT properties
  */
 
-static int hisi_regulator_probe_ldo(struct platform_device *pdev,
+static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
 				    struct device_node *np,
-				    struct hisi_pmic *pmic)
+				    struct hi6421_spmi_pmic *pmic)
 {
 	struct device *dev = &pdev->dev;
 	struct regulator_desc *rdesc;
@@ -354,7 +354,7 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 	rdesc = &sreg->rdesc;
 
 	rdesc->name = initdata->constraints.name;
-	rdesc->ops = &hisi_ldo_rops;
+	rdesc->ops = &hi6421_spmi_ldo_rops;
 	rdesc->type = REGULATOR_VOLTAGE;
 	rdesc->min_uV = initdata->constraints.min_uV;
 
@@ -363,9 +363,9 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 		initdata->supply_regulator = supplyname;
 
 	/* parse device tree data for regulator specific */
-	ret = hisi_dt_parse(pdev, sreg, rdesc);
+	ret = hi6421_spmi_dt_parse(pdev, sreg, rdesc);
 	if (ret)
-		goto hisi_probe_end;
+		goto probe_end;
 
 	/* hisi regulator supports two modes */
 	constraint = &initdata->constraints;
@@ -387,27 +387,27 @@ static int hisi_regulator_probe_ldo(struct platform_device *pdev,
 		dev_err(dev, "failed to register %s\n",
 			rdesc->name);
 		ret = PTR_ERR(rdev);
-		goto hisi_probe_end;
+		goto probe_end;
 	}
 
 	dev_dbg(dev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n",
 		 constraint->valid_modes_mask, constraint->valid_ops_mask);
 
 	dev_set_drvdata(dev, rdev);
-hisi_probe_end:
+probe_end:
 	if (ret)
 		kfree(sreg);
 	return ret;
 }
 
 
-static int hisi_regulator_probe(struct platform_device *pdev)
+static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
 {
 	struct device *pmic_dev = pdev->dev.parent;
 	struct device_node *np = pmic_dev->of_node;
 	struct device_node *regulators, *child;
 	struct platform_device *new_pdev;
-	struct hisi_pmic *pmic;
+	struct hi6421_spmi_pmic *pmic;
 	int ret;
 
 	dev_dbg(&pdev->dev, "probing hi6421v600 regulator\n");
@@ -442,7 +442,7 @@ static int hisi_regulator_probe(struct platform_device *pdev)
 			continue;
 		}
 
-		ret = hisi_regulator_probe_ldo(new_pdev, child, pmic);
+		ret = hi6421_spmi_regulator_probe_ldo(new_pdev, child, pmic);
 		if (ret < 0)
 			platform_device_put(new_pdev);
 	}
@@ -452,7 +452,7 @@ static int hisi_regulator_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int hisi_regulator_remove(struct platform_device *pdev)
+static int hi6421_spmi_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = dev_get_drvdata(&pdev->dev);
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
@@ -479,8 +479,8 @@ static struct platform_driver hi6421v600_regulator_driver = {
 	.driver = {
 		.name	= "hi6421v600-regulator",
 	},
-	.probe	= hisi_regulator_probe,
-	.remove	= hisi_regulator_remove,
+	.probe	= hi6421_spmi_regulator_probe,
+	.remove	= hi6421_spmi_regulator_remove,
 };
 module_platform_driver(hi6421v600_regulator_driver);
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 33/44] staging: regulator: hi6421v600-regulator: convert to use get/set voltage_sel
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (31 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 32/44] staging: regulator: hi6421v600-regulator: change namespace Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 34/44] staging: regulator: hi6421v600-regulator: don't use usleep_range for off_on_delay Mauro Carvalho Chehab
                   ` (12 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

As the supported LDOs on this driver are all using a selector,
change the implementation to use get_voltage_sel and
set_voltage_sel ops.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 58 +++++++------------
 1 file changed, 22 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index f77ecea78597..abd1f43dd5ec 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -86,8 +86,8 @@ static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
 
 	/* set enable register */
 	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
-		      rdev->desc->enable_mask,
-				rdev->desc->enable_mask);
+			     rdev->desc->enable_mask,
+			     rdev->desc->enable_mask);
 	dev_dbg(&rdev->dev, "%s: enable_reg=0x%x, enable_mask=0x%x\n",
 		 __func__, rdev->desc->enable_reg,
 		 rdev->desc->enable_mask);
@@ -109,64 +109,49 @@ static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev)
 	return 0;
 }
 
-static int hi6421_spmi_regulator_get_voltage(struct regulator_dev *rdev)
+static int hi6421_spmi_regulator_get_voltage_sel(struct regulator_dev *rdev)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 	u32 reg_val, selector;
-	int vol;
 
 	/* get voltage selector */
 	reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->vsel_reg);
-	selector = (reg_val & rdev->desc->vsel_mask) >>
-				(ffs(rdev->desc->vsel_mask) - 1);
 
-	vol = rdev->desc->ops->list_voltage(rdev, selector);
+	selector = (reg_val & rdev->desc->vsel_mask) >>	(ffs(rdev->desc->vsel_mask) - 1);
 
 	dev_dbg(&rdev->dev,
-		"%s: vsel_reg=0x%x, val=0x%x, entry=0x%x, voltage=%d mV\n",
-		 __func__, rdev->desc->vsel_reg, reg_val, selector, vol/ 1000);
+		"%s: vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n",
+		 __func__, rdev->desc->vsel_reg, reg_val, selector,
+		rdev->desc->ops->list_voltage(rdev, selector) / 1000);
 
-	return vol;
+	return selector;
 }
 
-static int hi6421_spmi_regulator_set_voltage(struct regulator_dev *rdev,
-				      int min_uV, int max_uV, unsigned int *selector)
+static int hi6421_spmi_regulator_set_voltage_sel(struct regulator_dev *rdev,
+						 unsigned int selector)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
-	u32 vsel;
-	int uV, ret = 0;
-
-	for (vsel = 0; vsel < rdev->desc->n_voltages; vsel++) {
-		uV = rdev->desc->volt_table[vsel];
-		dev_dbg(&rdev->dev,
-			"%s: min %d, max %d, value[%u] = %d\n",
-			__func__, min_uV, max_uV, vsel, uV);
-
-		/* Break at the first in-range value */
-		if (min_uV <= uV && uV <= max_uV)
-			break;
-	}
+	u32 reg_val;
 
 	/* unlikely to happen. sanity test done by regulator core */
-	if (unlikely(vsel == rdev->desc->n_voltages))
+	if (unlikely(selector >= rdev->desc->n_voltages))
 		return -EINVAL;
 
-	*selector = vsel;
+	reg_val = selector << (ffs(rdev->desc->vsel_mask) - 1);
+
 	/* set voltage selector */
 	hi6421_spmi_pmic_rmw(pmic, rdev->desc->vsel_reg,
-		      rdev->desc->vsel_mask,
-		      vsel << (ffs(rdev->desc->vsel_mask) - 1));
+			     rdev->desc->vsel_mask, reg_val);
 
 	dev_dbg(&rdev->dev,
-		"%s: vsel_reg=0x%x, vsel_mask=0x%x, value=0x%x, voltage=%d mV\n",
+		"%s: vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n",
 		 __func__,
-		 rdev->desc->vsel_reg,
-		 rdev->desc->vsel_mask,
-		 vsel << (ffs(rdev->desc->vsel_mask) - 1), uV / 1000);
+		 rdev->desc->vsel_reg, rdev->desc->vsel_mask, reg_val,
+		 rdev->desc->ops->list_voltage(rdev, selector) / 1000);
 
-	return ret;
+	return 0;
 }
 
 static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
@@ -315,8 +300,9 @@ static struct regulator_ops hi6421_spmi_ldo_rops = {
 	.enable = hi6421_spmi_regulator_enable,
 	.disable = hi6421_spmi_regulator_disable,
 	.list_voltage = regulator_list_voltage_table,
-	.get_voltage = hi6421_spmi_regulator_get_voltage,
-	.set_voltage = hi6421_spmi_regulator_set_voltage,
+	.map_voltage = regulator_map_voltage_iterate,
+	.get_voltage_sel = hi6421_spmi_regulator_get_voltage_sel,
+	.set_voltage_sel = hi6421_spmi_regulator_set_voltage_sel,
 	.get_mode = hi6421_spmi_regulator_get_mode,
 	.set_mode = hi6421_spmi_regulator_set_mode,
 	.get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 34/44] staging: regulator: hi6421v600-regulator: don't use usleep_range for off_on_delay
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (32 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 33/44] staging: regulator: hi6421v600-regulator: convert to use get/set voltage_sel Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 35/44] staging: regulator: hi6421v600-regulator: add a driver-specific debug macro Mauro Carvalho Chehab
                   ` (11 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

The regulator's core already handles it.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421v600-regulator.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index abd1f43dd5ec..31b8ff19fd31 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -73,9 +73,6 @@ static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 
-	/* keep a distance of off_on_delay from last time disabled */
-	usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 1000);
-
 	dev_dbg(&rdev->dev, "%s: off_on_delay=%d us\n",
 		__func__, rdev->desc->off_on_delay);
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 35/44] staging: regulator: hi6421v600-regulator: add a driver-specific debug macro
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (33 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 34/44] staging: regulator: hi6421v600-regulator: don't use usleep_range for off_on_delay Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 36/44] staging: regulator: hi6421v600-regulator: initialize ramp_delay Mauro Carvalho Chehab
                   ` (10 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Using dev_dbg() is not too nice, as, instead of printing the
name of the regulator, it prints "regulator.<number>", making
harder to associate what is happening with each ldo line.

So, add a debug-specific macro, which will print the rdev's
name, just like the regulator core.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 61 ++++++++++---------
 1 file changed, 32 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 31b8ff19fd31..5ddaf7f8cacc 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -39,6 +39,9 @@
 #include <linux/uaccess.h>
 #include <linux/spmi.h>
 
+#define rdev_dbg(rdev, fmt, arg...)	\
+		 pr_debug("%s: %s: " fmt, rdev->desc->name, __func__, ##arg)
+
 struct hi6421v600_regulator {
 	struct regulator_desc rdesc;
 	struct hi6421_spmi_pmic *pmic;
@@ -60,10 +63,10 @@ static int hi6421_spmi_regulator_is_enabled(struct regulator_dev *rdev)
 
 	reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg);
 
-	dev_dbg(&rdev->dev,
-		"%s: enable_reg=0x%x, val= 0x%x, enable_state=%d\n",
-		 __func__, rdev->desc->enable_reg,
-		reg_val, (reg_val & rdev->desc->enable_mask));
+	rdev_dbg(rdev,
+		 "enable_reg=0x%x, val= 0x%x, enable_state=%d\n",
+		 rdev->desc->enable_reg,
+		 reg_val, (reg_val & rdev->desc->enable_mask));
 
 	return ((reg_val & rdev->desc->enable_mask) != 0);
 }
@@ -73,21 +76,20 @@ static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 
-	dev_dbg(&rdev->dev, "%s: off_on_delay=%d us\n",
-		__func__, rdev->desc->off_on_delay);
-
 	/* cannot enable more than one regulator at one time */
 	mutex_lock(&enable_mutex);
 	usleep_range(HISI_REGS_ENA_PROTECT_TIME,
 		     HISI_REGS_ENA_PROTECT_TIME + 1000);
 
 	/* set enable register */
+	rdev_dbg(rdev,
+		 "off_on_delay=%d us, enable_reg=0x%x, enable_mask=0x%x\n",
+		 rdev->desc->off_on_delay, rdev->desc->enable_reg,
+		 rdev->desc->enable_mask);
+
 	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
 			     rdev->desc->enable_mask,
 			     rdev->desc->enable_mask);
-	dev_dbg(&rdev->dev, "%s: enable_reg=0x%x, enable_mask=0x%x\n",
-		 __func__, rdev->desc->enable_reg,
-		 rdev->desc->enable_mask);
 
 	mutex_unlock(&enable_mutex);
 
@@ -100,6 +102,9 @@ static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev)
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 
 	/* set enable register to 0 */
+	rdev_dbg(rdev, "enable_reg=0x%x, enable_mask=0x%x\n",
+		 rdev->desc->enable_reg, rdev->desc->enable_mask);
+
 	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
 		      rdev->desc->enable_mask, 0);
 
@@ -117,9 +122,9 @@ static int hi6421_spmi_regulator_get_voltage_sel(struct regulator_dev *rdev)
 
 	selector = (reg_val & rdev->desc->vsel_mask) >>	(ffs(rdev->desc->vsel_mask) - 1);
 
-	dev_dbg(&rdev->dev,
-		"%s: vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n",
-		 __func__, rdev->desc->vsel_reg, reg_val, selector,
+	rdev_dbg(rdev,
+		"vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n",
+		 rdev->desc->vsel_reg, reg_val, selector,
 		rdev->desc->ops->list_voltage(rdev, selector) / 1000);
 
 	return selector;
@@ -139,15 +144,14 @@ static int hi6421_spmi_regulator_set_voltage_sel(struct regulator_dev *rdev,
 	reg_val = selector << (ffs(rdev->desc->vsel_mask) - 1);
 
 	/* set voltage selector */
-	hi6421_spmi_pmic_rmw(pmic, rdev->desc->vsel_reg,
-			     rdev->desc->vsel_mask, reg_val);
-
-	dev_dbg(&rdev->dev,
-		"%s: vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n",
-		 __func__,
+	rdev_dbg(rdev,
+		"vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n",
 		 rdev->desc->vsel_reg, rdev->desc->vsel_mask, reg_val,
 		 rdev->desc->ops->list_voltage(rdev, selector) / 1000);
 
+	hi6421_spmi_pmic_rmw(pmic, rdev->desc->vsel_reg,
+			     rdev->desc->vsel_mask, reg_val);
+
 	return 0;
 }
 
@@ -165,9 +169,9 @@ static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
 	else
 		mode = REGULATOR_MODE_NORMAL;
 
-	dev_dbg(&rdev->dev,
-		"%s: enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n",
-		 __func__, rdev->desc->enable_reg, sreg->eco_mode_mask, reg_val,
+	rdev_dbg(rdev,
+		"enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n",
+		 rdev->desc->enable_reg, sreg->eco_mode_mask, reg_val,
 		 mode == REGULATOR_MODE_IDLE ? "idle" : "normal");
 
 	return mode;
@@ -192,13 +196,12 @@ static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
 	}
 
 	/* set mode */
+	rdev_dbg(rdev, "enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n",
+		 rdev->desc->enable_reg, sreg->eco_mode_mask, val);
+
 	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
 			     sreg->eco_mode_mask, val);
 
-	dev_dbg(&rdev->dev,
-		"%s: enable_reg=0x%x, eco_mode_mask=0x%x, value=0x%x\n",
-		 __func__, rdev->desc->enable_reg, sreg->eco_mode_mask, val);
-
 	return 0;
 }
 
@@ -209,10 +212,10 @@ static unsigned int hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 
 	if (load_uA || ((unsigned int)load_uA > sreg->eco_uA)) {
-		dev_dbg(&rdev->dev, "%s: normal mode", __func__);
+		rdev_dbg(rdev, "normal mode");
 		return REGULATOR_MODE_NORMAL;
 	} else {
-		dev_dbg(&rdev->dev, "%s: idle mode", __func__);
+		rdev_dbg(rdev, "idle mode");
 		return REGULATOR_MODE_IDLE;
 	}
 }
@@ -373,7 +376,7 @@ static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
 		goto probe_end;
 	}
 
-	dev_dbg(dev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n",
+	rdev_dbg(rdev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n",
 		 constraint->valid_modes_mask, constraint->valid_ops_mask);
 
 	dev_set_drvdata(dev, rdev);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 36/44] staging: regulator: hi6421v600-regulator: initialize ramp_delay
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (34 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 35/44] staging: regulator: hi6421v600-regulator: add a driver-specific debug macro Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 37/44] staging: regulator: hi6421v600-regulator: cleanup DT settings Mauro Carvalho Chehab
                   ` (9 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Without that, the regulator's core complains with:

       ldo17: ramp_delay not set

For now, use the enable time, as we don't have any datasheets from
this device.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/hi6421v600-regulator.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 5ddaf7f8cacc..21467fce9980 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -267,6 +267,9 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 		return ret;
 	}
 
+	/* FIXME: are there a better value for this? */
+	rdesc->ramp_delay = rdesc->enable_time;
+
 	/* parse .eco_uA */
 	ret = of_property_read_u32(np, "eco-microamp",
 				   &sreg->eco_uA);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 37/44] staging: regulator: hi6421v600-regulator: cleanup DT settings
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (35 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 36/44] staging: regulator: hi6421v600-regulator: initialize ramp_delay Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 38/44] staging: regulator: hi6421v600-regulator: fix some coding style issues Mauro Carvalho Chehab
                   ` (8 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Currently, an array is used to store both vsel and enable
settings, mixing registers, masks and bit settings.

Change it in order to have one separate property for each.

This makes easier to understand the contents of the DT
file, and to describe it at the Documentation/.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 69 +++++++++++--------
 1 file changed, 42 insertions(+), 27 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 21467fce9980..72f51594b5ff 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -45,8 +45,7 @@
 struct hi6421v600_regulator {
 	struct regulator_desc rdesc;
 	struct hi6421_spmi_pmic *pmic;
-	u8 eco_mode_mask;
-	u32 eco_uA;
+	u32 eco_mode_mask, eco_uA;
 };
 
 static DEFINE_MUTEX(enable_mutex);
@@ -226,36 +225,49 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
-	unsigned int register_info[3] = {0};
 	unsigned int *v_table;
 	int ret;
 
-	/* parse .register_info.enable_reg */
-	ret = of_property_read_u32_array(np, "hi6421-ctrl",
-					 register_info, 3);
+	ret = of_property_read_u32(np, "reg", &rdesc->enable_reg);
 	if (ret) {
-		dev_err(dev, "no hi6421-ctrl property set\n");
+		dev_err(dev, "missing reg property\nn");
 		return ret;
 	}
-	rdesc->enable_reg = register_info[0];
-	rdesc->enable_mask = register_info[1];
-	sreg->eco_mode_mask = register_info[2];
 
-	/* parse .register_info.vsel_reg */
-	ret = of_property_read_u32_array(np, "hi6421-vsel",
-					 register_info, 2);
+	ret = of_property_read_u32(np, "vsel-reg", &rdesc->vsel_reg);
 	if (ret) {
-		dev_err(dev, "no hi6421-vsel property set\n");
+		dev_err(dev, "missing vsel-reg property\n");
 		return ret;
 	}
-	rdesc->vsel_reg = register_info[0];
-	rdesc->vsel_mask = register_info[1];
+
+	ret = of_property_read_u32(np, "enable-mask", &rdesc->enable_mask);
+	if (ret) {
+		dev_err(dev, "missing enable-mask property\n");
+		return ret;
+	}
+
+	/*
+	 * Not all regulators work on idle mode
+	 */
+	ret = of_property_read_u32(np, "idle-mode-mask", &sreg->eco_mode_mask);
+	if (ret) {
+		dev_dbg(dev, "LDO doesn't support economy mode.\n");
+		sreg->eco_mode_mask = 0;
+		sreg->eco_uA = 0;
+	} else {
+		ret = of_property_read_u32(np, "eco-microamp",
+					&sreg->eco_uA);
+		if (ret) {
+			dev_err(dev, "missing eco-microamp property\n");
+			return ret;
+		}
+	}
 
 	/* parse .off-on-delay */
 	ret = of_property_read_u32(np, "off-on-delay-us",
 				   &rdesc->off_on_delay);
 	if (ret) {
-		dev_err(dev, "no off-on-delay-us property set\n");
+		dev_err(dev, "missing off-on-delay-us property\n");
 		return ret;
 	}
 
@@ -263,21 +275,13 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 	ret = of_property_read_u32(np, "startup-delay-us",
 				   &rdesc->enable_time);
 	if (ret) {
-		dev_err(dev, "no startup-delay-us property set\n");
+		dev_err(dev, "missing startup-delay-us property\n");
 		return ret;
 	}
 
 	/* FIXME: are there a better value for this? */
 	rdesc->ramp_delay = rdesc->enable_time;
 
-	/* parse .eco_uA */
-	ret = of_property_read_u32(np, "eco-microamp",
-				   &sreg->eco_uA);
-	if (ret) {
-		sreg->eco_uA = 0;
-		ret = 0;
-	}
-
 	/* parse volt_table */
 
 	rdesc->n_voltages = of_property_count_u32_elems(np, "voltage-table");
@@ -291,10 +295,21 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 	ret = of_property_read_u32_array(np, "voltage-table",
 					 v_table, rdesc->n_voltages);
 	if (ret) {
-		dev_err(dev, "no voltage-table property set\n");
+		dev_err(dev, "missing voltage-table property\n");
 		return ret;
 	}
 
+	/*
+	 * Instead of explicitly requiring a mask for the voltage selector,
+	 * as they all start from bit zero (at least on the known LDOs),
+	 * just use the number of voltages at the voltage table, getting the
+	 * minimal mask that would pick everything.
+	 */
+	rdesc->vsel_mask = (1 << (fls(rdesc->n_voltages) - 1)) - 1;
+
+	dev_dbg(dev, "voltage selector settings: reg: 0x%x, mask: 0x%x",
+		rdesc->vsel_reg, rdesc->vsel_mask);
+
 	return 0;
 }
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 38/44] staging: regulator: hi6421v600-regulator: fix some coding style issues
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (36 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 37/44] staging: regulator: hi6421v600-regulator: cleanup DT settings Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 39/44] staging: regulator: hi6421v600-regulator: add it to the building system Mauro Carvalho Chehab
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Fix the remaining issues complained by checkpatch.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 28 +++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 72f51594b5ff..c80dfac1e4c3 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -40,7 +40,7 @@
 #include <linux/spmi.h>
 
 #define rdev_dbg(rdev, fmt, arg...)	\
-		 pr_debug("%s: %s: " fmt, rdev->desc->name, __func__, ##arg)
+		 pr_debug("%s: %s: " fmt, (rdev)->desc->name, __func__, ##arg)
 
 struct hi6421v600_regulator {
 	struct regulator_desc rdesc;
@@ -105,7 +105,7 @@ static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev)
 		 rdev->desc->enable_reg, rdev->desc->enable_mask);
 
 	hi6421_spmi_pmic_rmw(pmic, rdev->desc->enable_reg,
-		      rdev->desc->enable_mask, 0);
+			     rdev->desc->enable_mask, 0);
 
 	return 0;
 }
@@ -122,7 +122,7 @@ static int hi6421_spmi_regulator_get_voltage_sel(struct regulator_dev *rdev)
 	selector = (reg_val & rdev->desc->vsel_mask) >>	(ffs(rdev->desc->vsel_mask) - 1);
 
 	rdev_dbg(rdev,
-		"vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n",
+		 "vsel_reg=0x%x, value=0x%x, entry=0x%x, voltage=%d mV\n",
 		 rdev->desc->vsel_reg, reg_val, selector,
 		rdev->desc->ops->list_voltage(rdev, selector) / 1000);
 
@@ -144,7 +144,7 @@ static int hi6421_spmi_regulator_set_voltage_sel(struct regulator_dev *rdev,
 
 	/* set voltage selector */
 	rdev_dbg(rdev,
-		"vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n",
+		 "vsel_reg=0x%x, mask=0x%x, value=0x%x, voltage=%d mV\n",
 		 rdev->desc->vsel_reg, rdev->desc->vsel_mask, reg_val,
 		 rdev->desc->ops->list_voltage(rdev, selector) / 1000);
 
@@ -169,7 +169,7 @@ static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
 		mode = REGULATOR_MODE_NORMAL;
 
 	rdev_dbg(rdev,
-		"enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n",
+		 "enable_reg=0x%x, eco_mode_mask=0x%x, reg_val=0x%x, %s mode\n",
 		 rdev->desc->enable_reg, sreg->eco_mode_mask, reg_val,
 		 mode == REGULATOR_MODE_IDLE ? "idle" : "normal");
 
@@ -177,7 +177,7 @@ static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
 }
 
 static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
-				   unsigned int mode)
+					  unsigned int mode)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
@@ -204,9 +204,10 @@ static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
 	return 0;
 }
 
-static unsigned int hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
-						    int input_uV, int output_uV,
-						    int load_uA)
+static unsigned int
+hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
+				       int input_uV, int output_uV,
+				       int load_uA)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 
@@ -220,7 +221,7 @@ static unsigned int hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev
 }
 
 static int hi6421_spmi_dt_parse(struct platform_device *pdev,
-			 struct hi6421v600_regulator *sreg,
+				struct hi6421v600_regulator *sreg,
 			 struct regulator_desc *rdesc)
 {
 	struct device *dev = &pdev->dev;
@@ -256,7 +257,7 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 		sreg->eco_uA = 0;
 	} else {
 		ret = of_property_read_u32(np, "eco-microamp",
-					&sreg->eco_uA);
+					   &sreg->eco_uA);
 		if (ret) {
 			dev_err(dev, "missing eco-microamp property\n");
 			return ret;
@@ -331,8 +332,8 @@ static struct regulator_ops hi6421_spmi_ldo_rops = {
  */
 
 static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
-				    struct device_node *np,
-				    struct hi6421_spmi_pmic *pmic)
+					   struct device_node *np,
+					   struct hi6421_spmi_pmic *pmic)
 {
 	struct device *dev = &pdev->dev;
 	struct regulator_desc *rdesc;
@@ -404,7 +405,6 @@ static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
 	return ret;
 }
 
-
 static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
 {
 	struct device *pmic_dev = pdev->dev.parent;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 39/44] staging: regulator: hi6421v600-regulator: add it to the building system
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (37 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 38/44] staging: regulator: hi6421v600-regulator: fix some coding style issues Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:10 ` [PATCH v3 40/44] staging: regulator: hi6421v600-regulator: code cleanup Mauro Carvalho Chehab
                   ` (6 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Change the binding logic to ensure that the PMIC SPMI
driver will run before the regulator code and add it to the
building system.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/Kconfig  | 10 +++++++++-
 drivers/staging/hikey9xx/Makefile |  5 +++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig
index 7ca083b7e94d..76267b9be562 100644
--- a/drivers/staging/hikey9xx/Kconfig
+++ b/drivers/staging/hikey9xx/Kconfig
@@ -15,7 +15,6 @@ config MFD_HI6421_SPMI
 	tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC"
 	depends on OF
 	select MFD_CORE
-	select REGMAP_MMIO
 	help
 	  Add support for HiSilicon Hi6421v600 SPMI PMIC. Hi6421 includes
 	  multi-functions, such as regulators, RTC, codec, Coulomb counter,
@@ -25,3 +24,12 @@ config MFD_HI6421_SPMI
 	  individual components like voltage regulators under corresponding
 	  menus in order to enable them.
 	  We communicate with the Hi6421v600 via a SPMI bus.
+
+# to be placed at drivers/regulator
+config REGULATOR_HI6421V600
+	tristate "HiSilicon Hi6421v600 PMIC voltage regulator support"
+	depends on MFD_HI6421_PMIC && OF
+	help
+	  This driver provides support for the voltage regulators on
+	  HiSilicon Hi6421v600 PMU / Codec IC.
+	  This is used on Kirin 3670 boards, like HiKey 970.
diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile
index 79de37da7a8f..9371dcc3d35b 100644
--- a/drivers/staging/hikey9xx/Makefile
+++ b/drivers/staging/hikey9xx/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_SPMI_HISI3670)	+= hisi-spmi-controller.o
-obj-$(CONFIG_MFD_HI6421_SPMI)	+= hi6421-spmi-pmic.o
+obj-$(CONFIG_SPMI_HISI3670)		+= hisi-spmi-controller.o
+obj-$(CONFIG_MFD_HI6421_SPMI)		+= hi6421-spmi-pmic.o
+obj-$(CONFIG_REGULATOR_HI6421V600)	+= hi6421v600-regulator.o
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 40/44] staging: regulator: hi6421v600-regulator: code cleanup
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (38 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 39/44] staging: regulator: hi6421v600-regulator: add it to the building system Mauro Carvalho Chehab
@ 2020-08-17  7:10 ` Mauro Carvalho Chehab
  2020-08-17  7:11 ` [PATCH v3 41/44] staging: hikey9xx: add a TODO list Mauro Carvalho Chehab
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel,
	devel, Jonathan Cameron

Do some code cleanup in order to make it cleaner for moving
it out of staging in the future.

Suggested-by: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../staging/hikey9xx/hi6421v600-regulator.c   | 80 ++++++++-----------
 1 file changed, 33 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index c80dfac1e4c3..82635ff54a74 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -15,29 +15,28 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
-#include <linux/slab.h>
+#include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/mfd/hi6421-spmi-pmic.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
-#include <linux/mfd/hi6421-spmi-pmic.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/version.h>
 #include <linux/seq_file.h>
-#include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/spmi.h>
+#include <linux/time.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
 
 #define rdev_dbg(rdev, fmt, arg...)	\
 		 pr_debug("%s: %s: " fmt, (rdev)->desc->name, __func__, ##arg)
@@ -50,15 +49,16 @@ struct hi6421v600_regulator {
 
 static DEFINE_MUTEX(enable_mutex);
 
-/* helper function to ensure when it returns it is at least 'delay_us'
+/*
+ * helper function to ensure when it returns it is at least 'delay_us'
  * microseconds after 'since'.
  */
 
 static int hi6421_spmi_regulator_is_enabled(struct regulator_dev *rdev)
 {
-	u32 reg_val;
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
+	u32 reg_val;
 
 	reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg);
 
@@ -136,7 +136,6 @@ static int hi6421_spmi_regulator_set_voltage_sel(struct regulator_dev *rdev,
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
 	u32 reg_val;
 
-	/* unlikely to happen. sanity test done by regulator core */
 	if (unlikely(selector >= rdev->desc->n_voltages))
 		return -EINVAL;
 
@@ -158,8 +157,8 @@ static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 	struct hi6421_spmi_pmic *pmic = sreg->pmic;
-	u32 reg_val;
 	unsigned int mode;
+	u32 reg_val;
 
 	reg_val = hi6421_spmi_pmic_read(pmic, rdev->desc->enable_reg);
 
@@ -211,13 +210,10 @@ hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
 {
 	struct hi6421v600_regulator *sreg = rdev_get_drvdata(rdev);
 
-	if (load_uA || ((unsigned int)load_uA > sreg->eco_uA)) {
-		rdev_dbg(rdev, "normal mode");
+	if (load_uA || ((unsigned int)load_uA > sreg->eco_uA))
 		return REGULATOR_MODE_NORMAL;
-	} else {
-		rdev_dbg(rdev, "idle mode");
-		return REGULATOR_MODE_IDLE;
-	}
+
+	return REGULATOR_MODE_IDLE;
 }
 
 static int hi6421_spmi_dt_parse(struct platform_device *pdev,
@@ -231,7 +227,7 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 
 	ret = of_property_read_u32(np, "reg", &rdesc->enable_reg);
 	if (ret) {
-		dev_err(dev, "missing reg property\nn");
+		dev_err(dev, "missing reg property\n");
 		return ret;
 	}
 
@@ -256,8 +252,7 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 		sreg->eco_mode_mask = 0;
 		sreg->eco_uA = 0;
 	} else {
-		ret = of_property_read_u32(np, "eco-microamp",
-					   &sreg->eco_uA);
+		ret = of_property_read_u32(np, "eco-microamp", &sreg->eco_uA);
 		if (ret) {
 			dev_err(dev, "missing eco-microamp property\n");
 			return ret;
@@ -308,13 +303,13 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
 	 */
 	rdesc->vsel_mask = (1 << (fls(rdesc->n_voltages) - 1)) - 1;
 
-	dev_dbg(dev, "voltage selector settings: reg: 0x%x, mask: 0x%x",
+	dev_dbg(dev, "voltage selector settings: reg: 0x%x, mask: 0x%x\n",
 		rdesc->vsel_reg, rdesc->vsel_mask);
 
 	return 0;
 }
 
-static struct regulator_ops hi6421_spmi_ldo_rops = {
+static const struct regulator_ops hi6421_spmi_ldo_rops = {
 	.is_enabled = hi6421_spmi_regulator_is_enabled,
 	.enable = hi6421_spmi_regulator_enable,
 	.disable = hi6421_spmi_regulator_disable,
@@ -327,23 +322,19 @@ static struct regulator_ops hi6421_spmi_ldo_rops = {
 	.get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode,
 };
 
-/*
- * Used only for parsing the DT properties
- */
-
 static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
 					   struct device_node *np,
 					   struct hi6421_spmi_pmic *pmic)
 {
-	struct device *dev = &pdev->dev;
-	struct regulator_desc *rdesc;
-	struct regulator_dev *rdev;
-	struct hi6421v600_regulator *sreg = NULL;
+	struct regulation_constraints *constraint;
 	struct regulator_init_data *initdata;
 	struct regulator_config config = { };
-	struct regulation_constraints *constraint;
-	const char *supplyname = NULL;
-	int ret = 0;
+	struct hi6421v600_regulator *sreg;
+	struct device *dev = &pdev->dev;
+	struct regulator_desc *rdesc;
+	struct regulator_dev *rdev;
+	const char *supplyname;
+	int ret;
 
 	initdata = of_get_regulator_init_data(dev, np, NULL);
 	if (!initdata) {
@@ -351,7 +342,7 @@ static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
-	sreg = kzalloc(sizeof(*sreg), GFP_KERNEL);
+	sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
 	if (!sreg)
 		return -ENOMEM;
 
@@ -370,7 +361,7 @@ static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
 	/* parse device tree data for regulator specific */
 	ret = hi6421_spmi_dt_parse(pdev, sreg, rdesc);
 	if (ret)
-		goto probe_end;
+		return ret;
 
 	/* hisi regulator supports two modes */
 	constraint = &initdata->constraints;
@@ -391,18 +382,15 @@ static int hi6421_spmi_regulator_probe_ldo(struct platform_device *pdev,
 	if (IS_ERR(rdev)) {
 		dev_err(dev, "failed to register %s\n",
 			rdesc->name);
-		ret = PTR_ERR(rdev);
-		goto probe_end;
+		return PTR_ERR(rdev);
 	}
 
 	rdev_dbg(rdev, "valid_modes_mask: 0x%x, valid_ops_mask: 0x%x\n",
 		 constraint->valid_modes_mask, constraint->valid_ops_mask);
 
 	dev_set_drvdata(dev, rdev);
-probe_end:
-	if (ret)
-		kfree(sreg);
-	return ret;
+
+	return 0;
 }
 
 static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
@@ -414,7 +402,6 @@ static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
 	struct hi6421_spmi_pmic *pmic;
 	int ret;
 
-	dev_dbg(&pdev->dev, "probing hi6421v600 regulator\n");
 	/*
 	 * This driver is meant to be called by hi6421-spmi-core,
 	 * which should first set drvdata. If this doesn't happen, hit
@@ -463,7 +450,6 @@ static int hi6421_spmi_regulator_remove(struct platform_device *pdev)
 
 	regulator_unregister(rdev);
 
-	/* TODO: should i worry about that? devm_kzalloc */
 	if (rdev->desc->volt_table)
 		devm_kfree(&pdev->dev, (unsigned int *)rdev->desc->volt_table);
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 41/44] staging: hikey9xx: add a TODO list
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (39 preceding siblings ...)
  2020-08-17  7:10 ` [PATCH v3 40/44] staging: regulator: hi6421v600-regulator: code cleanup Mauro Carvalho Chehab
@ 2020-08-17  7:11 ` Mauro Carvalho Chehab
  2020-08-17  7:11 ` [PATCH v3 42/44] MAINTAINERS: add an entry for HiSilicon 6421v600 drivers Mauro Carvalho Chehab
                   ` (4 subsequent siblings)
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, linux-kernel, devel

Place the things that are needed to be able to move those
drivers out of staging.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 drivers/staging/hikey9xx/TODO | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 drivers/staging/hikey9xx/TODO

diff --git a/drivers/staging/hikey9xx/TODO b/drivers/staging/hikey9xx/TODO
new file mode 100644
index 000000000000..65e7996a3066
--- /dev/null
+++ b/drivers/staging/hikey9xx/TODO
@@ -0,0 +1,5 @@
+ToDo list:
+
+- Port other drivers needed by Hikey 960/970;
+- Test drivers on Hikey 960;
+- Validate device tree bindings.
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 42/44] MAINTAINERS: add an entry for HiSilicon 6421v600 drivers
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (40 preceding siblings ...)
  2020-08-17  7:11 ` [PATCH v3 41/44] staging: hikey9xx: add a TODO list Mauro Carvalho Chehab
@ 2020-08-17  7:11 ` Mauro Carvalho Chehab
  2020-08-18 14:18   ` Greg Kroah-Hartman
  2020-08-17  7:11 ` [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties Mauro Carvalho Chehab
                   ` (3 subsequent siblings)
  45 siblings, 1 reply; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, David S. Miller,
	Rob Herring, linux-kernel

Add an entry for the SPMI, MFD and PMIC parts of the
HiSilicon 6421v600 support.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 956ecd5ba426..e2de0b2119fd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7824,6 +7824,12 @@ F:	drivers/crypto/hisilicon/sec2/sec_crypto.c
 F:	drivers/crypto/hisilicon/sec2/sec_crypto.h
 F:	drivers/crypto/hisilicon/sec2/sec_main.c
 
+HISILICON STAGING DRIVERS FOR HIKEY 960/970
+M:	Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	drivers/staging/hikey9xx/
+
 HISILICON TRUE RANDOM NUMBER GENERATOR V2 SUPPORT
 M:	Zaibo Xu <xuzaibo@huawei.com>
 S:	Maintained
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (41 preceding siblings ...)
  2020-08-17  7:11 ` [PATCH v3 42/44] MAINTAINERS: add an entry for HiSilicon 6421v600 drivers Mauro Carvalho Chehab
@ 2020-08-17  7:11 ` Mauro Carvalho Chehab
  2020-08-17 20:12   ` Rob Herring
  2020-08-18 11:10   ` [PATCH v3.1 " Mauro Carvalho Chehab
  2020-08-17  7:11 ` [PATCH v3 44/44] dt: hisilicon: add support for the PMIC found on Hikey 970 Mauro Carvalho Chehab
                   ` (2 subsequent siblings)
  45 siblings, 2 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Lee Jones,
	Rob Herring, Stephen Boyd, devicetree, linux-kernel,
	linux-arm-msm

Add documentation for the properties needed by the HiSilicon
6421v600 driver, and by the SPMI controller used to access
the chipset.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../mfd/hisilicon,hi6421-spmi-pmic.yaml       | 182 ++++++++++++++++++
 .../spmi/hisilicon,hisi-spmi-controller.yaml  |  54 ++++++
 2 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
 create mode 100644 Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.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..95494114554d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
@@ -0,0 +1,182 @@
+# 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 uses a MIPI System Power Management (SPMI) bus in order
+  to provide 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/spmi/hisilicon,hisi-spmi-controller.yaml.
+
+properties:
+  $nodename:
+    pattern: "pmic@[0-9a-f]"
+
+  compatible:
+    const: hisilicon,hi6421-spmi-pmic
+
+  reg:
+    maxItems: 1
+
+  spmi-channel:
+    description: number of the SPMI channel where the PMIC is connected
+
+  '#interrupt-cells':
+    const: 2
+
+  interrupt-controller:
+    description:
+      Identify that the PMIC is capable of behaving as an interrupt controller.
+
+  gpios:
+    maxItems: 1
+
+  irq-num:
+    description: Interrupt request number
+
+  'irq-array':
+    description: Interrupt request array
+
+  'irq-mask-addr':
+    description: Address for the interrupt request mask
+
+  'irq-addr':
+    description: Address for the interrupt request
+
+  regulators:
+    type: object
+
+    properties:
+      '#address-cells':
+        const: 1
+
+      '#size-cells':
+        const: 0
+
+    patternProperties:
+      '^ldo@[0-9]+$':
+        type: object
+
+        $ref: "/schemas/regulator/regulator.yaml#"
+
+        properties:
+          reg:
+            description: Enable register.
+
+          '#address-cells':
+            const: 1
+
+          '#size-cells':
+            const: 0
+
+          vsel-reg:
+            description: Voltage selector register.
+
+          enable-mask:
+            description: Bitmask used to enable the regulator.
+
+          voltage-table:
+            description: Table with the selector items for the voltage regulator.
+            minItems: 2
+            maxItems: 16
+
+          off-on-delay-us:
+            description: Time required for changing state to enabled in microseconds.
+
+          startup-delay-us:
+            description: Startup time in microseconds.
+
+          idle-mode-mask:
+            description: Bitmask used to put the regulator on idle mode.
+
+          eco-microamp:
+            description: Maximum current while on idle mode.
+
+        required:
+          - reg
+          - vsel-reg
+          - enable-mask
+          - voltage-table
+          - off-on-delay-us
+          - startup-delay-us
+
+required:
+  - compatible
+  - reg
+  - regulators
+
+examples:
+  - |
+    /* pmic properties */
+
+    pmic: pmic@0 {
+      compatible = "hisilicon,hi6421-spmi-pmic";
+      slave_id = <0>;
+      reg = <0 0>;
+
+      #interrupt-cells = <2>;
+      interrupt-controller;
+      gpios = <&gpio28 0 0>;
+      irq-num = <16>;
+      irq-array = <2>;
+      irq-mask-addr = <0x202 2>;
+      irq-addr = <0x212 2>;
+
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      regulators {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+        ldo3: ldo3@16 {
+          reg = <0x16>;
+          vsel-reg = <0x51>;
+
+          regulator-name = "ldo3";
+          regulator-min-microvolt = <1500000>;
+          regulator-max-microvolt = <2000000>;
+          regulator-boot-on;
+
+          enable-mask = <0x01>;
+
+          voltage-table = <1500000>, <1550000>, <1600000>, <1650000>,
+                          <1700000>, <1725000>, <1750000>, <1775000>,
+                          <1800000>, <1825000>, <1850000>, <1875000>,
+                          <1900000>, <1925000>, <1950000>, <2000000>;
+          off-on-delay-us = <20000>;
+          startup-delay-us = <120>;
+        };
+
+        ldo4: ldo4@17 { /* 40 PIN */
+          reg = <0x17>;
+          vsel-reg = <0x52>;
+
+          regulator-name = "ldo4";
+          regulator-min-microvolt = <1725000>;
+          regulator-max-microvolt = <1900000>;
+          regulator-boot-on;
+
+          enable-mask = <0x01>;
+          idle-mode-mask = <0x10>;
+          eco-microamp = <10000>;
+
+          hi6421-vsel = <0x52 0x07>;
+          voltage-table = <1725000>, <1750000>, <1775000>, <1800000>,
+                          <1825000>, <1850000>, <1875000>, <1900000>;
+          off-on-delay-us = <20000>;
+          startup-delay-us = <120>;
+        };
+      };
+    };
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..5aeb2ae12024
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
@@ -0,0 +1,54 @@
+# 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 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.
+
+properties:
+  $nodename:
+    pattern: "spmi@[0-9a-f]"
+
+  compatible:
+    const: hisilicon,spmi-controller
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 0
+
+  spmi-channel:
+    description: number of the SPMI channel where the PMIC is connected
+
+patternProperties:
+  "^pmic@[0-9a-f]$":
+    $ref: "/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#"
+
+examples:
+  - |
+    spmi: spmi@fff24000 {
+      compatible = "hisilicon,spmi-controller";
+      #address-cells = <2>;
+      #size-cells = <0>;
+      status = "ok";
+      reg = <0x0 0xfff24000 0x0 0x1000>;
+      spmi-channel = <2>;
+
+      /* pmic properties */
+
+    };
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v3 44/44] dt: hisilicon: add support for the PMIC found on Hikey 970
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (42 preceding siblings ...)
  2020-08-17  7:11 ` [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties Mauro Carvalho Chehab
@ 2020-08-17  7:11 ` Mauro Carvalho Chehab
  2020-08-17  7:32 ` [PATCH v3 00/44] SPMI patches needed by " Greg Kroah-Hartman
  2020-08-18 14:17 ` Greg Kroah-Hartman
  45 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-17  7:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Wei Xu,
	Rob Herring, linux-arm-kernel, devicetree, linux-kernel

Add a device tree for the HiSilicon 6421v600 SPMI PMIC, used
on HiKey970 board.

As we now have support for it, change the fixed regulators
used by the SD I/O to use the proper LDO supplies.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 .../boot/dts/hisilicon/hi3670-hikey970.dts    |  22 +-
 .../boot/dts/hisilicon/hikey970-pmic.dtsi     | 200 ++++++++++++++++++
 2 files changed, 203 insertions(+), 19 deletions(-)
 create mode 100644 arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi

diff --git a/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts b/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts
index 01234a175dcd..a9ad90e769ad 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts
@@ -12,6 +12,7 @@
 
 #include "hi3670.dtsi"
 #include "hikey970-pinctrl.dtsi"
+#include "hikey970-pmic.dtsi"
 
 / {
 	model = "HiKey970";
@@ -39,23 +40,6 @@ memory@0 {
 		reg = <0x0 0x0 0x0 0x0>;
 	};
 
-	sd_1v8: regulator-1v8 {
-		compatible = "regulator-fixed";
-		regulator-name = "fixed-1.8V";
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-		regulator-always-on;
-	};
-
-	sd_3v3: regulator-3v3 {
-		compatible = "regulator-fixed";
-		regulator-name = "fixed-3.3V";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
 	wlan_en: wlan-en-1-8v {
 		compatible = "regulator-fixed";
 		regulator-name = "wlan-en-regulator";
@@ -402,8 +386,8 @@ &dwmmc1 {
 	pinctrl-0 = <&sd_pmx_func
 		     &sd_clk_cfg_func
 		     &sd_cfg_func>;
-	vmmc-supply = <&sd_3v3>;
-	vqmmc-supply = <&sd_1v8>;
+	vmmc-supply = <&ldo16>;
+	vqmmc-supply = <&ldo9>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi
new file mode 100644
index 000000000000..2a6c366d9be6
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Hi6421v600 SPMI PMIC used at the HiKey970 Development Board
+ *
+ * Copyright (C) 2020, Huawei Tech. Co., Ltd.
+ */
+
+/ {
+	spmi: spmi@fff24000 {
+		compatible = "hisilicon,spmi-controller";
+		#address-cells = <2>;
+		#size-cells = <0>;
+		status = "ok";
+		reg = <0x0 0xfff24000 0x0 0x1000>;
+		spmi-channel = <2>;
+
+		pmic: pmic@0 {
+			compatible = "hisilicon,hi6421-spmi-pmic";
+			slave_id = <0>;
+			reg = <0 0>;
+
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			gpios = <&gpio28 0 0>;
+			irq-num = <16>;
+			irq-array = <2>;
+			irq-mask-addr = <0x202 2>;
+			irq-addr = <0x212 2>;
+
+			regulators {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ldo3: ldo3@16 {
+					reg = <0x16>;
+					vsel-reg = <0x51>;
+
+					regulator-name = "ldo3";
+					regulator-min-microvolt = <1500000>;
+					regulator-max-microvolt = <2000000>;
+					regulator-boot-on;
+
+					enable-mask = <0x01>;
+
+					voltage-table = <1500000>, <1550000>,
+							<1600000>, <1650000>,
+							<1700000>, <1725000>,
+							<1750000>, <1775000>,
+							<1800000>, <1825000>,
+							<1850000>, <1875000>,
+							<1900000>, <1925000>,
+							<1950000>, <2000000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <120>;
+				};
+
+				ldo4: ldo4@17 { /* 40 PIN */
+					reg = <0x17>;
+					vsel-reg = <0x52>;
+
+					regulator-name = "ldo4";
+					regulator-min-microvolt = <1725000>;
+					regulator-max-microvolt = <1900000>;
+					regulator-boot-on;
+
+					enable-mask = <0x01>;
+					idle-mode-mask = <0x10>;
+					eco-microamp = <10000>;
+
+					hi6421-vsel = <0x52 0x07>;
+					voltage-table = <1725000>, <1750000>,
+							<1775000>, <1800000>,
+							<1825000>, <1850000>,
+							<1875000>, <1900000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <120>;
+				};
+
+				ldo9: ldo9@1C { /* SDCARD I/O */
+					reg = <0x1C>;
+					vsel-reg = <0x57>;
+
+					regulator-name = "ldo9";
+					regulator-min-microvolt = <1750000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-boot-on;
+
+					enable-mask = <0x01>;
+					idle-mode-mask = <0x10>;
+					eco-microamp = <10000>;
+
+					voltage-table = <1750000>, <1800000>,
+							<1825000>, <2800000>,
+							<2850000>, <2950000>,
+							<3000000>, <3300000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <360>;
+				};
+
+				ldo15: ldo15@21 { /* UFS */
+					reg = <0x21>;
+					vsel-reg = <0x5c>;
+
+					regulator-name = "ldo15";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <3000000>;
+					regulator-always-on;
+
+					enable-mask = <0x01>;
+					idle-mode-mask = <0x10>;
+					eco-microamp = <10000>;
+
+					voltage-table = <1800000>, <1850000>,
+							<2400000>, <2600000>,
+							<2700000>, <2850000>,
+							<2950000>, <3000000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <120>;
+				};
+
+				ldo16: ldo16@22 { /* SD */
+					reg = <0x22>;
+					vsel-reg = <0x5d>;
+
+					regulator-name = "ldo16";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <3000000>;
+					regulator-boot-on;
+
+					enable-mask = <0x01>;
+					idle-mode-mask = <0x10>;
+					eco-microamp = <10000>;
+
+					voltage-table = <1800000>, <1850000>,
+							<2400000>, <2600000>,
+							<2700000>, <2850000>,
+							<2950000>, <3000000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <360>;
+				};
+
+				ldo17: ldo17@23 {
+					reg = <0x23>;
+					vsel-reg = <0x5e>;
+
+					regulator-name = "ldo17";
+					regulator-min-microvolt = <2500000>;
+					regulator-max-microvolt = <3300000>;
+
+					enable-mask = <0x01>;
+					idle-mode-mask = <0x10>;
+					eco-microamp = <10000>;
+
+					voltage-table = <2500000>, <2600000>,
+							<2700000>, <2800000>,
+							<3000000>, <3100000>,
+							<3200000>, <3300000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <120>;
+				};
+
+				ldo33: ldo33@32 { /* PEX8606 */
+					reg = <0x32>;
+					vsel-reg = <0x6d>;
+					regulator-name = "ldo33";
+					regulator-min-microvolt = <2500000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-boot-on;
+
+					enable-mask = <0x01>;
+
+					voltage-table = <2500000>, <2600000>,
+							<2700000>, <2800000>,
+							<3000000>, <3100000>,
+							<3200000>, <3300000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <120>;
+				};
+
+				ldo34: ldo34@33 { /* GPS AUX IN VDD */
+					reg = <0x33>;
+					vsel-reg = <0x6e>;
+
+					regulator-name = "ldo34";
+					regulator-min-microvolt = <2600000>;
+					regulator-max-microvolt = <3300000>;
+
+					enable-mask = <0x01>;
+
+					voltage-table = <2600000>, <2700000>,
+							<2800000>, <2900000>,
+							<3000000>, <3100000>,
+							<3200000>, <3300000>;
+					off-on-delay-us = <20000>;
+					startup-delay-us = <120>;
+				};
+			};
+		};
+	};
+};
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 00/44] SPMI patches needed by Hikey 970
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (43 preceding siblings ...)
  2020-08-17  7:11 ` [PATCH v3 44/44] dt: hisilicon: add support for the PMIC found on Hikey 970 Mauro Carvalho Chehab
@ 2020-08-17  7:32 ` Greg Kroah-Hartman
  2020-08-18 14:17 ` Greg Kroah-Hartman
  45 siblings, 0 replies; 57+ messages in thread
From: Greg Kroah-Hartman @ 2020-08-17  7:32 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: devel, devicetree, Rob Herring, linux-arm-msm, linuxarm, Wei Xu,
	linux-kernel, Stephen Boyd, Rob Herring, mauro.chehab, Lee Jones,
	David S. Miller, linux-arm-kernel

On Mon, Aug 17, 2020 at 09:10:19AM +0200, Mauro Carvalho Chehab wrote:
> Hi Greg,
> 
> This patch series is part of a work I'm doing in order to be able to support
> a HiKey 970 board that I recently got on my hands.

Do you feel this is good enough for me to add to my tree now?  Or do you
want me to wait a bit?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-17  7:11 ` [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties Mauro Carvalho Chehab
@ 2020-08-17 20:12   ` Rob Herring
  2020-08-18  9:13     ` Mauro Carvalho Chehab
  2020-08-18 11:10   ` [PATCH v3.1 " Mauro Carvalho Chehab
  1 sibling, 1 reply; 57+ messages in thread
From: Rob Herring @ 2020-08-17 20:12 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Greg Kroah-Hartman, linuxarm, mauro.chehab, Lee Jones,
	Stephen Boyd, devicetree, linux-kernel, linux-arm-msm

On Mon, Aug 17, 2020 at 09:11:02AM +0200, Mauro Carvalho Chehab wrote:
> Add documentation for the properties needed by the HiSilicon
> 6421v600 driver, and by the SPMI controller used to access
> the chipset.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> ---
>  .../mfd/hisilicon,hi6421-spmi-pmic.yaml       | 182 ++++++++++++++++++
>  .../spmi/hisilicon,hisi-spmi-controller.yaml  |  54 ++++++
>  2 files changed, 236 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
>  create mode 100644 Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.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..95494114554d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> @@ -0,0 +1,182 @@
> +# 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 uses a MIPI System Power Management (SPMI) bus in order
> +  to provide 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/spmi/hisilicon,hisi-spmi-controller.yaml.
> +
> +properties:
> +  $nodename:
> +    pattern: "pmic@[0-9a-f]"
> +
> +  compatible:
> +    const: hisilicon,hi6421-spmi-pmic

-spmi-pmic is redundant. Can the hi6421 be anything else?

> +
> +  reg:
> +    maxItems: 1
> +
> +  spmi-channel:
> +    description: number of the SPMI channel where the PMIC is connected

This looks like a common (to SPMI), but it's not something defined in 
spmi.txt (which should ideally be converted to schema first). Minimally, 
it needs a better explanation and determination if it should be common 
or is HiSilicon specific.

> +
> +  '#interrupt-cells':
> +    const: 2
> +
> +  interrupt-controller:
> +    description:
> +      Identify that the PMIC is capable of behaving as an interrupt controller.

No need to redefine common properties if nothing specific to this device 
to say. Just:

interrupt-controller: true

> +
> +  gpios:
> +    maxItems: 1
> +
> +  irq-num:
> +    description: Interrupt request number
> +
> +  'irq-array':
> +    description: Interrupt request array
> +
> +  'irq-mask-addr':
> +    description: Address for the interrupt request mask
> +
> +  'irq-addr':
> +    description: Address for the interrupt request

What's all these non-standard interrupt properties?

> +
> +  regulators:
> +    type: object

additionalProperties: false

> +
> +    properties:
> +      '#address-cells':
> +        const: 1
> +
> +      '#size-cells':
> +        const: 0
> +
> +    patternProperties:
> +      '^ldo@[0-9]+$':

Unit-addresses are hex.

Also, doesn't match the example.

> +        type: object
> +
> +        $ref: "/schemas/regulator/regulator.yaml#"
> +
> +        properties:
> +          reg:
> +            description: Enable register.
> +

> +          '#address-cells':
> +            const: 1
> +
> +          '#size-cells':
> +            const: 0

No child nodes, you don't need these.

> +
> +          vsel-reg:
> +            description: Voltage selector register.

'reg' can have multiple entries if you want.

> +
> +          enable-mask:
> +            description: Bitmask used to enable the regulator.

But if there's a shared enable reg, then you shouldn't have duplicate 
addresses (same 'reg' value in multiple nodes).

These perhaps should be driver data rather than in DT as it's all fixed 
for this chip. We don't try to parameterize everything in DT.

> +
> +          voltage-table:
> +            description: Table with the selector items for the voltage regulator.
> +            minItems: 2
> +            maxItems: 16

Needs a type $ref.

> +
> +          off-on-delay-us:
> +            description: Time required for changing state to enabled in microseconds.
> +
> +          startup-delay-us:
> +            description: Startup time in microseconds.
> +
> +          idle-mode-mask:
> +            description: Bitmask used to put the regulator on idle mode.
> +
> +          eco-microamp:
> +            description: Maximum current while on idle mode.
> +
> +        required:
> +          - reg
> +          - vsel-reg
> +          - enable-mask
> +          - voltage-table
> +          - off-on-delay-us
> +          - startup-delay-us
> +
> +required:
> +  - compatible
> +  - reg
> +  - regulators

Add:

additionalProperties: false

> +
> +examples:
> +  - |
> +    /* pmic properties */
> +
> +    pmic: pmic@0 {
> +      compatible = "hisilicon,hi6421-spmi-pmic";
> +      slave_id = <0>;

Not documented. I believe this is part of 'reg'.

> +      reg = <0 0>;
> +
> +      #interrupt-cells = <2>;
> +      interrupt-controller;
> +      gpios = <&gpio28 0 0>;
> +      irq-num = <16>;
> +      irq-array = <2>;
> +      irq-mask-addr = <0x202 2>;
> +      irq-addr = <0x212 2>;
> +
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +
> +      regulators {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +        ldo3: ldo3@16 {
> +          reg = <0x16>;
> +          vsel-reg = <0x51>;
> +
> +          regulator-name = "ldo3";
> +          regulator-min-microvolt = <1500000>;
> +          regulator-max-microvolt = <2000000>;
> +          regulator-boot-on;
> +
> +          enable-mask = <0x01>;
> +
> +          voltage-table = <1500000>, <1550000>, <1600000>, <1650000>,
> +                          <1700000>, <1725000>, <1750000>, <1775000>,
> +                          <1800000>, <1825000>, <1850000>, <1875000>,
> +                          <1900000>, <1925000>, <1950000>, <2000000>;
> +          off-on-delay-us = <20000>;
> +          startup-delay-us = <120>;
> +        };
> +
> +        ldo4: ldo4@17 { /* 40 PIN */
> +          reg = <0x17>;
> +          vsel-reg = <0x52>;
> +
> +          regulator-name = "ldo4";
> +          regulator-min-microvolt = <1725000>;
> +          regulator-max-microvolt = <1900000>;
> +          regulator-boot-on;
> +
> +          enable-mask = <0x01>;
> +          idle-mode-mask = <0x10>;
> +          eco-microamp = <10000>;
> +
> +          hi6421-vsel = <0x52 0x07>;

Not documented.

> +          voltage-table = <1725000>, <1750000>, <1775000>, <1800000>,
> +                          <1825000>, <1850000>, <1875000>, <1900000>;
> +          off-on-delay-us = <20000>;
> +          startup-delay-us = <120>;
> +        };
> +      };
> +    };
> 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..5aeb2ae12024
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
> @@ -0,0 +1,54 @@
> +# 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 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.
> +
> +properties:
> +  $nodename:
> +    pattern: "spmi@[0-9a-f]"
> +
> +  compatible:
> +    const: hisilicon,spmi-controller

Needs an SoC specific compatible.

> +
> +  reg:
> +    maxItems: 1
> +
> +  "#address-cells":
> +    const: 2
> +
> +  "#size-cells":
> +    const: 0
> +
> +  spmi-channel:
> +    description: number of the SPMI channel where the PMIC is connected
> +
> +patternProperties:
> +  "^pmic@[0-9a-f]$":
> +    $ref: "/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#"
> +
> +examples:
> +  - |
> +    spmi: spmi@fff24000 {
> +      compatible = "hisilicon,spmi-controller";
> +      #address-cells = <2>;
> +      #size-cells = <0>;
> +      status = "ok";
> +      reg = <0x0 0xfff24000 0x0 0x1000>;
> +      spmi-channel = <2>;

Does this go in the SPMI controller or child (pmic)?

> +
> +      /* pmic properties */
> +
> +    };
> -- 
> 2.26.2
> 

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-17 20:12   ` Rob Herring
@ 2020-08-18  9:13     ` Mauro Carvalho Chehab
  2020-08-18 10:37       ` Mauro Carvalho Chehab
  2020-08-18 17:07       ` Rob Herring
  0 siblings, 2 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-18  9:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: Greg Kroah-Hartman, linuxarm, mauro.chehab, Lee Jones,
	Stephen Boyd, devicetree, linux-kernel, linux-arm-msm

Em Mon, 17 Aug 2020 14:12:11 -0600
Rob Herring <robh@kernel.org> escreveu:

> On Mon, Aug 17, 2020 at 09:11:02AM +0200, Mauro Carvalho Chehab wrote:
> > Add documentation for the properties needed by the HiSilicon
> > 6421v600 driver, and by the SPMI controller used to access
> > the chipset.
> > 
> > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> > ---
> >  .../mfd/hisilicon,hi6421-spmi-pmic.yaml       | 182 ++++++++++++++++++
> >  .../spmi/hisilicon,hisi-spmi-controller.yaml  |  54 ++++++
> >  2 files changed, 236 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> >  create mode 100644 Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.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..95494114554d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> > @@ -0,0 +1,182 @@
> > +# 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 uses a MIPI System Power Management (SPMI) bus in order
> > +  to provide 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/spmi/hisilicon,hisi-spmi-controller.yaml.
> > +
> > +properties:
> > +  $nodename:
> > +    pattern: "pmic@[0-9a-f]"
> > +
> > +  compatible:
> > +    const: hisilicon,hi6421-spmi-pmic  
> 
> -spmi-pmic is redundant. Can the hi6421 be anything else?

There are other HiSilicom 6421 variants that don't use SPMI bus:

	Documentation/devicetree/bindings/mfd/hi6421.txt:       "hisilicon,hi6421-pmic";
	Documentation/devicetree/bindings/mfd/hi6421.txt:       "hisilicon,hi6421v530-pmic";

The DT file on Kernel 4.9 uses hi6421v600 (although the schematics
from 96boards name it as hi6421v610).

While I don't mind much,would prefer to keep "spmi" on its name, in order
to distinguish this one from the non-spmi variants.

Maybe we use this for compatible:

	hisilicon,hi6421v600-spmi

> 
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  spmi-channel:
> > +    description: number of the SPMI channel where the PMIC is connected  
> 
> This looks like a common (to SPMI), but it's not something defined in 
> spmi.txt 

This one is not part of the SPMI core. It is stored inside a private 
structure inside at the HiSilicon spmi controller driver. It is stored 
there as ctrl_dev->channel, and it is used to calculate the register offset
for readl():

	offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
	offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
	do {
		status = readl(base + offset);
	...

The SPMI bus is somewhat similar to I2C: it is a 2-wire serial bus
with up to 16 devices connected to it.

Now, most modern I2C chipsets provide multiple independent I2C
channels, on different pins. Also, on some chipsets, certain
GPIO pins can be used either as GPIO or as I2C.

I strongly suspect that this is the case here: according with
the Hikey 970 schematics:

	https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf

The pins used by SPMI clock/data can also be used as GPIO.

While I don't have access to the datasheets for Kirin 970 (or any other
chipsets on this board), for me, it sounds that different GPIO pins
are allowed to use SPMI. The "spmi-channel" property specifies
what pins will be used for SPMI, among the ones that are
compatible with MIPI SPMI specs.

> (which should ideally be converted to schema first). 

I can try porting spmi schema to yaml on a separate patch,
and submit it independently of this series.

> Minimally, 
> it needs a better explanation and determination if it should be common 
> or is HiSilicon specific.

What about:

  spmi-channel:
    description: |
      number of the SPMI channel at the HiSilicon SoC that will
      be used for the MIPI SPMI controller.

> 
> > +
> > +  '#interrupt-cells':
> > +    const: 2
> > +
> > +  interrupt-controller:
> > +    description:
> > +      Identify that the PMIC is capable of behaving as an interrupt controller.  
> 
> No need to redefine common properties if nothing specific to this device 
> to say. Just:
> 
> interrupt-controller: true

Ok.

> 
> > +
> > +  gpios:
> > +    maxItems: 1
> > +
> > +  irq-num:
> > +    description: Interrupt request number
> > +
> > +  'irq-array':
> > +    description: Interrupt request array
> > +
> > +  'irq-mask-addr':
> > +    description: Address for the interrupt request mask
> > +
> > +  'irq-addr':
> > +    description: Address for the interrupt request  
> 
> What's all these non-standard interrupt properties?

After doing a deeper look at the code which handles IRQs on this PMIC,
I'm considering to get rid of two properties: irq-num and irq-array.

See, the code does this:

	/* During probe time */
	pmic->irqs = devm_kzalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);

	/* While handling IRQs */
	for (i = 0; i < pmic->irqarray; i++) {
		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr));
		pending &= 0xff;

		for_each_set_bit(offset, &pending, 8)
			generic_handle_irq(pmic->irqs[offset + i * 8]);

	}

Right now, Hikey 970 sets:

	irq-num = <16>;
	irq-array = <2>;
	irq-mask-addr = <0x202>;
	irq-addr = <0x212>;

From the above code, it sounds to me that irq-array is the number of
bytes used for IRQ, while irq-num is the number of bits. E. g:

	irq_num =  irqarray * 8;

So, we can get rid of at least one of them.

Going further, the code provides an special treatment for some IRQs:

	#define HISI_IRQ_KEY_NUM		0
	#define HISI_IRQ_KEY_VALUE		0xc0
	#define HISI_IRQ_KEY_DOWN		7
	#define HISI_IRQ_KEY_UP			6

	for (i = 0; i < pmic->irqarray; i++) {
		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr));

	...
		/* solve powerkey order */
		if ((i == HISI_IRQ_KEY_NUM) &&
		    ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]);
			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]);
			pending &= (~HISI_IRQ_KEY_VALUE);
		}

As the values for HISI_IRQ_KEY_DOWN and HISI_IRQ_KEY_UP don't
depend on irqarray, it sounds to me that this is actually hardcoded 
for irqarray == 2.

So, I'll just get rid of those, replacing them by some defines inside
the code. If needed later, this patch can always be reverted.

> > +  'irq-mask-addr':
> > +    description: Address for the interrupt request mask
> > +
> > +  'irq-addr':
> > +    description: Address for the interrupt request  

Those two seems more standard to me: irq-mask-addr is the address to
enable/disable IRQs, while irq-addr is where the pending IRQs are
stored.

What would be the standard way to specify them both?

> > +
> > +  regulators:
> > +    type: object  
> 
> additionalProperties: false
> 
> > +
> > +    properties:
> > +      '#address-cells':
> > +        const: 1
> > +
> > +      '#size-cells':
> > +        const: 0
> > +
> > +    patternProperties:
> > +      '^ldo@[0-9]+$':  
> 
> Unit-addresses are hex.
>
> Also, doesn't match the example.

True. This should be, instead:

	patternProperties:
          '^ldo[0-9]+@[0-9a-f]+$':  

The name part of the property would better to stay in decimal,
as it makes a in order to match the public schematics:

	https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf

Using decimal values, the dmesg matches the schematics helps a lot when
dealing issues related to PM, as the names of the LDO lines will match
page 12 the schematics:

	ldo3: 1500 <--> 2000 mV at 1800 mV normal 
	ldo4: 1725 <--> 1900 mV at 1800 mV normal idle 
	ldo9: 1750 <--> 3300 mV at 2950 mV normal idle 
	ldo15: 1800 <--> 3000 mV at 2950 mV normal idle 
	ldo16: 1800 <--> 3000 mV at 2950 mV normal idle 
	ldo17: 2500 <--> 3300 mV at 2500 mV normal idle 
	ldo33: 2500 <--> 3300 mV at 2500 mV normal 
	ldo34: 2600 <--> 3300 mV at 2600 mV normal 
	ldo4: disabling
	ldo33: disabling

So, from above, looking at the datasheet, it is clear that
ldo33 - e. g. PCIe Switch VDD25 - is disabled.

> 
> > +        type: object
> > +
> > +        $ref: "/schemas/regulator/regulator.yaml#"
> > +
> > +        properties:
> > +          reg:
> > +            description: Enable register.
> > +  
> 
> > +          '#address-cells':
> > +            const: 1
> > +
> > +          '#size-cells':
> > +            const: 0  
> 
> No child nodes, you don't need these.

It is needed. However, this is at the second file of the DT.

See, as SPMI is actually a bus, the entire DT setting has 3
parts:
  - the SPMI controller;
  - the PMICs;
  - the regulators.

A complete example is:

	spmi: spmi@fff24000 {
		compatible = "hisilicon,spmi-controller";
		#address-cells = <2>;
		#size-cells = <0>;
		status = "ok";
		reg = <0x0 0xfff24000 0x0 0x1000>;
		spmi-channel = <2>;

		pmic: pmic@0 {
			compatible = "hisilicon,hi6421-spmi-pmic";
			slave_id = <0>;
			reg = <0 SPMI_USID>;

			#interrupt-cells = <2>;
			interrupt-controller;
			gpios = <&gpio28 0 0>;
			irq-mask-addr = <0x202>;
			irq-addr = <0x212>;

			regulators {
				#address-cells = <1>;
				#size-cells = <0>;

				ldo3: ldo3@16 {
					reg = <0x16>;
					vsel-reg = <0x51>;

					regulator-name = "ldo3";
					regulator-min-microvolt = <1500000>;
					regulator-max-microvolt = <2000000>;
					regulator-boot-on;

					enable-mask = <0x01>;

					voltage-table = <1500000>, <1550000>,
							<1600000>, <1650000>,
							<1700000>, <1725000>,
							<1750000>, <1775000>,
							<1800000>, <1825000>,
							<1850000>, <1875000>,
							<1900000>, <1925000>,
							<1950000>, <2000000>;
					off-on-delay-us = <20000>;
					startup-delay-us = <120>;
				};
				...
			};
		};
	};

The child nodes are at the regulator DT properties.

Well, I can drop those from here, adding them only at the regulator's
part, using "bus { ... };".

> > +
> > +          vsel-reg:
> > +            description: Voltage selector register.  
> 
> 'reg' can have multiple entries if you want.

Yes, I know. I was in doubt if I should either place vsel-reg on
a separate property or together with reg. I ended keeping it
in separate on the submitted patch series.

What makes more sense?

> 
> > +
> > +          enable-mask:
> > +            description: Bitmask used to enable the regulator.  
> 
> But if there's a shared enable reg, then you shouldn't have duplicate 
> addresses (same 'reg' value in multiple nodes).

At least for the LDOs supported on HiKey 970, values for
"reg" and "vsel-reg" are unique: each LDO has their own.

Right now, enable-mask is 0x01 for all LDOs at the Hikey 970
DTS. However, only 8 LDOs are currently present at the DTS. From
the schematics, it sounds that HiSilicon 6421v600 supports
at least 37 lines. I've no idea if enable-mask remains the same
for the other ones, nor if "reg" and "vsel-reg" won't be
unique in the general case.

> These perhaps should be driver data rather than in DT as it's all fixed 
> for this chip. We don't try to parameterize everything in DT.

I considered that. However, I've no idea about the values and
ranges for the other 29 LDOs. So, without knowing better about
this silicon, I prefer to keep those at DT.

> 
> > +
> > +          voltage-table:
> > +            description: Table with the selector items for the voltage regulator.
> > +            minItems: 2
> > +            maxItems: 16  
> 
> Needs a type $ref.

Ok. I'll add:

		$ref: /schemas/types.yaml#/definitions/uint32

> > +
> > +          off-on-delay-us:
> > +            description: Time required for changing state to enabled in microseconds.
> > +
> > +          startup-delay-us:
> > +            description: Startup time in microseconds.
> > +
> > +          idle-mode-mask:
> > +            description: Bitmask used to put the regulator on idle mode.
> > +
> > +          eco-microamp:
> > +            description: Maximum current while on idle mode.
> > +
> > +        required:
> > +          - reg
> > +          - vsel-reg
> > +          - enable-mask
> > +          - voltage-table
> > +          - off-on-delay-us
> > +          - startup-delay-us
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - regulators  
> 
> Add:
> 
> additionalProperties: false

Ok.

> 
> > +
> > +examples:
> > +  - |
> > +    /* pmic properties */
> > +
> > +    pmic: pmic@0 {
> > +      compatible = "hisilicon,hi6421-spmi-pmic";
> > +      slave_id = <0>;  
> 
> Not documented. I believe this is part of 'reg'.

Good point. I'll double-check this one, but I guess you're right.

> 
> > +      reg = <0 0>;
> > +
> > +      #interrupt-cells = <2>;
> > +      interrupt-controller;
> > +      gpios = <&gpio28 0 0>;
> > +      irq-num = <16>;
> > +      irq-array = <2>;
> > +      irq-mask-addr = <0x202 2>;
> > +      irq-addr = <0x212 2>;
> > +
> > +      #address-cells = <1>;
> > +      #size-cells = <0>;
> > +
> > +      regulators {
> > +          #address-cells = <1>;
> > +          #size-cells = <0>;
> > +
> > +        ldo3: ldo3@16 {
> > +          reg = <0x16>;
> > +          vsel-reg = <0x51>;
> > +
> > +          regulator-name = "ldo3";
> > +          regulator-min-microvolt = <1500000>;
> > +          regulator-max-microvolt = <2000000>;
> > +          regulator-boot-on;
> > +
> > +          enable-mask = <0x01>;
> > +
> > +          voltage-table = <1500000>, <1550000>, <1600000>, <1650000>,
> > +                          <1700000>, <1725000>, <1750000>, <1775000>,
> > +                          <1800000>, <1825000>, <1850000>, <1875000>,
> > +                          <1900000>, <1925000>, <1950000>, <2000000>;
> > +          off-on-delay-us = <20000>;
> > +          startup-delay-us = <120>;
> > +        };
> > +
> > +        ldo4: ldo4@17 { /* 40 PIN */
> > +          reg = <0x17>;
> > +          vsel-reg = <0x52>;
> > +
> > +          regulator-name = "ldo4";
> > +          regulator-min-microvolt = <1725000>;
> > +          regulator-max-microvolt = <1900000>;
> > +          regulator-boot-on;
> > +
> > +          enable-mask = <0x01>;
> > +          idle-mode-mask = <0x10>;
> > +          eco-microamp = <10000>;
> > +
> > +          hi6421-vsel = <0x52 0x07>;  
> 
> Not documented.

This is a left-over. I dropped this one, in favor of "vsel-reg"
(plus a mask for the voltage-table size).

> 
> > +          voltage-table = <1725000>, <1750000>, <1775000>, <1800000>,
> > +                          <1825000>, <1850000>, <1875000>, <1900000>;
> > +          off-on-delay-us = <20000>;
> > +          startup-delay-us = <120>;
> > +        };
> > +      };
> > +    };
> > 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..5aeb2ae12024
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
> > @@ -0,0 +1,54 @@
> > +# 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 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.
> > +
> > +properties:
> > +  $nodename:
> > +    pattern: "spmi@[0-9a-f]"
> > +
> > +  compatible:
> > +    const: hisilicon,spmi-controller  
> 
> Needs an SoC specific compatible.

What about:
	hisilicon,kirin970-spmi-controller 

> 
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  "#address-cells":
> > +    const: 2
> > +
> > +  "#size-cells":
> > +    const: 0
> > +
> > +  spmi-channel:
> > +    description: number of the SPMI channel where the PMIC is connected
> > +
> > +patternProperties:
> > +  "^pmic@[0-9a-f]$":
> > +    $ref: "/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#"
> > +
> > +examples:
> > +  - |
> > +    spmi: spmi@fff24000 {
> > +      compatible = "hisilicon,spmi-controller";
> > +      #address-cells = <2>;
> > +      #size-cells = <0>;
> > +      status = "ok";
> > +      reg = <0x0 0xfff24000 0x0 0x1000>;
> > +      spmi-channel = <2>;  
> 
> Does this go in the SPMI controller or child (pmic)?

Those belong to the SPMI controller. Maybe I did some mess trying to
split up DT in order to place the Kirin970 SPMI bus controller on
one file, and the HiSilicon 6421v600 on another one.

I ended needing to duplicate some things, as otherwise the DT checks fail.

Basically, the full DT is:

	spmi: spmi@fff24000 {
		/* Kirin 970 SPMI controller props */

		pmic: pmic@0 {
			/* HiSilicon 6421v600 PMIC props */

			regulators {
				ldo3: ldo3@16 {
					/* HiSilicon 6421v600 ldo3 regulator props */
				};
				ldo4: ldo3@17 {
					/* HiSilicon 6421v600 ldo4 regulator props */
				};
				...
				ldo34: ldo3@33 {
					/* HiSilicon 6421v600 ldo34 regulator props */
				};
			};
		};
	};

Thanks,
Mauro

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-18  9:13     ` Mauro Carvalho Chehab
@ 2020-08-18 10:37       ` Mauro Carvalho Chehab
  2020-08-18 17:07       ` Rob Herring
  1 sibling, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-18 10:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Greg Kroah-Hartman, linuxarm, mauro.chehab, Lee Jones,
	Stephen Boyd, devicetree, linux-kernel, linux-arm-msm

Em Tue, 18 Aug 2020 11:13:51 +0200
Mauro Carvalho Chehab <mchehab+huawei@kernel.org> escreveu:

> Em Mon, 17 Aug 2020 14:12:11 -0600
> Rob Herring <robh@kernel.org> escreveu:
> 

> > > +  'irq-mask-addr':
> > > +    description: Address for the interrupt request mask
> > > +
> > > +  'irq-addr':
> > > +    description: Address for the interrupt request  
> 
> Those two seems more standard to me: irq-mask-addr is the address to
> enable/disable IRQs, while irq-addr is where the pending IRQs are
> stored.
> 
> What would be the standard way to specify them both?

After another look at the driver, both seems to be fixed
address. There are even some comments that implies that:

	/* SOC_PMIC_IRQ_MASK_0_ADDR */
	ret = of_property_read_u32(np, "irq-mask-addr", &pmic->irq_mask_addr);

	/* SOC_PMIC_IRQ0_ADDR */
	ret = of_property_read_u32(np, "irq-addr", &pmic->irq_addr);

So, I'll just drop the entire set of irq-* properties. The PMIC part
should be just this:

	#include <dt-bindings/spmi/spmi.h>
...
		pmic: pmic@0 {
			compatible = "hisilicon,hi6421v600-spmi";
			reg = <0 SPMI_USID>;

			#interrupt-cells = <2>;
			interrupt-controller;
			gpios = <&gpio28 0 0>;
...
		};



Thanks,
Mauro

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH v3.1 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-17  7:11 ` [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties Mauro Carvalho Chehab
  2020-08-17 20:12   ` Rob Herring
@ 2020-08-18 11:10   ` Mauro Carvalho Chehab
  2020-08-18 14:19     ` Greg Kroah-Hartman
  1 sibling, 1 reply; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-18 11:10 UTC (permalink / raw)
  To: Rob Herring
  Cc: Greg Kroah-Hartman, linuxarm, mauro.chehab, Lee Jones,
	Stephen Boyd, devicetree, linux-kernel, linux-arm-msm

From e464ec2c38c083403b556e60f189ee8ae2f2c9c6 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Date: Fri, 31 Jul 2020 09:46:02 +0200
Subject: [PATCH] dt: document HiSilicon SPMI controller and mfd/regulator
 properties

Add documentation for the properties needed by the HiSilicon
6421v600 driver, and by the SPMI controller used to access
the chipset.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

---

v3.1:
  - Changed the DT properties to better match upstream requirements

PS.: I opted to submit just this patch, instead of the entire
series, in order to avoid flooding people's ML.

I'll be posting the full series again after DT specs match
upstream requirements.


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..881bbd83df65
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
@@ -0,0 +1,159 @@
+# 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/spmi/hisilicon,hisi-spmi-controller.yaml.
+
+properties:
+  $nodename:
+    pattern: "pmic@[0-9a-f]"
+
+  compatible:
+    const: hisilicon,hi6421v600-spmi
+
+  reg:
+    maxItems: 1
+
+  '#interrupt-cells':
+    const: 2
+
+  interrupt-controller:
+    description:
+      Identify that the PMIC is capable of behaving as an interrupt controller.
+
+  gpios:
+    maxItems: 1
+
+  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#"
+
+        properties:
+          reg:
+            description: Enable register.
+
+          '#address-cells':
+            const: 1
+
+          '#size-cells':
+            const: 0
+
+          vsel-reg:
+            description: Voltage selector register.
+
+          enable-mask:
+            description: Bitmask used to enable the regulator.
+
+          voltage-table:
+            description: Table with the selector items for the voltage regulator.
+            minItems: 2
+            maxItems: 16
+
+          off-on-delay-us:
+            description: Time required for changing state to enabled in microseconds.
+
+          startup-delay-us:
+            description: Startup time in microseconds.
+
+          idle-mode-mask:
+            description: Bitmask used to put the regulator on idle mode.
+
+          eco-microamp:
+            description: Maximum current while on idle mode.
+
+        required:
+          - reg
+          - vsel-reg
+          - enable-mask
+          - voltage-table
+          - off-on-delay-us
+          - startup-delay-us
+
+required:
+  - compatible
+  - reg
+  - regulators
+
+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@16 {
+          reg = <0x16>;
+          vsel-reg = <0x51>;
+
+          regulator-name = "ldo3";
+          regulator-min-microvolt = <1500000>;
+          regulator-max-microvolt = <2000000>;
+          regulator-boot-on;
+
+          enable-mask = <0x01>;
+
+          voltage-table = <1500000>, <1550000>, <1600000>, <1650000>,
+                          <1700000>, <1725000>, <1750000>, <1775000>,
+                          <1800000>, <1825000>, <1850000>, <1875000>,
+                          <1900000>, <1925000>, <1950000>, <2000000>;
+          off-on-delay-us = <20000>;
+          startup-delay-us = <120>;
+        };
+
+        ldo4: ldo4@17 { /* 40 PIN */
+          reg = <0x17>;
+          vsel-reg = <0x52>;
+
+          regulator-name = "ldo4";
+          regulator-min-microvolt = <1725000>;
+          regulator-max-microvolt = <1900000>;
+          regulator-boot-on;
+
+          enable-mask = <0x01>;
+          idle-mode-mask = <0x10>;
+          eco-microamp = <10000>;
+
+          hi6421-vsel = <0x52 0x07>;
+          voltage-table = <1725000>, <1750000>, <1775000>, <1800000>,
+                          <1825000>, <1850000>, <1875000>, <1900000>;
+          off-on-delay-us = <20000>;
+          startup-delay-us = <120>;
+        };
+      };
+    };
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..b1cfa9c3aca6
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
@@ -0,0 +1,62 @@
+# 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.
+
+properties:
+  $nodename:
+    pattern: "spmi@[0-9a-f]"
+
+  compatible:
+    const: hisilicon,kirin970-spmi-controller
+
+  reg:
+    maxItems: 1
+
+  spmi-channel:
+    description: |
+      number of the Kirin 970 SPMI channel where the SPMI devices are connected.
+
+required:
+ - compatible
+ - reg
+ - spmi-channel
+
+patternProperties:
+  "^pmic@[0-9a-f]$":
+    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
+      Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml.
+
+examples:
+  - |
+    bus {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      spmi: spmi@fff24000 {
+        compatible = "hisilicon,kirin970-spmi-controller";
+        status = "ok";
+        reg = <0x0 0xfff24000 0x0 0x1000>;
+        spmi-channel = <2>;
+
+        pmic@0 {
+          /* pmic properties */
+        };
+      };
+    };

^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 00/44] SPMI patches needed by Hikey 970
  2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
                   ` (44 preceding siblings ...)
  2020-08-17  7:32 ` [PATCH v3 00/44] SPMI patches needed by " Greg Kroah-Hartman
@ 2020-08-18 14:17 ` Greg Kroah-Hartman
  2020-08-18 14:28   ` Mauro Carvalho Chehab
  45 siblings, 1 reply; 57+ messages in thread
From: Greg Kroah-Hartman @ 2020-08-18 14:17 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: devel, devicetree, Rob Herring, linux-arm-msm, linuxarm, Wei Xu,
	linux-kernel, Stephen Boyd, Rob Herring, mauro.chehab, Lee Jones,
	David S. Miller, linux-arm-kernel

On Mon, Aug 17, 2020 at 09:10:19AM +0200, Mauro Carvalho Chehab wrote:
> Hi Greg,
> 
> This patch series is part of a work I'm doing in order to be able to support
> a HiKey 970 board that I recently got on my hands.

With this applied, I get the following build error:
ERROR: modpost: "__spmi_driver_register" [drivers/staging/hikey9xx/hi6421-spmi-pmic.ko] undefined!
ERROR: modpost: "spmi_ext_register_writel" [drivers/staging/hikey9xx/hi6421-spmi-pmic.ko] undefined!
ERROR: modpost: "spmi_ext_register_readl" [drivers/staging/hikey9xx/hi6421-spmi-pmic.ko] undefined!
ERROR: modpost: "spmi_controller_add" [drivers/staging/hikey9xx/hisi-spmi-controller.ko] undefined!
ERROR: modpost: "spmi_controller_alloc" [drivers/staging/hikey9xx/hisi-spmi-controller.ko] undefined!
ERROR: modpost: "spmi_controller_remove" [drivers/staging/hikey9xx/hisi-spmi-controller.ko] undefined!


I'll take this in my testing tree for now, can you send a follow-on
patch to fix this?

And I only took the first 41 patches in this series, see my comments on
the rest.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 42/44] MAINTAINERS: add an entry for HiSilicon 6421v600 drivers
  2020-08-17  7:11 ` [PATCH v3 42/44] MAINTAINERS: add an entry for HiSilicon 6421v600 drivers Mauro Carvalho Chehab
@ 2020-08-18 14:18   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 57+ messages in thread
From: Greg Kroah-Hartman @ 2020-08-18 14:18 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linuxarm, mauro.chehab, David S. Miller, Rob Herring, linux-kernel

On Mon, Aug 17, 2020 at 09:11:01AM +0200, Mauro Carvalho Chehab wrote:
> Add an entry for the SPMI, MFD and PMIC parts of the
> HiSilicon 6421v600 support.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> ---
>  MAINTAINERS | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 956ecd5ba426..e2de0b2119fd 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7824,6 +7824,12 @@ F:	drivers/crypto/hisilicon/sec2/sec_crypto.c
>  F:	drivers/crypto/hisilicon/sec2/sec_crypto.h
>  F:	drivers/crypto/hisilicon/sec2/sec_main.c
>  
> +HISILICON STAGING DRIVERS FOR HIKEY 960/970
> +M:	Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> +L:	linux-kernel@vger.kernel.org

staging driver patches are not sent to this list, please use the driver
devel list instead of lkml.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3.1 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-18 11:10   ` [PATCH v3.1 " Mauro Carvalho Chehab
@ 2020-08-18 14:19     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 57+ messages in thread
From: Greg Kroah-Hartman @ 2020-08-18 14:19 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Rob Herring, linuxarm, mauro.chehab, Lee Jones, Stephen Boyd,
	devicetree, linux-kernel, linux-arm-msm

On Tue, Aug 18, 2020 at 01:10:24PM +0200, Mauro Carvalho Chehab wrote:
> From e464ec2c38c083403b556e60f189ee8ae2f2c9c6 Mon Sep 17 00:00:00 2001
> From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> Date: Fri, 31 Jul 2020 09:46:02 +0200
> Subject: [PATCH] dt: document HiSilicon SPMI controller and mfd/regulator
>  properties
> 
> Add documentation for the properties needed by the HiSilicon
> 6421v600 driver, and by the SPMI controller used to access
> the chipset.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> 

Did you mean to enclose the whole patch, headers and all in here?


> ---
> 
> v3.1:
>   - Changed the DT properties to better match upstream requirements
> 
> PS.: I opted to submit just this patch, instead of the entire
> series, in order to avoid flooding people's ML.
> 
> I'll be posting the full series again after DT specs match
> upstream requirements.
> 
> 
> diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml

staging drivers should be self-contained, please keep dt files within
the staging driver directory for the driver until they move out of
staging if at all possible.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 00/44] SPMI patches needed by Hikey 970
  2020-08-18 14:17 ` Greg Kroah-Hartman
@ 2020-08-18 14:28   ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-18 14:28 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, devicetree, Rob Herring, linux-arm-msm, linuxarm, Wei Xu,
	linux-kernel, Stephen Boyd, Rob Herring, mauro.chehab, Lee Jones,
	David S. Miller, linux-arm-kernel

Em Tue, 18 Aug 2020 16:17:50 +0200
Greg Kroah-Hartman <gregkh@linuxfoundation.org> escreveu:

> On Mon, Aug 17, 2020 at 09:10:19AM +0200, Mauro Carvalho Chehab wrote:
> > Hi Greg,
> > 
> > This patch series is part of a work I'm doing in order to be able to support
> > a HiKey 970 board that I recently got on my hands.  
> 
> With this applied, I get the following build error:
> ERROR: modpost: "__spmi_driver_register" [drivers/staging/hikey9xx/hi6421-spmi-pmic.ko] undefined!
> ERROR: modpost: "spmi_ext_register_writel" [drivers/staging/hikey9xx/hi6421-spmi-pmic.ko] undefined!
> ERROR: modpost: "spmi_ext_register_readl" [drivers/staging/hikey9xx/hi6421-spmi-pmic.ko] undefined!
> ERROR: modpost: "spmi_controller_add" [drivers/staging/hikey9xx/hisi-spmi-controller.ko] undefined!
> ERROR: modpost: "spmi_controller_alloc" [drivers/staging/hikey9xx/hisi-spmi-controller.ko] undefined!
> ERROR: modpost: "spmi_controller_remove" [drivers/staging/hikey9xx/hisi-spmi-controller.ko] undefined!
> 
> 
> I'll take this in my testing tree for now, can you send a follow-on
> patch to fix this?

Surely. That's because it got moved from drivers/spmi/Kconfig.
The Kconfig var was inside a:

if SPMI
...
endif

This driver should "depends on SPMI". I'll send you a patch in a few.

Thanks,
Mauro

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-18  9:13     ` Mauro Carvalho Chehab
  2020-08-18 10:37       ` Mauro Carvalho Chehab
@ 2020-08-18 17:07       ` Rob Herring
  2020-08-18 22:18         ` Mauro Carvalho Chehab
  1 sibling, 1 reply; 57+ messages in thread
From: Rob Herring @ 2020-08-18 17:07 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Greg Kroah-Hartman, linuxarm, mauro.chehab, Lee Jones,
	Stephen Boyd, devicetree, linux-kernel, linux-arm-msm

On Tue, Aug 18, 2020 at 11:13:51AM +0200, Mauro Carvalho Chehab wrote:
> Em Mon, 17 Aug 2020 14:12:11 -0600
> Rob Herring <robh@kernel.org> escreveu:
> 
> > On Mon, Aug 17, 2020 at 09:11:02AM +0200, Mauro Carvalho Chehab wrote:
> > > Add documentation for the properties needed by the HiSilicon
> > > 6421v600 driver, and by the SPMI controller used to access
> > > the chipset.
> > > 
> > > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> > > ---
> > >  .../mfd/hisilicon,hi6421-spmi-pmic.yaml       | 182 ++++++++++++++++++
> > >  .../spmi/hisilicon,hisi-spmi-controller.yaml  |  54 ++++++
> > >  2 files changed, 236 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> > >  create mode 100644 Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.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..95494114554d
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
> > > @@ -0,0 +1,182 @@
> > > +# 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 uses a MIPI System Power Management (SPMI) bus in order
> > > +  to provide 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/spmi/hisilicon,hisi-spmi-controller.yaml.
> > > +
> > > +properties:
> > > +  $nodename:
> > > +    pattern: "pmic@[0-9a-f]"
> > > +
> > > +  compatible:
> > > +    const: hisilicon,hi6421-spmi-pmic  
> > 
> > -spmi-pmic is redundant. Can the hi6421 be anything else?
> 
> There are other HiSilicom 6421 variants that don't use SPMI bus:
> 
> 	Documentation/devicetree/bindings/mfd/hi6421.txt:       "hisilicon,hi6421-pmic";
> 	Documentation/devicetree/bindings/mfd/hi6421.txt:       "hisilicon,hi6421v530-pmic";
> 
> The DT file on Kernel 4.9 uses hi6421v600 (although the schematics
> from 96boards name it as hi6421v610).
> 
> While I don't mind much,would prefer to keep "spmi" on its name, in order
> to distinguish this one from the non-spmi variants.

Fine, though since probing is bus specific it works fine if the same 
compatible is used with different buses. Devices with multiple bus 
options are pretty common.


> Maybe we use this for compatible:
> 
> 	hisilicon,hi6421v600-spmi

Okay.

> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  spmi-channel:
> > > +    description: number of the SPMI channel where the PMIC is connected  
> > 
> > This looks like a common (to SPMI), but it's not something defined in 
> > spmi.txt 
> 
> This one is not part of the SPMI core. It is stored inside a private 
> structure inside at the HiSilicon spmi controller driver. It is stored 
> there as ctrl_dev->channel, and it is used to calculate the register offset
> for readl():
> 
> 	offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
> 	offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
> 	do {
> 		status = readl(base + offset);
> 	...
> 
> The SPMI bus is somewhat similar to I2C: it is a 2-wire serial bus
> with up to 16 devices connected to it.
> 
> Now, most modern I2C chipsets provide multiple independent I2C
> channels, on different pins. Also, on some chipsets, certain
> GPIO pins can be used either as GPIO or as I2C.
> 
> I strongly suspect that this is the case here: according with
> the Hikey 970 schematics:
> 
> 	https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf
> 
> The pins used by SPMI clock/data can also be used as GPIO.
> 
> While I don't have access to the datasheets for Kirin 970 (or any other
> chipsets on this board), for me, it sounds that different GPIO pins
> are allowed to use SPMI. The "spmi-channel" property specifies
> what pins will be used for SPMI, among the ones that are
> compatible with MIPI SPMI specs.

Based on this, I think it should be called 'hisilicon,spmi-channel' as 
it is vendor specific. 


> > (which should ideally be converted to schema first). 
> 
> I can try porting spmi schema to yaml on a separate patch,
> and submit it independently of this series.
> 
> > Minimally, 
> > it needs a better explanation and determination if it should be common 
> > or is HiSilicon specific.
> 
> What about:
> 
>   spmi-channel:
>     description: |
>       number of the SPMI channel at the HiSilicon SoC that will
>       be used for the MIPI SPMI controller.
> 
> > 
> > > +
> > > +  '#interrupt-cells':
> > > +    const: 2
> > > +
> > > +  interrupt-controller:
> > > +    description:
> > > +      Identify that the PMIC is capable of behaving as an interrupt controller.  
> > 
> > No need to redefine common properties if nothing specific to this device 
> > to say. Just:
> > 
> > interrupt-controller: true
> 
> Ok.
> 
> > 
> > > +
> > > +  gpios:
> > > +    maxItems: 1
> > > +
> > > +  irq-num:
> > > +    description: Interrupt request number
> > > +
> > > +  'irq-array':
> > > +    description: Interrupt request array
> > > +
> > > +  'irq-mask-addr':
> > > +    description: Address for the interrupt request mask
> > > +
> > > +  'irq-addr':
> > > +    description: Address for the interrupt request  
> > 
> > What's all these non-standard interrupt properties?
> 
> After doing a deeper look at the code which handles IRQs on this PMIC,
> I'm considering to get rid of two properties: irq-num and irq-array.
> 
> See, the code does this:
> 
> 	/* During probe time */
> 	pmic->irqs = devm_kzalloc(dev, pmic->irqnum * sizeof(int), GFP_KERNEL);
> 
> 	/* While handling IRQs */
> 	for (i = 0; i < pmic->irqarray; i++) {
> 		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr));
> 		pending &= 0xff;
> 
> 		for_each_set_bit(offset, &pending, 8)
> 			generic_handle_irq(pmic->irqs[offset + i * 8]);
> 
> 	}
> 
> Right now, Hikey 970 sets:
> 
> 	irq-num = <16>;
> 	irq-array = <2>;
> 	irq-mask-addr = <0x202>;
> 	irq-addr = <0x212>;
> 
> From the above code, it sounds to me that irq-array is the number of
> bytes used for IRQ, while irq-num is the number of bits. E. g:
> 
> 	irq_num =  irqarray * 8;
> 
> So, we can get rid of at least one of them.
> 
> Going further, the code provides an special treatment for some IRQs:
> 
> 	#define HISI_IRQ_KEY_NUM		0
> 	#define HISI_IRQ_KEY_VALUE		0xc0
> 	#define HISI_IRQ_KEY_DOWN		7
> 	#define HISI_IRQ_KEY_UP			6
> 
> 	for (i = 0; i < pmic->irqarray; i++) {
> 		pending = hi6421_spmi_pmic_read(pmic, (i + pmic->irq_addr));
> 
> 	...
> 		/* solve powerkey order */
> 		if ((i == HISI_IRQ_KEY_NUM) &&
> 		    ((pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE)) {
> 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_DOWN]);
> 			generic_handle_irq(pmic->irqs[HISI_IRQ_KEY_UP]);
> 			pending &= (~HISI_IRQ_KEY_VALUE);
> 		}
> 
> As the values for HISI_IRQ_KEY_DOWN and HISI_IRQ_KEY_UP don't
> depend on irqarray, it sounds to me that this is actually hardcoded 
> for irqarray == 2.
> 
> So, I'll just get rid of those, replacing them by some defines inside
> the code. If needed later, this patch can always be reverted.
> 
> > > +  'irq-mask-addr':
> > > +    description: Address for the interrupt request mask
> > > +
> > > +  'irq-addr':
> > > +    description: Address for the interrupt request  
> 
> Those two seems more standard to me: irq-mask-addr is the address to
> enable/disable IRQs, while irq-addr is where the pending IRQs are
> stored.
> 
> What would be the standard way to specify them both?
> 
> > > +
> > > +  regulators:
> > > +    type: object  
> > 
> > additionalProperties: false
> > 
> > > +
> > > +    properties:
> > > +      '#address-cells':
> > > +        const: 1
> > > +
> > > +      '#size-cells':
> > > +        const: 0
> > > +
> > > +    patternProperties:
> > > +      '^ldo@[0-9]+$':  
> > 
> > Unit-addresses are hex.
> >
> > Also, doesn't match the example.
> 
> True. This should be, instead:
> 
> 	patternProperties:
>           '^ldo[0-9]+@[0-9a-f]+$':  
> 
> The name part of the property would better to stay in decimal,
> as it makes a in order to match the public schematics:
> 
> 	https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf
> 
> Using decimal values, the dmesg matches the schematics helps a lot when
> dealing issues related to PM, as the names of the LDO lines will match
> page 12 the schematics:
> 
> 	ldo3: 1500 <--> 2000 mV at 1800 mV normal 
> 	ldo4: 1725 <--> 1900 mV at 1800 mV normal idle 
> 	ldo9: 1750 <--> 3300 mV at 2950 mV normal idle 
> 	ldo15: 1800 <--> 3000 mV at 2950 mV normal idle 
> 	ldo16: 1800 <--> 3000 mV at 2950 mV normal idle 
> 	ldo17: 2500 <--> 3300 mV at 2500 mV normal idle 
> 	ldo33: 2500 <--> 3300 mV at 2500 mV normal 
> 	ldo34: 2600 <--> 3300 mV at 2600 mV normal 
> 	ldo4: disabling
> 	ldo33: disabling
> 
> So, from above, looking at the datasheet, it is clear that
> ldo33 - e. g. PCIe Switch VDD25 - is disabled.

Makes sense.

> > > +        type: object
> > > +
> > > +        $ref: "/schemas/regulator/regulator.yaml#"
> > > +
> > > +        properties:
> > > +          reg:
> > > +            description: Enable register.
> > > +  
> > 
> > > +          '#address-cells':
> > > +            const: 1
> > > +
> > > +          '#size-cells':
> > > +            const: 0  
> > 
> > No child nodes, you don't need these.
> 
> It is needed. However, this is at the second file of the DT.
> 
> See, as SPMI is actually a bus, the entire DT setting has 3
> parts:
>   - the SPMI controller;
>   - the PMICs;
>   - the regulators.
> 
> A complete example is:
> 
> 	spmi: spmi@fff24000 {
> 		compatible = "hisilicon,spmi-controller";
> 		#address-cells = <2>;
> 		#size-cells = <0>;
> 		status = "ok";
> 		reg = <0x0 0xfff24000 0x0 0x1000>;
> 		spmi-channel = <2>;
> 
> 		pmic: pmic@0 {
> 			compatible = "hisilicon,hi6421-spmi-pmic";
> 			slave_id = <0>;
> 			reg = <0 SPMI_USID>;
> 
> 			#interrupt-cells = <2>;
> 			interrupt-controller;
> 			gpios = <&gpio28 0 0>;
> 			irq-mask-addr = <0x202>;
> 			irq-addr = <0x212>;
> 
> 			regulators {
> 				#address-cells = <1>;
> 				#size-cells = <0>;
> 
> 				ldo3: ldo3@16 {
> 					reg = <0x16>;
> 					vsel-reg = <0x51>;
> 
> 					regulator-name = "ldo3";
> 					regulator-min-microvolt = <1500000>;
> 					regulator-max-microvolt = <2000000>;
> 					regulator-boot-on;
> 
> 					enable-mask = <0x01>;
> 
> 					voltage-table = <1500000>, <1550000>,
> 							<1600000>, <1650000>,
> 							<1700000>, <1725000>,
> 							<1750000>, <1775000>,
> 							<1800000>, <1825000>,
> 							<1850000>, <1875000>,
> 							<1900000>, <1925000>,
> 							<1950000>, <2000000>;
> 					off-on-delay-us = <20000>;
> 					startup-delay-us = <120>;
> 				};
> 				...
> 			};
> 		};
> 	};
> 
> The child nodes are at the regulator DT properties.
> 
> Well, I can drop those from here, adding them only at the regulator's
> part, using "bus { ... };".
> 
> > > +
> > > +          vsel-reg:
> > > +            description: Voltage selector register.  
> > 
> > 'reg' can have multiple entries if you want.
> 
> Yes, I know. I was in doubt if I should either place vsel-reg on
> a separate property or together with reg. I ended keeping it
> in separate on the submitted patch series.
> 
> What makes more sense?

Really, not putting it in DT. Like other things, it's fixed for the 
chip.


> > > +
> > > +          enable-mask:
> > > +            description: Bitmask used to enable the regulator.  
> > 
> > But if there's a shared enable reg, then you shouldn't have duplicate 
> > addresses (same 'reg' value in multiple nodes).
> 
> At least for the LDOs supported on HiKey 970, values for
> "reg" and "vsel-reg" are unique: each LDO has their own.
> 
> Right now, enable-mask is 0x01 for all LDOs at the Hikey 970
> DTS. However, only 8 LDOs are currently present at the DTS. From
> the schematics, it sounds that HiSilicon 6421v600 supports
> at least 37 lines. I've no idea if enable-mask remains the same
> for the other ones, nor if "reg" and "vsel-reg" won't be
> unique in the general case.
> 
> > These perhaps should be driver data rather than in DT as it's all fixed 
> > for this chip. We don't try to parameterize everything in DT.
> 
> I considered that. However, I've no idea about the values and
> ranges for the other 29 LDOs. So, without knowing better about
> this silicon, I prefer to keep those at DT.
> 
> > 
> > > +
> > > +          voltage-table:
> > > +            description: Table with the selector items for the voltage regulator.
> > > +            minItems: 2
> > > +            maxItems: 16  
> > 
> > Needs a type $ref.
> 
> Ok. I'll add:
> 
> 		$ref: /schemas/types.yaml#/definitions/uint32
> 
> > > +
> > > +          off-on-delay-us:
> > > +            description: Time required for changing state to enabled in microseconds.
> > > +
> > > +          startup-delay-us:
> > > +            description: Startup time in microseconds.
> > > +
> > > +          idle-mode-mask:
> > > +            description: Bitmask used to put the regulator on idle mode.
> > > +
> > > +          eco-microamp:
> > > +            description: Maximum current while on idle mode.
> > > +
> > > +        required:
> > > +          - reg
> > > +          - vsel-reg
> > > +          - enable-mask
> > > +          - voltage-table
> > > +          - off-on-delay-us
> > > +          - startup-delay-us
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - regulators  
> > 
> > Add:
> > 
> > additionalProperties: false
> 
> Ok.
> 
> > 
> > > +
> > > +examples:
> > > +  - |
> > > +    /* pmic properties */
> > > +
> > > +    pmic: pmic@0 {
> > > +      compatible = "hisilicon,hi6421-spmi-pmic";
> > > +      slave_id = <0>;  
> > 
> > Not documented. I believe this is part of 'reg'.
> 
> Good point. I'll double-check this one, but I guess you're right.
> 
> > 
> > > +      reg = <0 0>;
> > > +
> > > +      #interrupt-cells = <2>;
> > > +      interrupt-controller;
> > > +      gpios = <&gpio28 0 0>;
> > > +      irq-num = <16>;
> > > +      irq-array = <2>;
> > > +      irq-mask-addr = <0x202 2>;
> > > +      irq-addr = <0x212 2>;
> > > +
> > > +      #address-cells = <1>;
> > > +      #size-cells = <0>;
> > > +
> > > +      regulators {
> > > +          #address-cells = <1>;
> > > +          #size-cells = <0>;
> > > +
> > > +        ldo3: ldo3@16 {
> > > +          reg = <0x16>;
> > > +          vsel-reg = <0x51>;
> > > +
> > > +          regulator-name = "ldo3";
> > > +          regulator-min-microvolt = <1500000>;
> > > +          regulator-max-microvolt = <2000000>;
> > > +          regulator-boot-on;
> > > +
> > > +          enable-mask = <0x01>;
> > > +
> > > +          voltage-table = <1500000>, <1550000>, <1600000>, <1650000>,
> > > +                          <1700000>, <1725000>, <1750000>, <1775000>,
> > > +                          <1800000>, <1825000>, <1850000>, <1875000>,
> > > +                          <1900000>, <1925000>, <1950000>, <2000000>;
> > > +          off-on-delay-us = <20000>;
> > > +          startup-delay-us = <120>;
> > > +        };
> > > +
> > > +        ldo4: ldo4@17 { /* 40 PIN */
> > > +          reg = <0x17>;
> > > +          vsel-reg = <0x52>;
> > > +
> > > +          regulator-name = "ldo4";
> > > +          regulator-min-microvolt = <1725000>;
> > > +          regulator-max-microvolt = <1900000>;
> > > +          regulator-boot-on;
> > > +
> > > +          enable-mask = <0x01>;
> > > +          idle-mode-mask = <0x10>;
> > > +          eco-microamp = <10000>;
> > > +
> > > +          hi6421-vsel = <0x52 0x07>;  
> > 
> > Not documented.
> 
> This is a left-over. I dropped this one, in favor of "vsel-reg"
> (plus a mask for the voltage-table size).
> 
> > 
> > > +          voltage-table = <1725000>, <1750000>, <1775000>, <1800000>,
> > > +                          <1825000>, <1850000>, <1875000>, <1900000>;
> > > +          off-on-delay-us = <20000>;
> > > +          startup-delay-us = <120>;
> > > +        };
> > > +      };
> > > +    };
> > > 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..5aeb2ae12024
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
> > > @@ -0,0 +1,54 @@
> > > +# 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 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.
> > > +
> > > +properties:
> > > +  $nodename:
> > > +    pattern: "spmi@[0-9a-f]"
> > > +
> > > +  compatible:
> > > +    const: hisilicon,spmi-controller  
> > 
> > Needs an SoC specific compatible.
> 
> What about:
> 	hisilicon,kirin970-spmi-controller 

Is 'kirin970' really the SoC name? The older ones are all 'hi[0-9]+'.

> 
> > 
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  "#address-cells":
> > > +    const: 2
> > > +
> > > +  "#size-cells":
> > > +    const: 0
> > > +
> > > +  spmi-channel:
> > > +    description: number of the SPMI channel where the PMIC is connected
> > > +
> > > +patternProperties:
> > > +  "^pmic@[0-9a-f]$":
> > > +    $ref: "/schemas/mfd/hisilicon,hi6421-spmi-pmic.yaml#"
> > > +
> > > +examples:
> > > +  - |
> > > +    spmi: spmi@fff24000 {
> > > +      compatible = "hisilicon,spmi-controller";
> > > +      #address-cells = <2>;
> > > +      #size-cells = <0>;
> > > +      status = "ok";
> > > +      reg = <0x0 0xfff24000 0x0 0x1000>;
> > > +      spmi-channel = <2>;  
> > 
> > Does this go in the SPMI controller or child (pmic)?
> 
> Those belong to the SPMI controller. Maybe I did some mess trying to
> split up DT in order to place the Kirin970 SPMI bus controller on
> one file, and the HiSilicon 6421v600 on another one.
> 
> I ended needing to duplicate some things, as otherwise the DT checks fail.
> 
> Basically, the full DT is:
> 
> 	spmi: spmi@fff24000 {
> 		/* Kirin 970 SPMI controller props */
> 
> 		pmic: pmic@0 {
> 			/* HiSilicon 6421v600 PMIC props */
> 
> 			regulators {
> 				ldo3: ldo3@16 {
> 					/* HiSilicon 6421v600 ldo3 regulator props */
> 				};
> 				ldo4: ldo3@17 {
> 					/* HiSilicon 6421v600 ldo4 regulator props */
> 				};
> 				...
> 				ldo34: ldo3@33 {
> 					/* HiSilicon 6421v600 ldo34 regulator props */
> 				};
> 			};
> 		};
> 	};
> 
> Thanks,
> Mauro

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-18 17:07       ` Rob Herring
@ 2020-08-18 22:18         ` Mauro Carvalho Chehab
  2020-08-19 20:48           ` Rob Herring
  0 siblings, 1 reply; 57+ messages in thread
From: Mauro Carvalho Chehab @ 2020-08-18 22:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: Greg Kroah-Hartman, linuxarm, mauro.chehab, Lee Jones,
	Stephen Boyd, devicetree, linux-kernel, linux-arm-msm

Em Tue, 18 Aug 2020 11:07:55 -0600
Rob Herring <robh@kernel.org> escreveu:

> > > > +  spmi-channel:
> > > > +    description: number of the SPMI channel where the PMIC is connected    
> > > 
> > > This looks like a common (to SPMI), but it's not something defined in 
> > > spmi.txt   
> > 
> > This one is not part of the SPMI core. It is stored inside a private 
> > structure inside at the HiSilicon spmi controller driver. It is stored 
> > there as ctrl_dev->channel, and it is used to calculate the register offset
> > for readl():
> > 
> > 	offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
> > 	offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
> > 	do {
> > 		status = readl(base + offset);
> > 	...
> > 
> > The SPMI bus is somewhat similar to I2C: it is a 2-wire serial bus
> > with up to 16 devices connected to it.
> > 
> > Now, most modern I2C chipsets provide multiple independent I2C
> > channels, on different pins. Also, on some chipsets, certain
> > GPIO pins can be used either as GPIO or as I2C.
> > 
> > I strongly suspect that this is the case here: according with
> > the Hikey 970 schematics:
> > 
> > 	https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf
> > 
> > The pins used by SPMI clock/data can also be used as GPIO.
> > 
> > While I don't have access to the datasheets for Kirin 970 (or any other
> > chipsets on this board), for me, it sounds that different GPIO pins
> > are allowed to use SPMI. The "spmi-channel" property specifies
> > what pins will be used for SPMI, among the ones that are
> > compatible with MIPI SPMI specs.  
> 
> Based on this, I think it should be called 'hisilicon,spmi-channel' as 
> it is vendor specific. 

I'm fine with "hisilicon,spmi-channel".

> > > > +
> > > > +          vsel-reg:
> > > > +            description: Voltage selector register.    
> > > 
> > > 'reg' can have multiple entries if you want.  
> > 
> > Yes, I know. I was in doubt if I should either place vsel-reg on
> > a separate property or together with reg. I ended keeping it
> > in separate on the submitted patch series.
> > 
> > What makes more sense?  
> 
> Really, not putting it in DT. Like other things, it's fixed for the 
> chip.

I agree, but, as I said before, without the datasheet, we can only
hardcode a small subset of the LDO settings.

Due to that, I prefer keeping it at DT - either grouped together at "reg" or 
as two separated properties (reg and vsel-reg).

> > > > +description: |
> > > > +  The HiSilicon SPMI 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.
> > > > +
> > > > +properties:
> > > > +  $nodename:
> > > > +    pattern: "spmi@[0-9a-f]"
> > > > +
> > > > +  compatible:
> > > > +    const: hisilicon,spmi-controller    
> > > 
> > > Needs an SoC specific compatible.  
> > 
> > What about:
> > 	hisilicon,kirin970-spmi-controller   
> 
> Is 'kirin970' really the SoC name? The older ones are all 'hi[0-9]+'.

This SoC is named Kirin 970. Yet, you can see places where 3670 is
used, like:

	https://en.wikichip.org/wiki/hisilicon/kirin/970

There, it says that Hi3670 is the part number.

Thanks,
Mauro

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties
  2020-08-18 22:18         ` Mauro Carvalho Chehab
@ 2020-08-19 20:48           ` Rob Herring
  0 siblings, 0 replies; 57+ messages in thread
From: Rob Herring @ 2020-08-19 20:48 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Greg Kroah-Hartman, Linuxarm, mauro.chehab, Lee Jones,
	Stephen Boyd, devicetree, linux-kernel, linux-arm-msm

On Tue, Aug 18, 2020 at 4:18 PM Mauro Carvalho Chehab
<mchehab+huawei@kernel.org> wrote:
>
> Em Tue, 18 Aug 2020 11:07:55 -0600
> Rob Herring <robh@kernel.org> escreveu:
>
> > > > > +  spmi-channel:
> > > > > +    description: number of the SPMI channel where the PMIC is connected
> > > >
> > > > This looks like a common (to SPMI), but it's not something defined in
> > > > spmi.txt
> > >
> > > This one is not part of the SPMI core. It is stored inside a private
> > > structure inside at the HiSilicon spmi controller driver. It is stored
> > > there as ctrl_dev->channel, and it is used to calculate the register offset
> > > for readl():
> > >
> > >     offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
> > >     offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
> > >     do {
> > >             status = readl(base + offset);
> > >     ...
> > >
> > > The SPMI bus is somewhat similar to I2C: it is a 2-wire serial bus
> > > with up to 16 devices connected to it.
> > >
> > > Now, most modern I2C chipsets provide multiple independent I2C
> > > channels, on different pins. Also, on some chipsets, certain
> > > GPIO pins can be used either as GPIO or as I2C.
> > >
> > > I strongly suspect that this is the case here: according with
> > > the Hikey 970 schematics:
> > >
> > >     https://www.96boards.org/documentation/consumer/hikey/hikey970/hardware-docs/files/hikey970-schematics.pdf
> > >
> > > The pins used by SPMI clock/data can also be used as GPIO.
> > >
> > > While I don't have access to the datasheets for Kirin 970 (or any other
> > > chipsets on this board), for me, it sounds that different GPIO pins
> > > are allowed to use SPMI. The "spmi-channel" property specifies
> > > what pins will be used for SPMI, among the ones that are
> > > compatible with MIPI SPMI specs.
> >
> > Based on this, I think it should be called 'hisilicon,spmi-channel' as
> > it is vendor specific.
>
> I'm fine with "hisilicon,spmi-channel".

Humm, QCom has a 'qcom,channel' property for SPMI. Seems like maybe it
should be a common thing.

Rob

^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2020-08-19 20:48 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-17  7:10 [PATCH v3 00/44] SPMI patches needed by Hikey 970 Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 01/44] staging: spmi: add Hikey 970 SPMI controller driver Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 02/44] staging: spmi: hisi-spmi-controller: coding style fixup Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 03/44] staging: spmi: hisi-spmi-controller: fix it to probe successfully Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 04/44] staging: spmi: hisi-spmi-controller: fix a typo Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 05/44] staging: spmi: hisi-spmi-controller: adjust whitespaces at defines Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 06/44] staging: spmi: hisi-spmi-controller: use le32 macros where needed Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 07/44] staging: spmi: hisi-spmi-controller: add debug when values are read/write Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 08/44] staging: spmi: hisi-spmi-controller: fix the dev_foo() logic Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 09/44] staging: spmi: hisi-spmi-controller: add it to the building system Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 10/44] staging: spmi: hisi-spmi-controller: do some code cleanups Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 11/44] staging: mfd: add a PMIC driver for HiSilicon 6421 SPMI version Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 12/44] staging: mfd: hi6421-spmi-pmic: get rid of unused code Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 13/44] staging: mfd: hi6421-spmi-pmic: deal with non-static functions Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 14/44] staging: mfd: hi6421-spmi-pmic: get rid of the static vars Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 15/44] staging: mfd: hi6421-spmi-pmic: cleanup hi6421-spmi-pmic.h header Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 16/44] staging: mfd: hi6421-spmi-pmic: change the binding logic Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 17/44] staging: mfd: hi6421-spmi-pmic: get rid of unused OF properties Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 18/44] staging: mfd: hi6421-spmi-pmic: cleanup " Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 19/44] staging: mfd: hi6421-spmi-pmic: change namespace on its functions Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 20/44] staging: mfd: hi6421-spmi-pmic: fix some coding style issues Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 21/44] staging: mfd: hi6421-spmi-pmic: add it to the building system Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 22/44] staging: mfd: hi6421-spmi-pmic: cleanup the code Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 23/44] staging: regulator: add a regulator driver for HiSilicon 6421v600 SPMI PMIC Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 24/44] staging: regulator: hi6421v600-regulator: get rid of unused code Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 25/44] staging: regulator: hi6421v600-regulator: port it to upstream Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 26/44] staging: regulator: hi6421v600-regulator: coding style fixups Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 27/44] staging: regulator: hi6421v600-regulator: change the binding logic Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 28/44] staging: regulator: hi6421v600-regulator: cleanup struct hisi_regulator Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 29/44] staging: regulator: hi6421v600-regulator: cleanup debug messages Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 30/44] staging: regulator: hi6421v600-regulator: use shorter names for OF properties Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 31/44] staging: regulator: hi6421v600-regulator: better handle modes Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 32/44] staging: regulator: hi6421v600-regulator: change namespace Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 33/44] staging: regulator: hi6421v600-regulator: convert to use get/set voltage_sel Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 34/44] staging: regulator: hi6421v600-regulator: don't use usleep_range for off_on_delay Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 35/44] staging: regulator: hi6421v600-regulator: add a driver-specific debug macro Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 36/44] staging: regulator: hi6421v600-regulator: initialize ramp_delay Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 37/44] staging: regulator: hi6421v600-regulator: cleanup DT settings Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 38/44] staging: regulator: hi6421v600-regulator: fix some coding style issues Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 39/44] staging: regulator: hi6421v600-regulator: add it to the building system Mauro Carvalho Chehab
2020-08-17  7:10 ` [PATCH v3 40/44] staging: regulator: hi6421v600-regulator: code cleanup Mauro Carvalho Chehab
2020-08-17  7:11 ` [PATCH v3 41/44] staging: hikey9xx: add a TODO list Mauro Carvalho Chehab
2020-08-17  7:11 ` [PATCH v3 42/44] MAINTAINERS: add an entry for HiSilicon 6421v600 drivers Mauro Carvalho Chehab
2020-08-18 14:18   ` Greg Kroah-Hartman
2020-08-17  7:11 ` [PATCH v3 43/44] dt: document HiSilicon SPMI controller and mfd/regulator properties Mauro Carvalho Chehab
2020-08-17 20:12   ` Rob Herring
2020-08-18  9:13     ` Mauro Carvalho Chehab
2020-08-18 10:37       ` Mauro Carvalho Chehab
2020-08-18 17:07       ` Rob Herring
2020-08-18 22:18         ` Mauro Carvalho Chehab
2020-08-19 20:48           ` Rob Herring
2020-08-18 11:10   ` [PATCH v3.1 " Mauro Carvalho Chehab
2020-08-18 14:19     ` Greg Kroah-Hartman
2020-08-17  7:11 ` [PATCH v3 44/44] dt: hisilicon: add support for the PMIC found on Hikey 970 Mauro Carvalho Chehab
2020-08-17  7:32 ` [PATCH v3 00/44] SPMI patches needed by " Greg Kroah-Hartman
2020-08-18 14:17 ` Greg Kroah-Hartman
2020-08-18 14:28   ` Mauro Carvalho Chehab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).