lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 18 May 2015 08:10:04 +0000
From:	"Zha, Qipeng" <qipeng.zha@...el.com>
To:	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
CC:	"broonie@...nel.org" <broonie@...nel.org>,
	"Yang, Fei" <fei.yang@...el.com>,
	"Zhong, Huiquan" <huiquan.zhong@...el.com>,
	"Chen, Jason CJ" <jason.cj.chen@...el.com>,
	"Zheng, Qi" <qi.zheng@...el.com>
Subject: RE: [PATCH] regmap: add virtual PMIC IPC bus support

Hi Broonie

Can you help comment on this patch ?
We do really want to leverage current regmap framework to acess intel pmic devices.
So please evaluate this driver, thanks.




Best wishes
Qipeng

-----Original Message-----
From: Zha, Qipeng 
Sent: Tuesday, April 21, 2015 7:39 AM
To: linux-kernel@...r.kernel.org
Cc: broonie@...nel.org; Yang, Fei; Zhong, Huiquan; Chen, Jason CJ; Zheng, Qi; Zha, Qipeng
Subject: [PATCH] regmap: add virtual PMIC IPC bus support

From: "qipeng.zha" <qipeng.zha@...el.com>

There defined Whiskey Cove PMIC controller on one Intel platform, and all registers on this PMIC are accessed by IPC commands.
This patch is to utilize regmap framework to access PMIC registers for PMIC core and device drivers.

Signed-off-by: qipeng.zha <qipeng.zha@...el.com>
---
 drivers/base/regmap/Kconfig           |   5 +-
 drivers/base/regmap/Makefile          |   1 +
 drivers/base/regmap/regmap-pmic-ipc.c | 128 ++++++++++++++++++++++++++++++++++
 include/linux/mfd/intel_soc_pmic.h    |   2 +
 include/linux/regmap.h                |   5 ++
 5 files changed, 140 insertions(+), 1 deletion(-)  create mode 100644 drivers/base/regmap/regmap-pmic-ipc.c

diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig index db9d00c3..c6ab5a9 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -3,7 +3,7 @@
 # subsystems should select the appropriate symbols.
 
 config REGMAP
-	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
+	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 
+|| REGMAP_MMIO || REGMAP_IRQ || REGMAP_PMIC_IPC)
 	select LZO_COMPRESS
 	select LZO_DECOMPRESS
 	select IRQ_DOMAIN if REGMAP_IRQ
@@ -29,3 +29,6 @@ config REGMAP_MMIO
 
 config REGMAP_IRQ
 	bool
+
+config REGMAP_PMIC_IPC
+	bool
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile index 609e4c8..fb859c0 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
 obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
 obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
 obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o
+obj-$(CONFIG_REGMAP_IRQ) += regmap-pmic-ipc.o
diff --git a/drivers/base/regmap/regmap-pmic-ipc.c b/drivers/base/regmap/regmap-pmic-ipc.c
new file mode 100644
index 0000000..2895d22
--- /dev/null
+++ b/drivers/base/regmap/regmap-pmic-ipc.c
@@ -0,0 +1,128 @@
+/*
+ * Register map access API - Intel PMIC IPC support
+ *
+ * (C) Copyright 2015 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ */
+
+#include <linux/regmap.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/mfd/intel_soc_pmic.h>
+#include <asm/intel_pmc_ipc.h>
+#include "internal.h"
+
+#define REG_ADDR_MASK		0xFF00
+#define REG_ADDR_SHIFT		8
+#define REG_OFFSET_MASK		0xFF
+
+static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
+				      unsigned int *val)
+{
+	int ret;
+	int i2c_addr;
+	u8 ipc_in[2];
+	u8 ipc_out[4];
+	struct intel_soc_pmic *pmic = context;
+
+	if (reg & REG_ADDR_MASK)
+		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
+	else {
+		i2c_addr = pmic->default_i2c_addr;
+		if (!i2c_addr) {
+			dev_err(pmic->dev, "Wrong register addr to read\n");
+			return -EINVAL;
+		}
+	}
+	reg &= REG_OFFSET_MASK;
+
+	ipc_in[0] = reg;
+	ipc_in[1] = i2c_addr;
+	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
+			PMC_IPC_PMIC_ACCESS_READ,
+			ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
+	if (ret) {
+		dev_err(pmic->dev, "Err: ipc read pmic\n");
+		return ret;
+	}
+	*val = ipc_out[0];
+	return 0;
+}
+
+static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
+				       unsigned int val)
+{
+	int ret;
+	int i2c_addr;
+	u8 ipc_in[3];
+	struct intel_soc_pmic *pmic = context;
+
+	if (reg & REG_ADDR_MASK)
+		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
+	else {
+		i2c_addr = pmic->default_i2c_addr;
+		if (!i2c_addr) {
+			dev_err(pmic->dev, "Wrong register addr to write\n");
+			return -EINVAL;
+		}
+	}
+	reg &= REG_OFFSET_MASK;
+
+	ipc_in[0] = reg;
+	ipc_in[1] = i2c_addr;
+	ipc_in[2] = val;
+	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
+			PMC_IPC_PMIC_ACCESS_WRITE,
+			ipc_in, sizeof(ipc_in), NULL, 0);
+	if (ret) {
+		dev_err(pmic->dev, "Err: ipc write pmic\n");
+		return ret;
+	}
+	return 0;
+}
+
+static struct regmap_bus ipc_regmap_bus = {
+	.reg_write = regmap_ipc_byte_reg_write,
+	.reg_read = regmap_ipc_byte_reg_read,
+};
+
+/**
+ * regmap_init_pmic_ipc(): Initialise register map
+ *
+ * @pmic: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+struct regmap *regmap_init_pmic_ipc(struct intel_soc_pmic *pmic,
+			       const struct regmap_config *config) {
+	return regmap_init(pmic->dev, &ipc_regmap_bus, pmic, config); } 
+EXPORT_SYMBOL_GPL(regmap_init_pmic_ipc);
+
+/**
+ * devm_regmap_init_pmic_ipc(): Initialise managed register map
+ *
+ * @pmic: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+struct regmap *devm_regmap_init_pmic_ipc(struct intel_soc_pmic *pmic,
+				    const struct regmap_config *config) {
+	return devm_regmap_init(pmic->dev, &ipc_regmap_bus, pmic, config); } 
+EXPORT_SYMBOL_GPL(devm_regmap_init_pmic_ipc);
+
+MODULE_AUTHOR("qipeng.zha@...el.com");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h
index abcbfcf..74ee3d2 100644
--- a/include/linux/mfd/intel_soc_pmic.h
+++ b/include/linux/mfd/intel_soc_pmic.h
@@ -25,6 +25,8 @@ struct intel_soc_pmic {
 	int irq;
 	struct regmap *regmap;
 	struct regmap_irq_chip_data *irq_chip_data;
+	struct device *dev;
+	int default_i2c_addr;
 };
 
 #endif	/* __INTEL_SOC_PMIC_H__ */
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 116655d..11bbf1d 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -28,6 +28,7 @@ struct regmap;
 struct regmap_range_cfg;
 struct regmap_field;
 struct snd_ac97;
+struct intel_soc_pmic;
 
 /* An enum of all the supported cache types */  enum regcache_type { @@ -343,6 +344,8 @@ struct regmap *regmap_init_mmio_clk(struct device *dev, const char *clk_id,
 				    const struct regmap_config *config);  struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
 				const struct regmap_config *config);
+struct regmap *regmap_init_pmic_ipc(struct intel_soc_pmic *pmic,
+			       const struct regmap_config *config);
 
 struct regmap *devm_regmap_init(struct device *dev,
 				const struct regmap_bus *bus,
@@ -361,6 +364,8 @@ struct regmap *devm_regmap_init_mmio_clk(struct device *dev, const char *clk_id,
 					 const struct regmap_config *config);  struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
 				     const struct regmap_config *config);
+struct regmap *devm_regmap_init_pmic_ipc(struct intel_soc_pmic *pmic,
+				    const struct regmap_config *config);
 
 bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
 
--
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ