All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/2] regulator: add irq domain and device tree support for MAX8997
@ 2012-03-24  9:49 ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: k.lewandowsk, devicetree-discuss, rob.herring, grant.likely,
	kgene.kim, broonie, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches

Changes since v3:
- Fixed all comments from Grant Likely.
  - In patch 1/2, since linear mapping is used, the handle_nested_irq() is
    called only for allocated irq's.
  - In patch 2/2, the incorrect assignment of platform data pointer to
    dev->platform_data is reworked and fixed.

Changes since v2:
- Atleast one voltage level has to be specfied for Buck 1/2/5 even if GPIO
  DVS option is not used (suggested by MyungJoo Ham).
- Reworked the irq_domain support based the v5 of irq_domain generalization
  patches.

MAX8997 is a multi-function device which includes support for regulators, rtc,
battery charger and other sub-blocks. This patchset adds device tree support
for the pmic (regulators) sub-block.

The first patch adds irq domain support for the interrupts supported by max8997
mainly for removing the need to pass a irq_base from the platform code. The
irq_base could not anyway be passed in case of device tree based instantiation.
The reverse mapping method used is linear since the sub-drivers of max8997 has
access to the max8997 irq_domain from which the linux irq number can be
obtained.

The second patch adds device tree support for max8997. This patch modifies both
mfd and regulator portions of the max8997 code.

This patchset is based on the following tree.
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git [for-next]

with all patches merged from
http://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git [for-next]
http://git.secretlab.ca/git/linux-2.6.git [irqdomain/next]

and depends on the following patchset.
[PATCH v4 0/4] ARM: Exynos4: Add irq domain and device tree support for wakeup interrupts.

This patchset has been tested on Origen board.

Thomas Abraham (2):
  mfd: add irq domain support for max8997 interrupts
  regulator: add device tree support for max8997

 .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
 arch/arm/mach-exynos/mach-nuri.c                   |    4 -
 arch/arm/mach-exynos/mach-origen.c                 |    1 -
 drivers/mfd/max8997-irq.c                          |   61 +++++----
 drivers/mfd/max8997.c                              |   74 ++++++++++-
 drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
 include/linux/mfd/max8997-private.h                |    5 +-
 include/linux/mfd/max8997.h                        |    2 +-
 8 files changed, 386 insertions(+), 37 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt


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

* [PATCH v4 0/2] regulator: add irq domain and device tree support for MAX8997
@ 2012-03-24  9:49 ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, patches-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	myungjoo.ham-Sze3O3UU22JBDgjK7y7TUQ,
	k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Changes since v3:
- Fixed all comments from Grant Likely.
  - In patch 1/2, since linear mapping is used, the handle_nested_irq() is
    called only for allocated irq's.
  - In patch 2/2, the incorrect assignment of platform data pointer to
    dev->platform_data is reworked and fixed.

Changes since v2:
- Atleast one voltage level has to be specfied for Buck 1/2/5 even if GPIO
  DVS option is not used (suggested by MyungJoo Ham).
- Reworked the irq_domain support based the v5 of irq_domain generalization
  patches.

MAX8997 is a multi-function device which includes support for regulators, rtc,
battery charger and other sub-blocks. This patchset adds device tree support
for the pmic (regulators) sub-block.

The first patch adds irq domain support for the interrupts supported by max8997
mainly for removing the need to pass a irq_base from the platform code. The
irq_base could not anyway be passed in case of device tree based instantiation.
The reverse mapping method used is linear since the sub-drivers of max8997 has
access to the max8997 irq_domain from which the linux irq number can be
obtained.

The second patch adds device tree support for max8997. This patch modifies both
mfd and regulator portions of the max8997 code.

This patchset is based on the following tree.
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git [for-next]

with all patches merged from
http://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git [for-next]
http://git.secretlab.ca/git/linux-2.6.git [irqdomain/next]

and depends on the following patchset.
[PATCH v4 0/4] ARM: Exynos4: Add irq domain and device tree support for wakeup interrupts.

This patchset has been tested on Origen board.

Thomas Abraham (2):
  mfd: add irq domain support for max8997 interrupts
  regulator: add device tree support for max8997

 .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
 arch/arm/mach-exynos/mach-nuri.c                   |    4 -
 arch/arm/mach-exynos/mach-origen.c                 |    1 -
 drivers/mfd/max8997-irq.c                          |   61 +++++----
 drivers/mfd/max8997.c                              |   74 ++++++++++-
 drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
 include/linux/mfd/max8997-private.h                |    5 +-
 include/linux/mfd/max8997.h                        |    2 +-
 8 files changed, 386 insertions(+), 37 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt

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

* [PATCH v4 0/2] regulator: add irq domain and device tree support for MAX8997
@ 2012-03-24  9:49 ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

Changes since v3:
- Fixed all comments from Grant Likely.
  - In patch 1/2, since linear mapping is used, the handle_nested_irq() is
    called only for allocated irq's.
  - In patch 2/2, the incorrect assignment of platform data pointer to
    dev->platform_data is reworked and fixed.

Changes since v2:
- Atleast one voltage level has to be specfied for Buck 1/2/5 even if GPIO
  DVS option is not used (suggested by MyungJoo Ham).
- Reworked the irq_domain support based the v5 of irq_domain generalization
  patches.

MAX8997 is a multi-function device which includes support for regulators, rtc,
battery charger and other sub-blocks. This patchset adds device tree support
for the pmic (regulators) sub-block.

The first patch adds irq domain support for the interrupts supported by max8997
mainly for removing the need to pass a irq_base from the platform code. The
irq_base could not anyway be passed in case of device tree based instantiation.
The reverse mapping method used is linear since the sub-drivers of max8997 has
access to the max8997 irq_domain from which the linux irq number can be
obtained.

The second patch adds device tree support for max8997. This patch modifies both
mfd and regulator portions of the max8997 code.

This patchset is based on the following tree.
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git [for-next]

with all patches merged from
http://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git [for-next]
http://git.secretlab.ca/git/linux-2.6.git [irqdomain/next]

and depends on the following patchset.
[PATCH v4 0/4] ARM: Exynos4: Add irq domain and device tree support for wakeup interrupts.

This patchset has been tested on Origen board.

Thomas Abraham (2):
  mfd: add irq domain support for max8997 interrupts
  regulator: add device tree support for max8997

 .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
 arch/arm/mach-exynos/mach-nuri.c                   |    4 -
 arch/arm/mach-exynos/mach-origen.c                 |    1 -
 drivers/mfd/max8997-irq.c                          |   61 +++++----
 drivers/mfd/max8997.c                              |   74 ++++++++++-
 drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
 include/linux/mfd/max8997-private.h                |    5 +-
 include/linux/mfd/max8997.h                        |    2 +-
 8 files changed, 386 insertions(+), 37 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
  2012-03-24  9:49 ` Thomas Abraham
  (?)
@ 2012-03-24  9:49   ` Thomas Abraham
  -1 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: k.lewandowsk, devicetree-discuss, rob.herring, grant.likely,
	kgene.kim, broonie, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches

Add irq domain support for max8997 interrupts. The reverse mapping method
used is linear mapping since the sub-drivers of max8997 such as regulator
and charger drivers can use the max8997 irq_domain to get the linux irq
number for max8997 interrupts. All uses of irq_base in platform data and
max8997 driver private data are removed.

Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/mach-exynos/mach-nuri.c    |    4 --
 arch/arm/mach-exynos/mach-origen.c  |    1 -
 drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
 drivers/mfd/max8997.c               |    1 -
 include/linux/mfd/max8997-private.h |    4 ++-
 include/linux/mfd/max8997.h         |    1 -
 6 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 7ac81ce..b21d85d 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
 static void __init nuri_power_init(void)
 {
 	int gpio;
-	int irq_base = IRQ_GPIO_END + 1;
 	int ta_en = 0;
 
-	nuri_max8997_pdata.irq_base = irq_base;
-	irq_base += MAX8997_IRQ_NR;
-
 	gpio = EXYNOS4_GPX0(7);
 	gpio_request(gpio, "AP_PMIC_IRQ");
 	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 827cb99..d3b2e9d 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
 	.buck1_gpiodvs	= false,
 	.buck2_gpiodvs	= false,
 	.buck5_gpiodvs	= false,
-	.irq_base	= IRQ_GPIO_END + 1,
 
 	.ignore_gpiodvs_side_effect = true,
 	.buck125_default_idx = 0x0,
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
index 09274cf..00390a1 100644
--- a/drivers/mfd/max8997-irq.c
+++ b/drivers/mfd/max8997-irq.c
@@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
 static const inline struct max8997_irq_data *
 irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
 {
-	return &max8997_irqs[irq - max8997->irq_base];
+	struct irq_data *data = irq_get_irq_data(irq);
+	return &max8997_irqs[data->hwirq];
 }
 
 static void max8997_irq_mask(struct irq_data *data)
@@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 	u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
 	u8 irq_src;
 	int ret;
-	int i;
+	int i, cur_irq;
 
 	ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
 	if (ret < 0) {
@@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 
 	/* Report */
 	for (i = 0; i < MAX8997_IRQ_NR; i++) {
-		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
-			handle_nested_irq(max8997->irq_base + i);
+		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
+			cur_irq = irq_find_mapping(max8997->irq_domain, i);
+			if (cur_irq)
+				handle_nested_irq(cur_irq);
+		}
 	}
 
 	return IRQ_HANDLED;
@@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 
 int max8997_irq_resume(struct max8997_dev *max8997)
 {
-	if (max8997->irq && max8997->irq_base)
-		max8997_irq_thread(max8997->irq_base, max8997);
+	if (max8997->irq && max8997->irq_domain)
+		max8997_irq_thread(0, max8997);
+	return 0;
+}
+
+static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
+					irq_hw_number_t hw)
+{
+	struct max8997_dev *max8997 = d->host_data;
+
+	irq_set_chip_data(irq, max8997);
+	irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	irq_set_noprobe(irq);
+#endif
 	return 0;
 }
 
+static struct irq_domain_ops max8997_irq_domain_ops = {
+	.map = max8997_irq_domain_map,
+};
+
 int max8997_irq_init(struct max8997_dev *max8997)
 {
+	struct irq_domain *domain;
 	int i;
-	int cur_irq;
 	int ret;
 	u8 val;
 
 	if (!max8997->irq) {
 		dev_warn(max8997->dev, "No interrupt specified.\n");
-		max8997->irq_base = 0;
-		return 0;
-	}
-
-	if (!max8997->irq_base) {
-		dev_err(max8997->dev, "No interrupt base specified.\n");
 		return 0;
 	}
 
@@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
 					true : false;
 	}
 
-	/* Register with genirq */
-	for (i = 0; i < MAX8997_IRQ_NR; i++) {
-		cur_irq = i + max8997->irq_base;
-		irq_set_chip_data(cur_irq, max8997);
-		irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
-				handle_edge_irq);
-		irq_set_nested_thread(cur_irq, 1);
-#ifdef CONFIG_ARM
-		set_irq_flags(cur_irq, IRQF_VALID);
-#else
-		irq_set_noprobe(cur_irq);
-#endif
+	domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
+					&max8997_irq_domain_ops, &max8997);
+	if (!domain) {
+		dev_err(max8997->dev, "could not create irq domain\n");
+		return -ENODEV;
 	}
 
 	ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index cb83a7a..20ecad3 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 	if (!pdata)
 		goto err;
 
-	max8997->irq_base = pdata->irq_base;
 	max8997->ono = pdata->ono;
 
 	mutex_init(&max8997->iolock);
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 3f4deb6..830152c 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -23,6 +23,8 @@
 #define __LINUX_MFD_MAX8997_PRIV_H
 
 #include <linux/i2c.h>
+#include <linux/export.h>
+#include <linux/irqdomain.h>
 
 #define MAX8997_REG_INVALID	(0xff)
 
@@ -325,7 +327,7 @@ struct max8997_dev {
 
 	int irq;
 	int ono;
-	int irq_base;
+	struct irq_domain *irq_domain;
 	struct mutex irqlock;
 	int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
 	int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index fff5905..818486c 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -155,7 +155,6 @@ struct max8997_led_platform_data {
 
 struct max8997_platform_data {
 	/* IRQ */
-	int irq_base;
 	int ono;
 	int wakeup;
 
-- 
1.6.6.rc2


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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-03-24  9:49   ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: kgene.kim, patches, devicetree-discuss, broonie, rob.herring,
	grant.likely, linux-samsung-soc, kyungmin.park, myungjoo.ham,
	k.lewandowsk, linux-arm-kernel

Add irq domain support for max8997 interrupts. The reverse mapping method
used is linear mapping since the sub-drivers of max8997 such as regulator
and charger drivers can use the max8997 irq_domain to get the linux irq
number for max8997 interrupts. All uses of irq_base in platform data and
max8997 driver private data are removed.

Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/mach-exynos/mach-nuri.c    |    4 --
 arch/arm/mach-exynos/mach-origen.c  |    1 -
 drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
 drivers/mfd/max8997.c               |    1 -
 include/linux/mfd/max8997-private.h |    4 ++-
 include/linux/mfd/max8997.h         |    1 -
 6 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 7ac81ce..b21d85d 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
 static void __init nuri_power_init(void)
 {
 	int gpio;
-	int irq_base = IRQ_GPIO_END + 1;
 	int ta_en = 0;
 
-	nuri_max8997_pdata.irq_base = irq_base;
-	irq_base += MAX8997_IRQ_NR;
-
 	gpio = EXYNOS4_GPX0(7);
 	gpio_request(gpio, "AP_PMIC_IRQ");
 	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 827cb99..d3b2e9d 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
 	.buck1_gpiodvs	= false,
 	.buck2_gpiodvs	= false,
 	.buck5_gpiodvs	= false,
-	.irq_base	= IRQ_GPIO_END + 1,
 
 	.ignore_gpiodvs_side_effect = true,
 	.buck125_default_idx = 0x0,
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
index 09274cf..00390a1 100644
--- a/drivers/mfd/max8997-irq.c
+++ b/drivers/mfd/max8997-irq.c
@@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
 static const inline struct max8997_irq_data *
 irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
 {
-	return &max8997_irqs[irq - max8997->irq_base];
+	struct irq_data *data = irq_get_irq_data(irq);
+	return &max8997_irqs[data->hwirq];
 }
 
 static void max8997_irq_mask(struct irq_data *data)
@@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 	u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
 	u8 irq_src;
 	int ret;
-	int i;
+	int i, cur_irq;
 
 	ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
 	if (ret < 0) {
@@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 
 	/* Report */
 	for (i = 0; i < MAX8997_IRQ_NR; i++) {
-		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
-			handle_nested_irq(max8997->irq_base + i);
+		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
+			cur_irq = irq_find_mapping(max8997->irq_domain, i);
+			if (cur_irq)
+				handle_nested_irq(cur_irq);
+		}
 	}
 
 	return IRQ_HANDLED;
@@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 
 int max8997_irq_resume(struct max8997_dev *max8997)
 {
-	if (max8997->irq && max8997->irq_base)
-		max8997_irq_thread(max8997->irq_base, max8997);
+	if (max8997->irq && max8997->irq_domain)
+		max8997_irq_thread(0, max8997);
+	return 0;
+}
+
+static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
+					irq_hw_number_t hw)
+{
+	struct max8997_dev *max8997 = d->host_data;
+
+	irq_set_chip_data(irq, max8997);
+	irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	irq_set_noprobe(irq);
+#endif
 	return 0;
 }
 
+static struct irq_domain_ops max8997_irq_domain_ops = {
+	.map = max8997_irq_domain_map,
+};
+
 int max8997_irq_init(struct max8997_dev *max8997)
 {
+	struct irq_domain *domain;
 	int i;
-	int cur_irq;
 	int ret;
 	u8 val;
 
 	if (!max8997->irq) {
 		dev_warn(max8997->dev, "No interrupt specified.\n");
-		max8997->irq_base = 0;
-		return 0;
-	}
-
-	if (!max8997->irq_base) {
-		dev_err(max8997->dev, "No interrupt base specified.\n");
 		return 0;
 	}
 
@@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
 					true : false;
 	}
 
-	/* Register with genirq */
-	for (i = 0; i < MAX8997_IRQ_NR; i++) {
-		cur_irq = i + max8997->irq_base;
-		irq_set_chip_data(cur_irq, max8997);
-		irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
-				handle_edge_irq);
-		irq_set_nested_thread(cur_irq, 1);
-#ifdef CONFIG_ARM
-		set_irq_flags(cur_irq, IRQF_VALID);
-#else
-		irq_set_noprobe(cur_irq);
-#endif
+	domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
+					&max8997_irq_domain_ops, &max8997);
+	if (!domain) {
+		dev_err(max8997->dev, "could not create irq domain\n");
+		return -ENODEV;
 	}
 
 	ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index cb83a7a..20ecad3 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 	if (!pdata)
 		goto err;
 
-	max8997->irq_base = pdata->irq_base;
 	max8997->ono = pdata->ono;
 
 	mutex_init(&max8997->iolock);
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 3f4deb6..830152c 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -23,6 +23,8 @@
 #define __LINUX_MFD_MAX8997_PRIV_H
 
 #include <linux/i2c.h>
+#include <linux/export.h>
+#include <linux/irqdomain.h>
 
 #define MAX8997_REG_INVALID	(0xff)
 
@@ -325,7 +327,7 @@ struct max8997_dev {
 
 	int irq;
 	int ono;
-	int irq_base;
+	struct irq_domain *irq_domain;
 	struct mutex irqlock;
 	int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
 	int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index fff5905..818486c 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -155,7 +155,6 @@ struct max8997_led_platform_data {
 
 struct max8997_platform_data {
 	/* IRQ */
-	int irq_base;
 	int ono;
 	int wakeup;
 
-- 
1.6.6.rc2

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-03-24  9:49   ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add irq domain support for max8997 interrupts. The reverse mapping method
used is linear mapping since the sub-drivers of max8997 such as regulator
and charger drivers can use the max8997 irq_domain to get the linux irq
number for max8997 interrupts. All uses of irq_base in platform data and
max8997 driver private data are removed.

Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/mach-exynos/mach-nuri.c    |    4 --
 arch/arm/mach-exynos/mach-origen.c  |    1 -
 drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
 drivers/mfd/max8997.c               |    1 -
 include/linux/mfd/max8997-private.h |    4 ++-
 include/linux/mfd/max8997.h         |    1 -
 6 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 7ac81ce..b21d85d 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
 static void __init nuri_power_init(void)
 {
 	int gpio;
-	int irq_base = IRQ_GPIO_END + 1;
 	int ta_en = 0;
 
-	nuri_max8997_pdata.irq_base = irq_base;
-	irq_base += MAX8997_IRQ_NR;
-
 	gpio = EXYNOS4_GPX0(7);
 	gpio_request(gpio, "AP_PMIC_IRQ");
 	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 827cb99..d3b2e9d 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
 	.buck1_gpiodvs	= false,
 	.buck2_gpiodvs	= false,
 	.buck5_gpiodvs	= false,
-	.irq_base	= IRQ_GPIO_END + 1,
 
 	.ignore_gpiodvs_side_effect = true,
 	.buck125_default_idx = 0x0,
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
index 09274cf..00390a1 100644
--- a/drivers/mfd/max8997-irq.c
+++ b/drivers/mfd/max8997-irq.c
@@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
 static const inline struct max8997_irq_data *
 irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
 {
-	return &max8997_irqs[irq - max8997->irq_base];
+	struct irq_data *data = irq_get_irq_data(irq);
+	return &max8997_irqs[data->hwirq];
 }
 
 static void max8997_irq_mask(struct irq_data *data)
@@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 	u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
 	u8 irq_src;
 	int ret;
-	int i;
+	int i, cur_irq;
 
 	ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
 	if (ret < 0) {
@@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 
 	/* Report */
 	for (i = 0; i < MAX8997_IRQ_NR; i++) {
-		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
-			handle_nested_irq(max8997->irq_base + i);
+		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
+			cur_irq = irq_find_mapping(max8997->irq_domain, i);
+			if (cur_irq)
+				handle_nested_irq(cur_irq);
+		}
 	}
 
 	return IRQ_HANDLED;
@@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
 
 int max8997_irq_resume(struct max8997_dev *max8997)
 {
-	if (max8997->irq && max8997->irq_base)
-		max8997_irq_thread(max8997->irq_base, max8997);
+	if (max8997->irq && max8997->irq_domain)
+		max8997_irq_thread(0, max8997);
+	return 0;
+}
+
+static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
+					irq_hw_number_t hw)
+{
+	struct max8997_dev *max8997 = d->host_data;
+
+	irq_set_chip_data(irq, max8997);
+	irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	irq_set_noprobe(irq);
+#endif
 	return 0;
 }
 
+static struct irq_domain_ops max8997_irq_domain_ops = {
+	.map = max8997_irq_domain_map,
+};
+
 int max8997_irq_init(struct max8997_dev *max8997)
 {
+	struct irq_domain *domain;
 	int i;
-	int cur_irq;
 	int ret;
 	u8 val;
 
 	if (!max8997->irq) {
 		dev_warn(max8997->dev, "No interrupt specified.\n");
-		max8997->irq_base = 0;
-		return 0;
-	}
-
-	if (!max8997->irq_base) {
-		dev_err(max8997->dev, "No interrupt base specified.\n");
 		return 0;
 	}
 
@@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
 					true : false;
 	}
 
-	/* Register with genirq */
-	for (i = 0; i < MAX8997_IRQ_NR; i++) {
-		cur_irq = i + max8997->irq_base;
-		irq_set_chip_data(cur_irq, max8997);
-		irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
-				handle_edge_irq);
-		irq_set_nested_thread(cur_irq, 1);
-#ifdef CONFIG_ARM
-		set_irq_flags(cur_irq, IRQF_VALID);
-#else
-		irq_set_noprobe(cur_irq);
-#endif
+	domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
+					&max8997_irq_domain_ops, &max8997);
+	if (!domain) {
+		dev_err(max8997->dev, "could not create irq domain\n");
+		return -ENODEV;
 	}
 
 	ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index cb83a7a..20ecad3 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 	if (!pdata)
 		goto err;
 
-	max8997->irq_base = pdata->irq_base;
 	max8997->ono = pdata->ono;
 
 	mutex_init(&max8997->iolock);
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 3f4deb6..830152c 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -23,6 +23,8 @@
 #define __LINUX_MFD_MAX8997_PRIV_H
 
 #include <linux/i2c.h>
+#include <linux/export.h>
+#include <linux/irqdomain.h>
 
 #define MAX8997_REG_INVALID	(0xff)
 
@@ -325,7 +327,7 @@ struct max8997_dev {
 
 	int irq;
 	int ono;
-	int irq_base;
+	struct irq_domain *irq_domain;
 	struct mutex irqlock;
 	int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
 	int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index fff5905..818486c 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -155,7 +155,6 @@ struct max8997_led_platform_data {
 
 struct max8997_platform_data {
 	/* IRQ */
-	int irq_base;
 	int ono;
 	int wakeup;
 
-- 
1.6.6.rc2

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-03-24  9:49 ` Thomas Abraham
@ 2012-03-24  9:49   ` Thomas Abraham
  -1 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: k.lewandowsk, devicetree-discuss, rob.herring, grant.likely,
	kgene.kim, broonie, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

Add device tree based discovery support for max8997.

Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
 drivers/mfd/max8997.c                              |   73 ++++++++++-
 drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
 include/linux/mfd/max8997-private.h                |    1 +
 include/linux/mfd/max8997.h                        |    1 +
 5 files changed, 347 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt

diff --git a/Documentation/devicetree/bindings/regulator/max8997-pmic.txt b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
new file mode 100644
index 0000000..90a730b
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
@@ -0,0 +1,133 @@
+* Maxim MAX8997 Voltage and Current Regulator
+
+The Maxim MAX8997 is a multi-function device which includes volatage and
+current regulators, rtc, charger controller and other sub-blocks. It is
+interfaced to the host controller using a i2c interface. Each sub-block is
+addressed by the host system using different i2c slave address. This document
+describes the bindings for 'pmic' sub-block of max8997.
+
+Required properties:
+- compatible: Should be "maxim,max8997-pmic".
+- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
+
+- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck1 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck2 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck5 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+[1] If none of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
+    property is specified, the 'max8997,pmic-buck[1/2/5]-dvs-voltage'
+    property should specify atleast one voltage level (which would be a
+    safe operating voltage).
+
+    If either of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
+    property is specified, then all the eigth voltage values for the
+    'max8997,pmic-buck[1/2/5]-dvs-voltage' should be specified.
+
+Optional properties:
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the interrupts from max8997 are delivered to.
+- interrupts: Interrupt specifiers for two interrupt sources.
+  - First interrupt specifier is for 'irq1' interrupt.
+  - Second interrupt specifier is for 'alert' interrupt.
+- max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs.
+- max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
+- max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs.
+
+Additional properties required if either of the optional properties are used:
+- max8997,pmic-ignore-gpiodvs-side-effect: When GPIO-DVS mode is used for
+  multiple bucks, changing the voltage value of one of the bucks may affect
+  that of another buck, which is the side effect of the change (set_voltage).
+  Use this property to ignore such side effects and change the voltage.
+
+- max8997,pmic-buck125-default-dvs-idx: Default voltage setting selected from
+  the possible 8 options selectable by the dvs gpios. The value of this
+  property should be between 0 and 7. If not specified or if out of range, the
+  default value of this property is set to 0.
+
+- max8997,pmic-buck125-dvs-gpios: GPIO specifiers for three host gpio's used
+  for dvs. The format of the gpio specifier depends in the gpio controller.
+
+
+Regulators: The regulators of max8997 that have to be instantiated should be
+included in a sub-node named 'regulators'. Regulator nodes included in this
+sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
+represents the LDO or BUCK number as per the datasheet of max8997.
+
+    For LDO's:
+		LDOn {
+			standard regulator bindings here
+		};
+
+    For BUCK's:
+		BUCKn {
+			standard regulator bindings here
+		};
+
+The bindings inside the regulator nodes use the standard regulator bindings
+which are documented elsewhere.
+
+Example:
+
+	max8997_pmic@66 {
+		compatible = "maxim,max8997-pmic";
+		interrupt-parent = <&wakeup_eint>;
+		reg = <0x66>;
+		interrupts = <4 0>, <3 0>;
+
+		max8997,pmic-buck1-uses-gpio-dvs;
+		max8997,pmic-buck2-uses-gpio-dvs;
+		max8997,pmic-buck5-uses-gpio-dvs;
+
+		max8997,pmic-ignore-gpiodvs-side-effect;
+		max8997,pmic-buck125-default-dvs-idx = <0>;
+
+		max8997,pmic-buck125-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
+						 <&gpx0 1 1 0 0>, /* SET2 */
+						 <&gpx0 2 1 0 0>; /* SET3 */
+
+		max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
+						 <1250000>, <1200000>,
+						 <1150000>, <1100000>,
+						 <1000000>, <950000>;
+
+		max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
+				    		 <1100000>, <1100000>,
+						 <1000000>, <1000000>,
+						 <1000000>, <1000000>;
+
+		max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>;
+
+		regulators {
+			ldo1_reg: LDO1 {
+				regulator-name = "VDD_ABB_3.3V";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VDD_ALIVE_1.1V";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "VDD_ARM_1.2V";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index 20ecad3..1c38e98 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -21,8 +21,10 @@
  * This driver is based on max8998.c
  */
 
+#include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/of_irq.h>
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 #include <linux/module.h>
@@ -47,6 +49,13 @@ static struct mfd_cell max8997_devs[] = {
 	{ .name = "max8997-led", .id = 2 },
 };
 
+#ifdef CONFIG_OF
+static struct of_device_id __devinitdata max8997_pmic_dt_match[] = {
+	{ .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
+	{},
+};
+#endif
+
 int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
 {
 	struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
@@ -123,6 +132,58 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
 }
 EXPORT_SYMBOL_GPL(max8997_update_reg);
 
+#ifdef CONFIG_OF
+/*
+ * Only the common platform data elements for max8997 are parsed here from the
+ * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
+ * to parse their own platform data elements from device tree.
+ *
+ * The max8997 platform data structure is instantiated here and the drivers for
+ * the sub-modules need not instantiate another instance while parsing their
+ * platform data.
+ */
+static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
+					struct device *dev)
+{
+	struct max8997_platform_data *pd;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		dev_err(dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pd->ono = irq_of_parse_and_map(dev->of_node, 1);
+
+	/*
+	 * ToDo: the 'wakeup' member in the platform data is more of a linux
+	 * specfic information. Hence, there is no binding for that yet and
+	 * not parsed here.
+	 */
+
+	return pd;
+}
+#else
+static int max8997_i2c_parse_dt_pdata(struct device *dev,
+					struct max8997_platform_data **pdata)
+{
+	return 0;
+}
+#endif
+
+static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
+						const struct i2c_device_id *id)
+{
+#ifdef CONFIG_OF
+	if (i2c->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
+		return (int)match->data;
+	}
+#endif
+	return (int)id->driver_data;
+}
+
 static int max8997_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
@@ -137,12 +198,21 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, max8997);
 	max8997->dev = &i2c->dev;
 	max8997->i2c = i2c;
-	max8997->type = id->driver_data;
+	max8997->type = max8997_i2c_get_driver_data(i2c, id);
 	max8997->irq = i2c->irq;
 
+	if (max8997->dev->of_node) {
+		pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
+		if (IS_ERR(pdata)) {
+			ret = PTR_ERR(pdata);
+			goto err;
+		}
+	}
+
 	if (!pdata)
 		goto err;
 
+	max8997->pdata = pdata;
 	max8997->ono = pdata->ono;
 
 	mutex_init(&max8997->iolock);
@@ -434,6 +504,7 @@ static struct i2c_driver max8997_i2c_driver = {
 		   .name = "max8997",
 		   .owner = THIS_MODULE,
 		   .pm = &max8997_pm,
+		   .of_match_table = of_match_ptr(max8997_pmic_dt_match),
 	},
 	.probe = max8997_i2c_probe,
 	.remove = max8997_i2c_remove,
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index 9657929..dce8aaf 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -32,6 +33,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/mfd/max8997.h>
 #include <linux/mfd/max8997-private.h>
+#include <linux/regulator/of_regulator.h>
 
 struct max8997_data {
 	struct device *dev;
@@ -953,21 +955,155 @@ static struct regulator_desc regulators[] = {
 	},
 };
 
+#ifdef CONFIG_OF
+static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
+			struct max8997_platform_data *pdata,
+			struct device_node *pmic_np)
+{
+	int i, gpio;
+
+	for (i = 0; i < 3; i++) {
+		gpio = of_get_named_gpio(pmic_np,
+					"max8997,pmic-buck125-dvs-gpios", i);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
+			return -EINVAL;
+		}
+		pdata->buck125_gpios[i] = gpio;
+	}
+	return 0;
+}
+
+static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+					struct max8997_platform_data *pdata)
+{
+	struct device_node *pmic_np, *regulators_np, *reg_np;
+	struct max8997_regulator_data *rdata;
+	unsigned int i, dvs_voltage_nr = 1, ret;
+
+	pmic_np = iodev->dev->of_node;
+	if (!pmic_np) {
+		dev_err(iodev->dev, "could not find pmic sub-node\n");
+		return -ENODEV;
+	}
+
+	regulators_np = of_find_node_by_name(pmic_np, "regulators");
+	if (!regulators_np) {
+		dev_err(iodev->dev, "could not find regulators sub-node\n");
+		return -EINVAL;
+	}
+
+	/* count the number of regulators to be supported in pmic */
+	pdata->num_regulators = 0;
+	for_each_child_of_node(regulators_np, reg_np)
+		pdata->num_regulators++;
+
+	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
+				pdata->num_regulators, GFP_KERNEL);
+	if (!rdata) {
+		dev_err(iodev->dev, "could not allocate memory for "
+						"regulator data\n");
+		return -ENOMEM;
+	}
+
+	pdata->regulators = rdata;
+	for_each_child_of_node(regulators_np, reg_np) {
+		for (i = 0; i < ARRAY_SIZE(regulators); i++)
+			if (!of_node_cmp(reg_np->name, regulators[i].name))
+				break;
+		rdata->id = i;
+		rdata->initdata = of_get_regulator_init_data(
+						iodev->dev, reg_np);
+		rdata->reg_node = reg_np;
+		rdata++;
+	}
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck1-uses-gpio-dvs", NULL))
+		pdata->buck1_gpiodvs = true;
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck2-uses-gpio-dvs", NULL))
+		pdata->buck2_gpiodvs = true;
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck5-uses-gpio-dvs", NULL))
+		pdata->buck5_gpiodvs = true;
+
+	if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
+						pdata->buck5_gpiodvs) {
+		ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
+		if (ret)
+			return -EINVAL;
+
+		if (of_property_read_u32(pmic_np,
+				"max8997,pmic-buck125-default-dvs-idx",
+				&pdata->buck125_default_idx)) {
+			pdata->buck125_default_idx = 0;
+		} else {
+			if (pdata->buck125_default_idx >= 8) {
+				pdata->buck125_default_idx = 0;
+				dev_info(iodev->dev, "invalid value for "
+				"default dvs index, using 0 instead\n");
+			}
+		}
+
+		if (of_get_property(pmic_np,
+			"max8997,pmic-ignore-gpiodvs-side-effect", NULL))
+			pdata->ignore_gpiodvs_side_effect = true;
+
+		dvs_voltage_nr = 8;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck1-dvs-voltage",
+				pdata->buck1_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck1 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck2-dvs-voltage",
+				pdata->buck2_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck2 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck5-dvs-voltage",
+				pdata->buck5_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck5 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#else
+static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+					struct max8997_platform_data *pdata)
+{
+	return 0;
+}
+#endif /* CONFIG_OF */
+
 static __devinit int max8997_pmic_probe(struct platform_device *pdev)
 {
 	struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
-	struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+	struct max8997_platform_data *pdata = iodev->pdata;
 	struct regulator_dev **rdev;
 	struct max8997_data *max8997;
 	struct i2c_client *i2c;
 	int i, ret, size;
 	u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0;
 
-	if (!pdata) {
+	if (IS_ERR_OR_NULL(pdata)) {
 		dev_err(pdev->dev.parent, "No platform init data supplied.\n");
 		return -ENODEV;
 	}
 
+	if (iodev->dev->of_node) {
+		ret = max8997_pmic_dt_parse_pdata(iodev, pdata);
+		if (ret)
+			return ret;
+	}
+
 	max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL);
 	if (!max8997)
 		return -ENOMEM;
@@ -1141,7 +1277,8 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
 			regulators[id].n_voltages = 16;
 
 		rdev[i] = regulator_register(&regulators[id], max8997->dev,
-				pdata->regulators[i].initdata, max8997, NULL);
+				pdata->regulators[i].initdata, max8997,
+				pdata->regulators[i].reg_node);
 		if (IS_ERR(rdev[i])) {
 			ret = PTR_ERR(rdev[i]);
 			dev_err(max8997->dev, "regulator init failed for %d\n",
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 830152c..6ae21bf 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -316,6 +316,7 @@ enum max8997_irq {
 #define MAX8997_NUM_GPIO	12
 struct max8997_dev {
 	struct device *dev;
+	struct max8997_platform_data *pdata;
 	struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
 	struct i2c_client *rtc; /* slave addr 0x0c */
 	struct i2c_client *haptic; /* slave addr 0x90 */
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index 818486c..ba92375 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -75,6 +75,7 @@ enum max8998_regulators {
 struct max8997_regulator_data {
 	int id;
 	struct regulator_init_data *initdata;
+	struct device_node *reg_node;
 };
 
 enum max8997_muic_usb_type {
-- 
1.6.6.rc2


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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-03-24  9:49   ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-03-24  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add device tree based discovery support for max8997.

Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
 drivers/mfd/max8997.c                              |   73 ++++++++++-
 drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
 include/linux/mfd/max8997-private.h                |    1 +
 include/linux/mfd/max8997.h                        |    1 +
 5 files changed, 347 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt

diff --git a/Documentation/devicetree/bindings/regulator/max8997-pmic.txt b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
new file mode 100644
index 0000000..90a730b
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
@@ -0,0 +1,133 @@
+* Maxim MAX8997 Voltage and Current Regulator
+
+The Maxim MAX8997 is a multi-function device which includes volatage and
+current regulators, rtc, charger controller and other sub-blocks. It is
+interfaced to the host controller using a i2c interface. Each sub-block is
+addressed by the host system using different i2c slave address. This document
+describes the bindings for 'pmic' sub-block of max8997.
+
+Required properties:
+- compatible: Should be "maxim,max8997-pmic".
+- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
+
+- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck1 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck2 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck5 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+[1] If none of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
+    property is specified, the 'max8997,pmic-buck[1/2/5]-dvs-voltage'
+    property should specify atleast one voltage level (which would be a
+    safe operating voltage).
+
+    If either of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
+    property is specified, then all the eigth voltage values for the
+    'max8997,pmic-buck[1/2/5]-dvs-voltage' should be specified.
+
+Optional properties:
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the interrupts from max8997 are delivered to.
+- interrupts: Interrupt specifiers for two interrupt sources.
+  - First interrupt specifier is for 'irq1' interrupt.
+  - Second interrupt specifier is for 'alert' interrupt.
+- max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs.
+- max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
+- max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs.
+
+Additional properties required if either of the optional properties are used:
+- max8997,pmic-ignore-gpiodvs-side-effect: When GPIO-DVS mode is used for
+  multiple bucks, changing the voltage value of one of the bucks may affect
+  that of another buck, which is the side effect of the change (set_voltage).
+  Use this property to ignore such side effects and change the voltage.
+
+- max8997,pmic-buck125-default-dvs-idx: Default voltage setting selected from
+  the possible 8 options selectable by the dvs gpios. The value of this
+  property should be between 0 and 7. If not specified or if out of range, the
+  default value of this property is set to 0.
+
+- max8997,pmic-buck125-dvs-gpios: GPIO specifiers for three host gpio's used
+  for dvs. The format of the gpio specifier depends in the gpio controller.
+
+
+Regulators: The regulators of max8997 that have to be instantiated should be
+included in a sub-node named 'regulators'. Regulator nodes included in this
+sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
+represents the LDO or BUCK number as per the datasheet of max8997.
+
+    For LDO's:
+		LDOn {
+			standard regulator bindings here
+		};
+
+    For BUCK's:
+		BUCKn {
+			standard regulator bindings here
+		};
+
+The bindings inside the regulator nodes use the standard regulator bindings
+which are documented elsewhere.
+
+Example:
+
+	max8997_pmic at 66 {
+		compatible = "maxim,max8997-pmic";
+		interrupt-parent = <&wakeup_eint>;
+		reg = <0x66>;
+		interrupts = <4 0>, <3 0>;
+
+		max8997,pmic-buck1-uses-gpio-dvs;
+		max8997,pmic-buck2-uses-gpio-dvs;
+		max8997,pmic-buck5-uses-gpio-dvs;
+
+		max8997,pmic-ignore-gpiodvs-side-effect;
+		max8997,pmic-buck125-default-dvs-idx = <0>;
+
+		max8997,pmic-buck125-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
+						 <&gpx0 1 1 0 0>, /* SET2 */
+						 <&gpx0 2 1 0 0>; /* SET3 */
+
+		max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
+						 <1250000>, <1200000>,
+						 <1150000>, <1100000>,
+						 <1000000>, <950000>;
+
+		max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
+				    		 <1100000>, <1100000>,
+						 <1000000>, <1000000>,
+						 <1000000>, <1000000>;
+
+		max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>;
+
+		regulators {
+			ldo1_reg: LDO1 {
+				regulator-name = "VDD_ABB_3.3V";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VDD_ALIVE_1.1V";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "VDD_ARM_1.2V";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index 20ecad3..1c38e98 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -21,8 +21,10 @@
  * This driver is based on max8998.c
  */
 
+#include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/of_irq.h>
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 #include <linux/module.h>
@@ -47,6 +49,13 @@ static struct mfd_cell max8997_devs[] = {
 	{ .name = "max8997-led", .id = 2 },
 };
 
+#ifdef CONFIG_OF
+static struct of_device_id __devinitdata max8997_pmic_dt_match[] = {
+	{ .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
+	{},
+};
+#endif
+
 int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
 {
 	struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
@@ -123,6 +132,58 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
 }
 EXPORT_SYMBOL_GPL(max8997_update_reg);
 
+#ifdef CONFIG_OF
+/*
+ * Only the common platform data elements for max8997 are parsed here from the
+ * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
+ * to parse their own platform data elements from device tree.
+ *
+ * The max8997 platform data structure is instantiated here and the drivers for
+ * the sub-modules need not instantiate another instance while parsing their
+ * platform data.
+ */
+static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
+					struct device *dev)
+{
+	struct max8997_platform_data *pd;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		dev_err(dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pd->ono = irq_of_parse_and_map(dev->of_node, 1);
+
+	/*
+	 * ToDo: the 'wakeup' member in the platform data is more of a linux
+	 * specfic information. Hence, there is no binding for that yet and
+	 * not parsed here.
+	 */
+
+	return pd;
+}
+#else
+static int max8997_i2c_parse_dt_pdata(struct device *dev,
+					struct max8997_platform_data **pdata)
+{
+	return 0;
+}
+#endif
+
+static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
+						const struct i2c_device_id *id)
+{
+#ifdef CONFIG_OF
+	if (i2c->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
+		return (int)match->data;
+	}
+#endif
+	return (int)id->driver_data;
+}
+
 static int max8997_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
@@ -137,12 +198,21 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, max8997);
 	max8997->dev = &i2c->dev;
 	max8997->i2c = i2c;
-	max8997->type = id->driver_data;
+	max8997->type = max8997_i2c_get_driver_data(i2c, id);
 	max8997->irq = i2c->irq;
 
+	if (max8997->dev->of_node) {
+		pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
+		if (IS_ERR(pdata)) {
+			ret = PTR_ERR(pdata);
+			goto err;
+		}
+	}
+
 	if (!pdata)
 		goto err;
 
+	max8997->pdata = pdata;
 	max8997->ono = pdata->ono;
 
 	mutex_init(&max8997->iolock);
@@ -434,6 +504,7 @@ static struct i2c_driver max8997_i2c_driver = {
 		   .name = "max8997",
 		   .owner = THIS_MODULE,
 		   .pm = &max8997_pm,
+		   .of_match_table = of_match_ptr(max8997_pmic_dt_match),
 	},
 	.probe = max8997_i2c_probe,
 	.remove = max8997_i2c_remove,
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index 9657929..dce8aaf 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -32,6 +33,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/mfd/max8997.h>
 #include <linux/mfd/max8997-private.h>
+#include <linux/regulator/of_regulator.h>
 
 struct max8997_data {
 	struct device *dev;
@@ -953,21 +955,155 @@ static struct regulator_desc regulators[] = {
 	},
 };
 
+#ifdef CONFIG_OF
+static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
+			struct max8997_platform_data *pdata,
+			struct device_node *pmic_np)
+{
+	int i, gpio;
+
+	for (i = 0; i < 3; i++) {
+		gpio = of_get_named_gpio(pmic_np,
+					"max8997,pmic-buck125-dvs-gpios", i);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
+			return -EINVAL;
+		}
+		pdata->buck125_gpios[i] = gpio;
+	}
+	return 0;
+}
+
+static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+					struct max8997_platform_data *pdata)
+{
+	struct device_node *pmic_np, *regulators_np, *reg_np;
+	struct max8997_regulator_data *rdata;
+	unsigned int i, dvs_voltage_nr = 1, ret;
+
+	pmic_np = iodev->dev->of_node;
+	if (!pmic_np) {
+		dev_err(iodev->dev, "could not find pmic sub-node\n");
+		return -ENODEV;
+	}
+
+	regulators_np = of_find_node_by_name(pmic_np, "regulators");
+	if (!regulators_np) {
+		dev_err(iodev->dev, "could not find regulators sub-node\n");
+		return -EINVAL;
+	}
+
+	/* count the number of regulators to be supported in pmic */
+	pdata->num_regulators = 0;
+	for_each_child_of_node(regulators_np, reg_np)
+		pdata->num_regulators++;
+
+	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
+				pdata->num_regulators, GFP_KERNEL);
+	if (!rdata) {
+		dev_err(iodev->dev, "could not allocate memory for "
+						"regulator data\n");
+		return -ENOMEM;
+	}
+
+	pdata->regulators = rdata;
+	for_each_child_of_node(regulators_np, reg_np) {
+		for (i = 0; i < ARRAY_SIZE(regulators); i++)
+			if (!of_node_cmp(reg_np->name, regulators[i].name))
+				break;
+		rdata->id = i;
+		rdata->initdata = of_get_regulator_init_data(
+						iodev->dev, reg_np);
+		rdata->reg_node = reg_np;
+		rdata++;
+	}
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck1-uses-gpio-dvs", NULL))
+		pdata->buck1_gpiodvs = true;
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck2-uses-gpio-dvs", NULL))
+		pdata->buck2_gpiodvs = true;
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck5-uses-gpio-dvs", NULL))
+		pdata->buck5_gpiodvs = true;
+
+	if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
+						pdata->buck5_gpiodvs) {
+		ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
+		if (ret)
+			return -EINVAL;
+
+		if (of_property_read_u32(pmic_np,
+				"max8997,pmic-buck125-default-dvs-idx",
+				&pdata->buck125_default_idx)) {
+			pdata->buck125_default_idx = 0;
+		} else {
+			if (pdata->buck125_default_idx >= 8) {
+				pdata->buck125_default_idx = 0;
+				dev_info(iodev->dev, "invalid value for "
+				"default dvs index, using 0 instead\n");
+			}
+		}
+
+		if (of_get_property(pmic_np,
+			"max8997,pmic-ignore-gpiodvs-side-effect", NULL))
+			pdata->ignore_gpiodvs_side_effect = true;
+
+		dvs_voltage_nr = 8;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck1-dvs-voltage",
+				pdata->buck1_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck1 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck2-dvs-voltage",
+				pdata->buck2_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck2 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck5-dvs-voltage",
+				pdata->buck5_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck5 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#else
+static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+					struct max8997_platform_data *pdata)
+{
+	return 0;
+}
+#endif /* CONFIG_OF */
+
 static __devinit int max8997_pmic_probe(struct platform_device *pdev)
 {
 	struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
-	struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+	struct max8997_platform_data *pdata = iodev->pdata;
 	struct regulator_dev **rdev;
 	struct max8997_data *max8997;
 	struct i2c_client *i2c;
 	int i, ret, size;
 	u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0;
 
-	if (!pdata) {
+	if (IS_ERR_OR_NULL(pdata)) {
 		dev_err(pdev->dev.parent, "No platform init data supplied.\n");
 		return -ENODEV;
 	}
 
+	if (iodev->dev->of_node) {
+		ret = max8997_pmic_dt_parse_pdata(iodev, pdata);
+		if (ret)
+			return ret;
+	}
+
 	max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL);
 	if (!max8997)
 		return -ENOMEM;
@@ -1141,7 +1277,8 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
 			regulators[id].n_voltages = 16;
 
 		rdev[i] = regulator_register(&regulators[id], max8997->dev,
-				pdata->regulators[i].initdata, max8997, NULL);
+				pdata->regulators[i].initdata, max8997,
+				pdata->regulators[i].reg_node);
 		if (IS_ERR(rdev[i])) {
 			ret = PTR_ERR(rdev[i]);
 			dev_err(max8997->dev, "regulator init failed for %d\n",
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 830152c..6ae21bf 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -316,6 +316,7 @@ enum max8997_irq {
 #define MAX8997_NUM_GPIO	12
 struct max8997_dev {
 	struct device *dev;
+	struct max8997_platform_data *pdata;
 	struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
 	struct i2c_client *rtc; /* slave addr 0x0c */
 	struct i2c_client *haptic; /* slave addr 0x90 */
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index 818486c..ba92375 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -75,6 +75,7 @@ enum max8998_regulators {
 struct max8997_regulator_data {
 	int id;
 	struct regulator_init_data *initdata;
+	struct device_node *reg_node;
 };
 
 enum max8997_muic_usb_type {
-- 
1.6.6.rc2

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

* Re: [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-03-26 12:20     ` MyungJoo Ham
  -1 siblings, 0 replies; 36+ messages in thread
From: MyungJoo Ham @ 2012-03-26 12:20 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: linux-kernel, k.lewandowsk, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, broonie, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches

On Sat, Mar 24, 2012 at 6:49 PM, Thomas Abraham
<thomas.abraham@linaro.org> wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.
>
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com>

> ---
>  arch/arm/mach-exynos/mach-nuri.c    |    4 --
>  arch/arm/mach-exynos/mach-origen.c  |    1 -
>  drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
>  drivers/mfd/max8997.c               |    1 -
>  include/linux/mfd/max8997-private.h |    4 ++-
>  include/linux/mfd/max8997.h         |    1 -
>  6 files changed, 39 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
> index 7ac81ce..b21d85d 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
>  static void __init nuri_power_init(void)
>  {
>        int gpio;
> -       int irq_base = IRQ_GPIO_END + 1;
>        int ta_en = 0;
>
> -       nuri_max8997_pdata.irq_base = irq_base;
> -       irq_base += MAX8997_IRQ_NR;
> -
>        gpio = EXYNOS4_GPX0(7);
>        gpio_request(gpio, "AP_PMIC_IRQ");
>        s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
> index 827cb99..d3b2e9d 100644
> --- a/arch/arm/mach-exynos/mach-origen.c
> +++ b/arch/arm/mach-exynos/mach-origen.c
> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
>        .buck1_gpiodvs  = false,
>        .buck2_gpiodvs  = false,
>        .buck5_gpiodvs  = false,
> -       .irq_base       = IRQ_GPIO_END + 1,
>
>        .ignore_gpiodvs_side_effect = true,
>        .buck125_default_idx = 0x0,
> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
> index 09274cf..00390a1 100644
> --- a/drivers/mfd/max8997-irq.c
> +++ b/drivers/mfd/max8997-irq.c
> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
>  static const inline struct max8997_irq_data *
>  irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
>  {
> -       return &max8997_irqs[irq - max8997->irq_base];
> +       struct irq_data *data = irq_get_irq_data(irq);
> +       return &max8997_irqs[data->hwirq];
>  }
>
>  static void max8997_irq_mask(struct irq_data *data)
> @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>        u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
>        u8 irq_src;
>        int ret;
> -       int i;
> +       int i, cur_irq;
>
>        ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
>        if (ret < 0) {
> @@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>
>        /* Report */
>        for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -               if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
> -                       handle_nested_irq(max8997->irq_base + i);
> +               if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
> +                       cur_irq = irq_find_mapping(max8997->irq_domain, i);
> +                       if (cur_irq)
> +                               handle_nested_irq(cur_irq);
> +               }
>        }
>
>        return IRQ_HANDLED;
> @@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>
>  int max8997_irq_resume(struct max8997_dev *max8997)
>  {
> -       if (max8997->irq && max8997->irq_base)
> -               max8997_irq_thread(max8997->irq_base, max8997);
> +       if (max8997->irq && max8997->irq_domain)
> +               max8997_irq_thread(0, max8997);
> +       return 0;
> +}
> +
> +static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
> +                                       irq_hw_number_t hw)
> +{
> +       struct max8997_dev *max8997 = d->host_data;
> +
> +       irq_set_chip_data(irq, max8997);
> +       irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
> +       irq_set_nested_thread(irq, 1);
> +#ifdef CONFIG_ARM
> +       set_irq_flags(irq, IRQF_VALID);
> +#else
> +       irq_set_noprobe(irq);
> +#endif
>        return 0;
>  }
>
> +static struct irq_domain_ops max8997_irq_domain_ops = {
> +       .map = max8997_irq_domain_map,
> +};
> +
>  int max8997_irq_init(struct max8997_dev *max8997)
>  {
> +       struct irq_domain *domain;
>        int i;
> -       int cur_irq;
>        int ret;
>        u8 val;
>
>        if (!max8997->irq) {
>                dev_warn(max8997->dev, "No interrupt specified.\n");
> -               max8997->irq_base = 0;
> -               return 0;
> -       }
> -
> -       if (!max8997->irq_base) {
> -               dev_err(max8997->dev, "No interrupt base specified.\n");
>                return 0;
>        }
>
> @@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
>                                        true : false;
>        }
>
> -       /* Register with genirq */
> -       for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -               cur_irq = i + max8997->irq_base;
> -               irq_set_chip_data(cur_irq, max8997);
> -               irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
> -                               handle_edge_irq);
> -               irq_set_nested_thread(cur_irq, 1);
> -#ifdef CONFIG_ARM
> -               set_irq_flags(cur_irq, IRQF_VALID);
> -#else
> -               irq_set_noprobe(cur_irq);
> -#endif
> +       domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
> +                                       &max8997_irq_domain_ops, &max8997);
> +       if (!domain) {
> +               dev_err(max8997->dev, "could not create irq domain\n");
> +               return -ENODEV;
>        }
>
>        ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index cb83a7a..20ecad3 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
>        if (!pdata)
>                goto err;
>
> -       max8997->irq_base = pdata->irq_base;
>        max8997->ono = pdata->ono;
>
>        mutex_init(&max8997->iolock);
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 3f4deb6..830152c 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -23,6 +23,8 @@
>  #define __LINUX_MFD_MAX8997_PRIV_H
>
>  #include <linux/i2c.h>
> +#include <linux/export.h>
> +#include <linux/irqdomain.h>
>
>  #define MAX8997_REG_INVALID    (0xff)
>
> @@ -325,7 +327,7 @@ struct max8997_dev {
>
>        int irq;
>        int ono;
> -       int irq_base;
> +       struct irq_domain *irq_domain;
>        struct mutex irqlock;
>        int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
>        int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index fff5905..818486c 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -155,7 +155,6 @@ struct max8997_led_platform_data {
>
>  struct max8997_platform_data {
>        /* IRQ */
> -       int irq_base;
>        int ono;
>        int wakeup;
>
> --
> 1.6.6.rc2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-03-26 12:20     ` MyungJoo Ham
  0 siblings, 0 replies; 36+ messages in thread
From: MyungJoo Ham @ 2012-03-26 12:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 24, 2012 at 6:49 PM, Thomas Abraham
<thomas.abraham@linaro.org> wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.
>
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com>

> ---
> ?arch/arm/mach-exynos/mach-nuri.c ? ?| ? ?4 --
> ?arch/arm/mach-exynos/mach-origen.c ?| ? ?1 -
> ?drivers/mfd/max8997-irq.c ? ? ? ? ? | ? 61 ++++++++++++++++++++--------------
> ?drivers/mfd/max8997.c ? ? ? ? ? ? ? | ? ?1 -
> ?include/linux/mfd/max8997-private.h | ? ?4 ++-
> ?include/linux/mfd/max8997.h ? ? ? ? | ? ?1 -
> ?6 files changed, 39 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
> index 7ac81ce..b21d85d 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
> ?static void __init nuri_power_init(void)
> ?{
> ? ? ? ?int gpio;
> - ? ? ? int irq_base = IRQ_GPIO_END + 1;
> ? ? ? ?int ta_en = 0;
>
> - ? ? ? nuri_max8997_pdata.irq_base = irq_base;
> - ? ? ? irq_base += MAX8997_IRQ_NR;
> -
> ? ? ? ?gpio = EXYNOS4_GPX0(7);
> ? ? ? ?gpio_request(gpio, "AP_PMIC_IRQ");
> ? ? ? ?s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
> index 827cb99..d3b2e9d 100644
> --- a/arch/arm/mach-exynos/mach-origen.c
> +++ b/arch/arm/mach-exynos/mach-origen.c
> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
> ? ? ? ?.buck1_gpiodvs ?= false,
> ? ? ? ?.buck2_gpiodvs ?= false,
> ? ? ? ?.buck5_gpiodvs ?= false,
> - ? ? ? .irq_base ? ? ? = IRQ_GPIO_END + 1,
>
> ? ? ? ?.ignore_gpiodvs_side_effect = true,
> ? ? ? ?.buck125_default_idx = 0x0,
> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
> index 09274cf..00390a1 100644
> --- a/drivers/mfd/max8997-irq.c
> +++ b/drivers/mfd/max8997-irq.c
> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
> ?static const inline struct max8997_irq_data *
> ?irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
> ?{
> - ? ? ? return &max8997_irqs[irq - max8997->irq_base];
> + ? ? ? struct irq_data *data = irq_get_irq_data(irq);
> + ? ? ? return &max8997_irqs[data->hwirq];
> ?}
>
> ?static void max8997_irq_mask(struct irq_data *data)
> @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
> ? ? ? ?u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
> ? ? ? ?u8 irq_src;
> ? ? ? ?int ret;
> - ? ? ? int i;
> + ? ? ? int i, cur_irq;
>
> ? ? ? ?ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
> ? ? ? ?if (ret < 0) {
> @@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>
> ? ? ? ?/* Report */
> ? ? ? ?for (i = 0; i < MAX8997_IRQ_NR; i++) {
> - ? ? ? ? ? ? ? if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
> - ? ? ? ? ? ? ? ? ? ? ? handle_nested_irq(max8997->irq_base + i);
> + ? ? ? ? ? ? ? if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
> + ? ? ? ? ? ? ? ? ? ? ? cur_irq = irq_find_mapping(max8997->irq_domain, i);
> + ? ? ? ? ? ? ? ? ? ? ? if (cur_irq)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? handle_nested_irq(cur_irq);
> + ? ? ? ? ? ? ? }
> ? ? ? ?}
>
> ? ? ? ?return IRQ_HANDLED;
> @@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>
> ?int max8997_irq_resume(struct max8997_dev *max8997)
> ?{
> - ? ? ? if (max8997->irq && max8997->irq_base)
> - ? ? ? ? ? ? ? max8997_irq_thread(max8997->irq_base, max8997);
> + ? ? ? if (max8997->irq && max8997->irq_domain)
> + ? ? ? ? ? ? ? max8997_irq_thread(0, max8997);
> + ? ? ? return 0;
> +}
> +
> +static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? irq_hw_number_t hw)
> +{
> + ? ? ? struct max8997_dev *max8997 = d->host_data;
> +
> + ? ? ? irq_set_chip_data(irq, max8997);
> + ? ? ? irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
> + ? ? ? irq_set_nested_thread(irq, 1);
> +#ifdef CONFIG_ARM
> + ? ? ? set_irq_flags(irq, IRQF_VALID);
> +#else
> + ? ? ? irq_set_noprobe(irq);
> +#endif
> ? ? ? ?return 0;
> ?}
>
> +static struct irq_domain_ops max8997_irq_domain_ops = {
> + ? ? ? .map = max8997_irq_domain_map,
> +};
> +
> ?int max8997_irq_init(struct max8997_dev *max8997)
> ?{
> + ? ? ? struct irq_domain *domain;
> ? ? ? ?int i;
> - ? ? ? int cur_irq;
> ? ? ? ?int ret;
> ? ? ? ?u8 val;
>
> ? ? ? ?if (!max8997->irq) {
> ? ? ? ? ? ? ? ?dev_warn(max8997->dev, "No interrupt specified.\n");
> - ? ? ? ? ? ? ? max8997->irq_base = 0;
> - ? ? ? ? ? ? ? return 0;
> - ? ? ? }
> -
> - ? ? ? if (!max8997->irq_base) {
> - ? ? ? ? ? ? ? dev_err(max8997->dev, "No interrupt base specified.\n");
> ? ? ? ? ? ? ? ?return 0;
> ? ? ? ?}
>
> @@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?true : false;
> ? ? ? ?}
>
> - ? ? ? /* Register with genirq */
> - ? ? ? for (i = 0; i < MAX8997_IRQ_NR; i++) {
> - ? ? ? ? ? ? ? cur_irq = i + max8997->irq_base;
> - ? ? ? ? ? ? ? irq_set_chip_data(cur_irq, max8997);
> - ? ? ? ? ? ? ? irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? handle_edge_irq);
> - ? ? ? ? ? ? ? irq_set_nested_thread(cur_irq, 1);
> -#ifdef CONFIG_ARM
> - ? ? ? ? ? ? ? set_irq_flags(cur_irq, IRQF_VALID);
> -#else
> - ? ? ? ? ? ? ? irq_set_noprobe(cur_irq);
> -#endif
> + ? ? ? domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &max8997_irq_domain_ops, &max8997);
> + ? ? ? if (!domain) {
> + ? ? ? ? ? ? ? dev_err(max8997->dev, "could not create irq domain\n");
> + ? ? ? ? ? ? ? return -ENODEV;
> ? ? ? ?}
>
> ? ? ? ?ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index cb83a7a..20ecad3 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
> ? ? ? ?if (!pdata)
> ? ? ? ? ? ? ? ?goto err;
>
> - ? ? ? max8997->irq_base = pdata->irq_base;
> ? ? ? ?max8997->ono = pdata->ono;
>
> ? ? ? ?mutex_init(&max8997->iolock);
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 3f4deb6..830152c 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -23,6 +23,8 @@
> ?#define __LINUX_MFD_MAX8997_PRIV_H
>
> ?#include <linux/i2c.h>
> +#include <linux/export.h>
> +#include <linux/irqdomain.h>
>
> ?#define MAX8997_REG_INVALID ? ?(0xff)
>
> @@ -325,7 +327,7 @@ struct max8997_dev {
>
> ? ? ? ?int irq;
> ? ? ? ?int ono;
> - ? ? ? int irq_base;
> + ? ? ? struct irq_domain *irq_domain;
> ? ? ? ?struct mutex irqlock;
> ? ? ? ?int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
> ? ? ? ?int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index fff5905..818486c 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -155,7 +155,6 @@ struct max8997_led_platform_data {
>
> ?struct max8997_platform_data {
> ? ? ? ?/* IRQ */
> - ? ? ? int irq_base;
> ? ? ? ?int ono;
> ? ? ? ?int wakeup;
>
> --
> 1.6.6.rc2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html



-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-03-27  6:40     ` MyungJoo Ham
  -1 siblings, 0 replies; 36+ messages in thread
From: MyungJoo Ham @ 2012-03-27  6:40 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: linux-kernel, k.lewandowsk, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, broonie, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

On Sat, Mar 24, 2012 at 6:49 PM, Thomas Abraham
<thomas.abraham@linaro.org> wrote:
> Add device tree based discovery support for max8997.
>
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Cc: Rajendra Nayak <rnayak@ti.com>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>

Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com>

> ---
>  .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
>  drivers/mfd/max8997.c                              |   73 ++++++++++-
>  drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
>  include/linux/mfd/max8997-private.h                |    1 +
>  include/linux/mfd/max8997.h                        |    1 +
>  5 files changed, 347 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt
>
> diff --git a/Documentation/devicetree/bindings/regulator/max8997-pmic.txt b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> new file mode 100644
> index 0000000..90a730b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> @@ -0,0 +1,133 @@
> +* Maxim MAX8997 Voltage and Current Regulator
> +
> +The Maxim MAX8997 is a multi-function device which includes volatage and
> +current regulators, rtc, charger controller and other sub-blocks. It is
> +interfaced to the host controller using a i2c interface. Each sub-block is
> +addressed by the host system using different i2c slave address. This document
> +describes the bindings for 'pmic' sub-block of max8997.
> +
> +Required properties:
> +- compatible: Should be "maxim,max8997-pmic".
> +- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
> +
> +- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck1 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.
> +
> +- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck2 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.
> +
> +- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck5 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.
> +
> +[1] If none of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
> +    property is specified, the 'max8997,pmic-buck[1/2/5]-dvs-voltage'
> +    property should specify atleast one voltage level (which would be a
> +    safe operating voltage).
> +
> +    If either of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
> +    property is specified, then all the eigth voltage values for the
> +    'max8997,pmic-buck[1/2/5]-dvs-voltage' should be specified.
> +
> +Optional properties:
> +- interrupt-parent: Specifies the phandle of the interrupt controller to which
> +  the interrupts from max8997 are delivered to.
> +- interrupts: Interrupt specifiers for two interrupt sources.
> +  - First interrupt specifier is for 'irq1' interrupt.
> +  - Second interrupt specifier is for 'alert' interrupt.
> +- max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs.
> +- max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
> +- max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs.
> +
> +Additional properties required if either of the optional properties are used:
> +- max8997,pmic-ignore-gpiodvs-side-effect: When GPIO-DVS mode is used for
> +  multiple bucks, changing the voltage value of one of the bucks may affect
> +  that of another buck, which is the side effect of the change (set_voltage).
> +  Use this property to ignore such side effects and change the voltage.
> +
> +- max8997,pmic-buck125-default-dvs-idx: Default voltage setting selected from
> +  the possible 8 options selectable by the dvs gpios. The value of this
> +  property should be between 0 and 7. If not specified or if out of range, the
> +  default value of this property is set to 0.
> +
> +- max8997,pmic-buck125-dvs-gpios: GPIO specifiers for three host gpio's used
> +  for dvs. The format of the gpio specifier depends in the gpio controller.
> +
> +
> +Regulators: The regulators of max8997 that have to be instantiated should be
> +included in a sub-node named 'regulators'. Regulator nodes included in this
> +sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
> +represents the LDO or BUCK number as per the datasheet of max8997.
> +
> +    For LDO's:
> +               LDOn {
> +                       standard regulator bindings here
> +               };
> +
> +    For BUCK's:
> +               BUCKn {
> +                       standard regulator bindings here
> +               };
> +
> +The bindings inside the regulator nodes use the standard regulator bindings
> +which are documented elsewhere.
> +
> +Example:
> +
> +       max8997_pmic@66 {
> +               compatible = "maxim,max8997-pmic";
> +               interrupt-parent = <&wakeup_eint>;
> +               reg = <0x66>;
> +               interrupts = <4 0>, <3 0>;
> +
> +               max8997,pmic-buck1-uses-gpio-dvs;
> +               max8997,pmic-buck2-uses-gpio-dvs;
> +               max8997,pmic-buck5-uses-gpio-dvs;
> +
> +               max8997,pmic-ignore-gpiodvs-side-effect;
> +               max8997,pmic-buck125-default-dvs-idx = <0>;
> +
> +               max8997,pmic-buck125-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
> +                                                <&gpx0 1 1 0 0>, /* SET2 */
> +                                                <&gpx0 2 1 0 0>; /* SET3 */
> +
> +               max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
> +                                                <1250000>, <1200000>,
> +                                                <1150000>, <1100000>,
> +                                                <1000000>, <950000>;
> +
> +               max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
> +                                                <1100000>, <1100000>,
> +                                                <1000000>, <1000000>,
> +                                                <1000000>, <1000000>;
> +
> +               max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
> +                                                <1200000>, <1200000>,
> +                                                <1200000>, <1200000>,
> +                                                <1200000>, <1200000>;
> +
> +               regulators {
> +                       ldo1_reg: LDO1 {
> +                               regulator-name = "VDD_ABB_3.3V";
> +                               regulator-min-microvolt = <3300000>;
> +                               regulator-max-microvolt = <3300000>;
> +                       };
> +
> +                       ldo2_reg: LDO2 {
> +                               regulator-name = "VDD_ALIVE_1.1V";
> +                               regulator-min-microvolt = <1100000>;
> +                               regulator-max-microvolt = <1100000>;
> +                               regulator-always-on;
> +                       };
> +
> +                       buck1_reg: BUCK1 {
> +                               regulator-name = "VDD_ARM_1.2V";
> +                               regulator-min-microvolt = <950000>;
> +                               regulator-max-microvolt = <1350000>;
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                       };
> +               };
> +       };
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index 20ecad3..1c38e98 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -21,8 +21,10 @@
>  * This driver is based on max8998.c
>  */
>
> +#include <linux/err.h>
>  #include <linux/slab.h>
>  #include <linux/i2c.h>
> +#include <linux/of_irq.h>
>  #include <linux/interrupt.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/module.h>
> @@ -47,6 +49,13 @@ static struct mfd_cell max8997_devs[] = {
>        { .name = "max8997-led", .id = 2 },
>  };
>
> +#ifdef CONFIG_OF
> +static struct of_device_id __devinitdata max8997_pmic_dt_match[] = {
> +       { .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
> +       {},
> +};
> +#endif
> +
>  int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
>  {
>        struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
> @@ -123,6 +132,58 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
>  }
>  EXPORT_SYMBOL_GPL(max8997_update_reg);
>
> +#ifdef CONFIG_OF
> +/*
> + * Only the common platform data elements for max8997 are parsed here from the
> + * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
> + * to parse their own platform data elements from device tree.
> + *
> + * The max8997 platform data structure is instantiated here and the drivers for
> + * the sub-modules need not instantiate another instance while parsing their
> + * platform data.
> + */
> +static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
> +                                       struct device *dev)
> +{
> +       struct max8997_platform_data *pd;
> +
> +       pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> +       if (!pd) {
> +               dev_err(dev, "could not allocate memory for pdata\n");
> +               return ERR_PTR(-ENOMEM);
> +       }
> +
> +       pd->ono = irq_of_parse_and_map(dev->of_node, 1);
> +
> +       /*
> +        * ToDo: the 'wakeup' member in the platform data is more of a linux
> +        * specfic information. Hence, there is no binding for that yet and
> +        * not parsed here.
> +        */
> +
> +       return pd;
> +}
> +#else
> +static int max8997_i2c_parse_dt_pdata(struct device *dev,
> +                                       struct max8997_platform_data **pdata)
> +{
> +       return 0;
> +}
> +#endif
> +
> +static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
> +                                               const struct i2c_device_id *id)
> +{
> +#ifdef CONFIG_OF
> +       if (i2c->dev.of_node) {
> +               const struct of_device_id *match;
> +               match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
> +               return (int)match->data;
> +       }
> +#endif
> +       return (int)id->driver_data;
> +}
> +
>  static int max8997_i2c_probe(struct i2c_client *i2c,
>                            const struct i2c_device_id *id)
>  {
> @@ -137,12 +198,21 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
>        i2c_set_clientdata(i2c, max8997);
>        max8997->dev = &i2c->dev;
>        max8997->i2c = i2c;
> -       max8997->type = id->driver_data;
> +       max8997->type = max8997_i2c_get_driver_data(i2c, id);
>        max8997->irq = i2c->irq;
>
> +       if (max8997->dev->of_node) {
> +               pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
> +               if (IS_ERR(pdata)) {
> +                       ret = PTR_ERR(pdata);
> +                       goto err;
> +               }
> +       }
> +
>        if (!pdata)
>                goto err;
>
> +       max8997->pdata = pdata;
>        max8997->ono = pdata->ono;
>
>        mutex_init(&max8997->iolock);
> @@ -434,6 +504,7 @@ static struct i2c_driver max8997_i2c_driver = {
>                   .name = "max8997",
>                   .owner = THIS_MODULE,
>                   .pm = &max8997_pm,
> +                  .of_match_table = of_match_ptr(max8997_pmic_dt_match),
>        },
>        .probe = max8997_i2c_probe,
>        .remove = max8997_i2c_remove,
> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
> index 9657929..dce8aaf 100644
> --- a/drivers/regulator/max8997.c
> +++ b/drivers/regulator/max8997.c
> @@ -25,6 +25,7 @@
>  #include <linux/delay.h>
>  #include <linux/err.h>
>  #include <linux/gpio.h>
> +#include <linux/of_gpio.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
> @@ -32,6 +33,7 @@
>  #include <linux/regulator/machine.h>
>  #include <linux/mfd/max8997.h>
>  #include <linux/mfd/max8997-private.h>
> +#include <linux/regulator/of_regulator.h>
>
>  struct max8997_data {
>        struct device *dev;
> @@ -953,21 +955,155 @@ static struct regulator_desc regulators[] = {
>        },
>  };
>
> +#ifdef CONFIG_OF
> +static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
> +                       struct max8997_platform_data *pdata,
> +                       struct device_node *pmic_np)
> +{
> +       int i, gpio;
> +
> +       for (i = 0; i < 3; i++) {
> +               gpio = of_get_named_gpio(pmic_np,
> +                                       "max8997,pmic-buck125-dvs-gpios", i);
> +               if (!gpio_is_valid(gpio)) {
> +                       dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
> +                       return -EINVAL;
> +               }
> +               pdata->buck125_gpios[i] = gpio;
> +       }
> +       return 0;
> +}
> +
> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
> +                                       struct max8997_platform_data *pdata)
> +{
> +       struct device_node *pmic_np, *regulators_np, *reg_np;
> +       struct max8997_regulator_data *rdata;
> +       unsigned int i, dvs_voltage_nr = 1, ret;
> +
> +       pmic_np = iodev->dev->of_node;
> +       if (!pmic_np) {
> +               dev_err(iodev->dev, "could not find pmic sub-node\n");
> +               return -ENODEV;
> +       }
> +
> +       regulators_np = of_find_node_by_name(pmic_np, "regulators");
> +       if (!regulators_np) {
> +               dev_err(iodev->dev, "could not find regulators sub-node\n");
> +               return -EINVAL;
> +       }
> +
> +       /* count the number of regulators to be supported in pmic */
> +       pdata->num_regulators = 0;
> +       for_each_child_of_node(regulators_np, reg_np)
> +               pdata->num_regulators++;
> +
> +       rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
> +                               pdata->num_regulators, GFP_KERNEL);
> +       if (!rdata) {
> +               dev_err(iodev->dev, "could not allocate memory for "
> +                                               "regulator data\n");
> +               return -ENOMEM;
> +       }
> +
> +       pdata->regulators = rdata;
> +       for_each_child_of_node(regulators_np, reg_np) {
> +               for (i = 0; i < ARRAY_SIZE(regulators); i++)
> +                       if (!of_node_cmp(reg_np->name, regulators[i].name))
> +                               break;
> +               rdata->id = i;
> +               rdata->initdata = of_get_regulator_init_data(
> +                                               iodev->dev, reg_np);
> +               rdata->reg_node = reg_np;
> +               rdata++;
> +       }
> +
> +       if (of_get_property(pmic_np, "max8997,pmic-buck1-uses-gpio-dvs", NULL))
> +               pdata->buck1_gpiodvs = true;
> +
> +       if (of_get_property(pmic_np, "max8997,pmic-buck2-uses-gpio-dvs", NULL))
> +               pdata->buck2_gpiodvs = true;
> +
> +       if (of_get_property(pmic_np, "max8997,pmic-buck5-uses-gpio-dvs", NULL))
> +               pdata->buck5_gpiodvs = true;
> +
> +       if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
> +                                               pdata->buck5_gpiodvs) {
> +               ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
> +               if (ret)
> +                       return -EINVAL;
> +
> +               if (of_property_read_u32(pmic_np,
> +                               "max8997,pmic-buck125-default-dvs-idx",
> +                               &pdata->buck125_default_idx)) {
> +                       pdata->buck125_default_idx = 0;
> +               } else {
> +                       if (pdata->buck125_default_idx >= 8) {
> +                               pdata->buck125_default_idx = 0;
> +                               dev_info(iodev->dev, "invalid value for "
> +                               "default dvs index, using 0 instead\n");
> +                       }
> +               }
> +
> +               if (of_get_property(pmic_np,
> +                       "max8997,pmic-ignore-gpiodvs-side-effect", NULL))
> +                       pdata->ignore_gpiodvs_side_effect = true;
> +
> +               dvs_voltage_nr = 8;
> +       }
> +
> +       if (of_property_read_u32_array(pmic_np,
> +                               "max8997,pmic-buck1-dvs-voltage",
> +                               pdata->buck1_voltage, dvs_voltage_nr)) {
> +               dev_err(iodev->dev, "buck1 voltages not specified\n");
> +               return -EINVAL;
> +       }
> +
> +       if (of_property_read_u32_array(pmic_np,
> +                               "max8997,pmic-buck2-dvs-voltage",
> +                               pdata->buck2_voltage, dvs_voltage_nr)) {
> +               dev_err(iodev->dev, "buck2 voltages not specified\n");
> +               return -EINVAL;
> +       }
> +
> +       if (of_property_read_u32_array(pmic_np,
> +                               "max8997,pmic-buck5-dvs-voltage",
> +                               pdata->buck5_voltage, dvs_voltage_nr)) {
> +               dev_err(iodev->dev, "buck5 voltages not specified\n");
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +#else
> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
> +                                       struct max8997_platform_data *pdata)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_OF */
> +
>  static __devinit int max8997_pmic_probe(struct platform_device *pdev)
>  {
>        struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
> -       struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
> +       struct max8997_platform_data *pdata = iodev->pdata;
>        struct regulator_dev **rdev;
>        struct max8997_data *max8997;
>        struct i2c_client *i2c;
>        int i, ret, size;
>        u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0;
>
> -       if (!pdata) {
> +       if (IS_ERR_OR_NULL(pdata)) {
>                dev_err(pdev->dev.parent, "No platform init data supplied.\n");
>                return -ENODEV;
>        }
>
> +       if (iodev->dev->of_node) {
> +               ret = max8997_pmic_dt_parse_pdata(iodev, pdata);
> +               if (ret)
> +                       return ret;
> +       }
> +
>        max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL);
>        if (!max8997)
>                return -ENOMEM;
> @@ -1141,7 +1277,8 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
>                        regulators[id].n_voltages = 16;
>
>                rdev[i] = regulator_register(&regulators[id], max8997->dev,
> -                               pdata->regulators[i].initdata, max8997, NULL);
> +                               pdata->regulators[i].initdata, max8997,
> +                               pdata->regulators[i].reg_node);
>                if (IS_ERR(rdev[i])) {
>                        ret = PTR_ERR(rdev[i]);
>                        dev_err(max8997->dev, "regulator init failed for %d\n",
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 830152c..6ae21bf 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -316,6 +316,7 @@ enum max8997_irq {
>  #define MAX8997_NUM_GPIO       12
>  struct max8997_dev {
>        struct device *dev;
> +       struct max8997_platform_data *pdata;
>        struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
>        struct i2c_client *rtc; /* slave addr 0x0c */
>        struct i2c_client *haptic; /* slave addr 0x90 */
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index 818486c..ba92375 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -75,6 +75,7 @@ enum max8998_regulators {
>  struct max8997_regulator_data {
>        int id;
>        struct regulator_init_data *initdata;
> +       struct device_node *reg_node;
>  };
>
>  enum max8997_muic_usb_type {
> --
> 1.6.6.rc2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-03-27  6:40     ` MyungJoo Ham
  0 siblings, 0 replies; 36+ messages in thread
From: MyungJoo Ham @ 2012-03-27  6:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 24, 2012 at 6:49 PM, Thomas Abraham
<thomas.abraham@linaro.org> wrote:
> Add device tree based discovery support for max8997.
>
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Cc: Rajendra Nayak <rnayak@ti.com>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>

Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com>

> ---
> ?.../devicetree/bindings/regulator/max8997-pmic.txt | ?133 ++++++++++++++++++
> ?drivers/mfd/max8997.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 73 ++++++++++-
> ?drivers/regulator/max8997.c ? ? ? ? ? ? ? ? ? ? ? ?| ?143 +++++++++++++++++++-
> ?include/linux/mfd/max8997-private.h ? ? ? ? ? ? ? ?| ? ?1 +
> ?include/linux/mfd/max8997.h ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?5 files changed, 347 insertions(+), 4 deletions(-)
> ?create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt
>
> diff --git a/Documentation/devicetree/bindings/regulator/max8997-pmic.txt b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> new file mode 100644
> index 0000000..90a730b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> @@ -0,0 +1,133 @@
> +* Maxim MAX8997 Voltage and Current Regulator
> +
> +The Maxim MAX8997 is a multi-function device which includes volatage and
> +current regulators, rtc, charger controller and other sub-blocks. It is
> +interfaced to the host controller using a i2c interface. Each sub-block is
> +addressed by the host system using different i2c slave address. This document
> +describes the bindings for 'pmic' sub-block of max8997.
> +
> +Required properties:
> +- compatible: Should be "maxim,max8997-pmic".
> +- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
> +
> +- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> + ?units for buck1 when changing voltage using gpio dvs. Refer to [1] below
> + ?for additional information.
> +
> +- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> + ?units for buck2 when changing voltage using gpio dvs. Refer to [1] below
> + ?for additional information.
> +
> +- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> + ?units for buck5 when changing voltage using gpio dvs. Refer to [1] below
> + ?for additional information.
> +
> +[1] If none of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
> + ? ?property is specified, the 'max8997,pmic-buck[1/2/5]-dvs-voltage'
> + ? ?property should specify atleast one voltage level (which would be a
> + ? ?safe operating voltage).
> +
> + ? ?If either of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
> + ? ?property is specified, then all the eigth voltage values for the
> + ? ?'max8997,pmic-buck[1/2/5]-dvs-voltage' should be specified.
> +
> +Optional properties:
> +- interrupt-parent: Specifies the phandle of the interrupt controller to which
> + ?the interrupts from max8997 are delivered to.
> +- interrupts: Interrupt specifiers for two interrupt sources.
> + ?- First interrupt specifier is for 'irq1' interrupt.
> + ?- Second interrupt specifier is for 'alert' interrupt.
> +- max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs.
> +- max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
> +- max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs.
> +
> +Additional properties required if either of the optional properties are used:
> +- max8997,pmic-ignore-gpiodvs-side-effect: When GPIO-DVS mode is used for
> + ?multiple bucks, changing the voltage value of one of the bucks may affect
> + ?that of another buck, which is the side effect of the change (set_voltage).
> + ?Use this property to ignore such side effects and change the voltage.
> +
> +- max8997,pmic-buck125-default-dvs-idx: Default voltage setting selected from
> + ?the possible 8 options selectable by the dvs gpios. The value of this
> + ?property should be between 0 and 7. If not specified or if out of range, the
> + ?default value of this property is set to 0.
> +
> +- max8997,pmic-buck125-dvs-gpios: GPIO specifiers for three host gpio's used
> + ?for dvs. The format of the gpio specifier depends in the gpio controller.
> +
> +
> +Regulators: The regulators of max8997 that have to be instantiated should be
> +included in a sub-node named 'regulators'. Regulator nodes included in this
> +sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
> +represents the LDO or BUCK number as per the datasheet of max8997.
> +
> + ? ?For LDO's:
> + ? ? ? ? ? ? ? LDOn {
> + ? ? ? ? ? ? ? ? ? ? ? standard regulator bindings here
> + ? ? ? ? ? ? ? };
> +
> + ? ?For BUCK's:
> + ? ? ? ? ? ? ? BUCKn {
> + ? ? ? ? ? ? ? ? ? ? ? standard regulator bindings here
> + ? ? ? ? ? ? ? };
> +
> +The bindings inside the regulator nodes use the standard regulator bindings
> +which are documented elsewhere.
> +
> +Example:
> +
> + ? ? ? max8997_pmic at 66 {
> + ? ? ? ? ? ? ? compatible = "maxim,max8997-pmic";
> + ? ? ? ? ? ? ? interrupt-parent = <&wakeup_eint>;
> + ? ? ? ? ? ? ? reg = <0x66>;
> + ? ? ? ? ? ? ? interrupts = <4 0>, <3 0>;
> +
> + ? ? ? ? ? ? ? max8997,pmic-buck1-uses-gpio-dvs;
> + ? ? ? ? ? ? ? max8997,pmic-buck2-uses-gpio-dvs;
> + ? ? ? ? ? ? ? max8997,pmic-buck5-uses-gpio-dvs;
> +
> + ? ? ? ? ? ? ? max8997,pmic-ignore-gpiodvs-side-effect;
> + ? ? ? ? ? ? ? max8997,pmic-buck125-default-dvs-idx = <0>;
> +
> + ? ? ? ? ? ? ? max8997,pmic-buck125-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<&gpx0 1 1 0 0>, /* SET2 */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<&gpx0 2 1 0 0>; /* SET3 */
> +
> + ? ? ? ? ? ? ? max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1250000>, <1200000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1150000>, <1100000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1000000>, <950000>;
> +
> + ? ? ? ? ? ? ? max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1100000>, <1100000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1000000>, <1000000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1000000>, <1000000>;
> +
> + ? ? ? ? ? ? ? max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1200000>, <1200000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1200000>, <1200000>,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1200000>, <1200000>;
> +
> + ? ? ? ? ? ? ? regulators {
> + ? ? ? ? ? ? ? ? ? ? ? ldo1_reg: LDO1 {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-name = "VDD_ABB_3.3V";
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-min-microvolt = <3300000>;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-max-microvolt = <3300000>;
> + ? ? ? ? ? ? ? ? ? ? ? };
> +
> + ? ? ? ? ? ? ? ? ? ? ? ldo2_reg: LDO2 {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-name = "VDD_ALIVE_1.1V";
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-min-microvolt = <1100000>;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-max-microvolt = <1100000>;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-always-on;
> + ? ? ? ? ? ? ? ? ? ? ? };
> +
> + ? ? ? ? ? ? ? ? ? ? ? buck1_reg: BUCK1 {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-name = "VDD_ARM_1.2V";
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-min-microvolt = <950000>;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-max-microvolt = <1350000>;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-always-on;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? regulator-boot-on;
> + ? ? ? ? ? ? ? ? ? ? ? };
> + ? ? ? ? ? ? ? };
> + ? ? ? };
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index 20ecad3..1c38e98 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -21,8 +21,10 @@
> ?* This driver is based on max8998.c
> ?*/
>
> +#include <linux/err.h>
> ?#include <linux/slab.h>
> ?#include <linux/i2c.h>
> +#include <linux/of_irq.h>
> ?#include <linux/interrupt.h>
> ?#include <linux/pm_runtime.h>
> ?#include <linux/module.h>
> @@ -47,6 +49,13 @@ static struct mfd_cell max8997_devs[] = {
> ? ? ? ?{ .name = "max8997-led", .id = 2 },
> ?};
>
> +#ifdef CONFIG_OF
> +static struct of_device_id __devinitdata max8997_pmic_dt_match[] = {
> + ? ? ? { .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
> + ? ? ? {},
> +};
> +#endif
> +
> ?int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
> ?{
> ? ? ? ?struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
> @@ -123,6 +132,58 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
> ?}
> ?EXPORT_SYMBOL_GPL(max8997_update_reg);
>
> +#ifdef CONFIG_OF
> +/*
> + * Only the common platform data elements for max8997 are parsed here from the
> + * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
> + * to parse their own platform data elements from device tree.
> + *
> + * The max8997 platform data structure is instantiated here and the drivers for
> + * the sub-modules need not instantiate another instance while parsing their
> + * platform data.
> + */
> +static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct device *dev)
> +{
> + ? ? ? struct max8997_platform_data *pd;
> +
> + ? ? ? pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> + ? ? ? if (!pd) {
> + ? ? ? ? ? ? ? dev_err(dev, "could not allocate memory for pdata\n");
> + ? ? ? ? ? ? ? return ERR_PTR(-ENOMEM);
> + ? ? ? }
> +
> + ? ? ? pd->ono = irq_of_parse_and_map(dev->of_node, 1);
> +
> + ? ? ? /*
> + ? ? ? ?* ToDo: the 'wakeup' member in the platform data is more of a linux
> + ? ? ? ?* specfic information. Hence, there is no binding for that yet and
> + ? ? ? ?* not parsed here.
> + ? ? ? ?*/
> +
> + ? ? ? return pd;
> +}
> +#else
> +static int max8997_i2c_parse_dt_pdata(struct device *dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct max8997_platform_data **pdata)
> +{
> + ? ? ? return 0;
> +}
> +#endif
> +
> +static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const struct i2c_device_id *id)
> +{
> +#ifdef CONFIG_OF
> + ? ? ? if (i2c->dev.of_node) {
> + ? ? ? ? ? ? ? const struct of_device_id *match;
> + ? ? ? ? ? ? ? match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
> + ? ? ? ? ? ? ? return (int)match->data;
> + ? ? ? }
> +#endif
> + ? ? ? return (int)id->driver_data;
> +}
> +
> ?static int max8997_i2c_probe(struct i2c_client *i2c,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ?const struct i2c_device_id *id)
> ?{
> @@ -137,12 +198,21 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
> ? ? ? ?i2c_set_clientdata(i2c, max8997);
> ? ? ? ?max8997->dev = &i2c->dev;
> ? ? ? ?max8997->i2c = i2c;
> - ? ? ? max8997->type = id->driver_data;
> + ? ? ? max8997->type = max8997_i2c_get_driver_data(i2c, id);
> ? ? ? ?max8997->irq = i2c->irq;
>
> + ? ? ? if (max8997->dev->of_node) {
> + ? ? ? ? ? ? ? pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
> + ? ? ? ? ? ? ? if (IS_ERR(pdata)) {
> + ? ? ? ? ? ? ? ? ? ? ? ret = PTR_ERR(pdata);
> + ? ? ? ? ? ? ? ? ? ? ? goto err;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> ? ? ? ?if (!pdata)
> ? ? ? ? ? ? ? ?goto err;
>
> + ? ? ? max8997->pdata = pdata;
> ? ? ? ?max8997->ono = pdata->ono;
>
> ? ? ? ?mutex_init(&max8997->iolock);
> @@ -434,6 +504,7 @@ static struct i2c_driver max8997_i2c_driver = {
> ? ? ? ? ? ? ? ? ? .name = "max8997",
> ? ? ? ? ? ? ? ? ? .owner = THIS_MODULE,
> ? ? ? ? ? ? ? ? ? .pm = &max8997_pm,
> + ? ? ? ? ? ? ? ? ?.of_match_table = of_match_ptr(max8997_pmic_dt_match),
> ? ? ? ?},
> ? ? ? ?.probe = max8997_i2c_probe,
> ? ? ? ?.remove = max8997_i2c_remove,
> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
> index 9657929..dce8aaf 100644
> --- a/drivers/regulator/max8997.c
> +++ b/drivers/regulator/max8997.c
> @@ -25,6 +25,7 @@
> ?#include <linux/delay.h>
> ?#include <linux/err.h>
> ?#include <linux/gpio.h>
> +#include <linux/of_gpio.h>
> ?#include <linux/slab.h>
> ?#include <linux/module.h>
> ?#include <linux/platform_device.h>
> @@ -32,6 +33,7 @@
> ?#include <linux/regulator/machine.h>
> ?#include <linux/mfd/max8997.h>
> ?#include <linux/mfd/max8997-private.h>
> +#include <linux/regulator/of_regulator.h>
>
> ?struct max8997_data {
> ? ? ? ?struct device *dev;
> @@ -953,21 +955,155 @@ static struct regulator_desc regulators[] = {
> ? ? ? ?},
> ?};
>
> +#ifdef CONFIG_OF
> +static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
> + ? ? ? ? ? ? ? ? ? ? ? struct max8997_platform_data *pdata,
> + ? ? ? ? ? ? ? ? ? ? ? struct device_node *pmic_np)
> +{
> + ? ? ? int i, gpio;
> +
> + ? ? ? for (i = 0; i < 3; i++) {
> + ? ? ? ? ? ? ? gpio = of_get_named_gpio(pmic_np,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "max8997,pmic-buck125-dvs-gpios", i);
> + ? ? ? ? ? ? ? if (!gpio_is_valid(gpio)) {
> + ? ? ? ? ? ? ? ? ? ? ? dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
> + ? ? ? ? ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? pdata->buck125_gpios[i] = gpio;
> + ? ? ? }
> + ? ? ? return 0;
> +}
> +
> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct max8997_platform_data *pdata)
> +{
> + ? ? ? struct device_node *pmic_np, *regulators_np, *reg_np;
> + ? ? ? struct max8997_regulator_data *rdata;
> + ? ? ? unsigned int i, dvs_voltage_nr = 1, ret;
> +
> + ? ? ? pmic_np = iodev->dev->of_node;
> + ? ? ? if (!pmic_np) {
> + ? ? ? ? ? ? ? dev_err(iodev->dev, "could not find pmic sub-node\n");
> + ? ? ? ? ? ? ? return -ENODEV;
> + ? ? ? }
> +
> + ? ? ? regulators_np = of_find_node_by_name(pmic_np, "regulators");
> + ? ? ? if (!regulators_np) {
> + ? ? ? ? ? ? ? dev_err(iodev->dev, "could not find regulators sub-node\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? /* count the number of regulators to be supported in pmic */
> + ? ? ? pdata->num_regulators = 0;
> + ? ? ? for_each_child_of_node(regulators_np, reg_np)
> + ? ? ? ? ? ? ? pdata->num_regulators++;
> +
> + ? ? ? rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->num_regulators, GFP_KERNEL);
> + ? ? ? if (!rdata) {
> + ? ? ? ? ? ? ? dev_err(iodev->dev, "could not allocate memory for "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "regulator data\n");
> + ? ? ? ? ? ? ? return -ENOMEM;
> + ? ? ? }
> +
> + ? ? ? pdata->regulators = rdata;
> + ? ? ? for_each_child_of_node(regulators_np, reg_np) {
> + ? ? ? ? ? ? ? for (i = 0; i < ARRAY_SIZE(regulators); i++)
> + ? ? ? ? ? ? ? ? ? ? ? if (!of_node_cmp(reg_np->name, regulators[i].name))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? rdata->id = i;
> + ? ? ? ? ? ? ? rdata->initdata = of_get_regulator_init_data(
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? iodev->dev, reg_np);
> + ? ? ? ? ? ? ? rdata->reg_node = reg_np;
> + ? ? ? ? ? ? ? rdata++;
> + ? ? ? }
> +
> + ? ? ? if (of_get_property(pmic_np, "max8997,pmic-buck1-uses-gpio-dvs", NULL))
> + ? ? ? ? ? ? ? pdata->buck1_gpiodvs = true;
> +
> + ? ? ? if (of_get_property(pmic_np, "max8997,pmic-buck2-uses-gpio-dvs", NULL))
> + ? ? ? ? ? ? ? pdata->buck2_gpiodvs = true;
> +
> + ? ? ? if (of_get_property(pmic_np, "max8997,pmic-buck5-uses-gpio-dvs", NULL))
> + ? ? ? ? ? ? ? pdata->buck5_gpiodvs = true;
> +
> + ? ? ? if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->buck5_gpiodvs) {
> + ? ? ? ? ? ? ? ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
> + ? ? ? ? ? ? ? if (ret)
> + ? ? ? ? ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? ? ? ? ? if (of_property_read_u32(pmic_np,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "max8997,pmic-buck125-default-dvs-idx",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &pdata->buck125_default_idx)) {
> + ? ? ? ? ? ? ? ? ? ? ? pdata->buck125_default_idx = 0;
> + ? ? ? ? ? ? ? } else {
> + ? ? ? ? ? ? ? ? ? ? ? if (pdata->buck125_default_idx >= 8) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->buck125_default_idx = 0;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dev_info(iodev->dev, "invalid value for "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "default dvs index, using 0 instead\n");
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? if (of_get_property(pmic_np,
> + ? ? ? ? ? ? ? ? ? ? ? "max8997,pmic-ignore-gpiodvs-side-effect", NULL))
> + ? ? ? ? ? ? ? ? ? ? ? pdata->ignore_gpiodvs_side_effect = true;
> +
> + ? ? ? ? ? ? ? dvs_voltage_nr = 8;
> + ? ? ? }
> +
> + ? ? ? if (of_property_read_u32_array(pmic_np,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "max8997,pmic-buck1-dvs-voltage",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->buck1_voltage, dvs_voltage_nr)) {
> + ? ? ? ? ? ? ? dev_err(iodev->dev, "buck1 voltages not specified\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? if (of_property_read_u32_array(pmic_np,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "max8997,pmic-buck2-dvs-voltage",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->buck2_voltage, dvs_voltage_nr)) {
> + ? ? ? ? ? ? ? dev_err(iodev->dev, "buck2 voltages not specified\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? if (of_property_read_u32_array(pmic_np,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "max8997,pmic-buck5-dvs-voltage",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->buck5_voltage, dvs_voltage_nr)) {
> + ? ? ? ? ? ? ? dev_err(iodev->dev, "buck5 voltages not specified\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +#else
> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct max8997_platform_data *pdata)
> +{
> + ? ? ? return 0;
> +}
> +#endif /* CONFIG_OF */
> +
> ?static __devinit int max8997_pmic_probe(struct platform_device *pdev)
> ?{
> ? ? ? ?struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
> - ? ? ? struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
> + ? ? ? struct max8997_platform_data *pdata = iodev->pdata;
> ? ? ? ?struct regulator_dev **rdev;
> ? ? ? ?struct max8997_data *max8997;
> ? ? ? ?struct i2c_client *i2c;
> ? ? ? ?int i, ret, size;
> ? ? ? ?u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0;
>
> - ? ? ? if (!pdata) {
> + ? ? ? if (IS_ERR_OR_NULL(pdata)) {
> ? ? ? ? ? ? ? ?dev_err(pdev->dev.parent, "No platform init data supplied.\n");
> ? ? ? ? ? ? ? ?return -ENODEV;
> ? ? ? ?}
>
> + ? ? ? if (iodev->dev->of_node) {
> + ? ? ? ? ? ? ? ret = max8997_pmic_dt_parse_pdata(iodev, pdata);
> + ? ? ? ? ? ? ? if (ret)
> + ? ? ? ? ? ? ? ? ? ? ? return ret;
> + ? ? ? }
> +
> ? ? ? ?max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL);
> ? ? ? ?if (!max8997)
> ? ? ? ? ? ? ? ?return -ENOMEM;
> @@ -1141,7 +1277,8 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
> ? ? ? ? ? ? ? ? ? ? ? ?regulators[id].n_voltages = 16;
>
> ? ? ? ? ? ? ? ?rdev[i] = regulator_register(&regulators[id], max8997->dev,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->regulators[i].initdata, max8997, NULL);
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->regulators[i].initdata, max8997,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->regulators[i].reg_node);
> ? ? ? ? ? ? ? ?if (IS_ERR(rdev[i])) {
> ? ? ? ? ? ? ? ? ? ? ? ?ret = PTR_ERR(rdev[i]);
> ? ? ? ? ? ? ? ? ? ? ? ?dev_err(max8997->dev, "regulator init failed for %d\n",
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 830152c..6ae21bf 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -316,6 +316,7 @@ enum max8997_irq {
> ?#define MAX8997_NUM_GPIO ? ? ? 12
> ?struct max8997_dev {
> ? ? ? ?struct device *dev;
> + ? ? ? struct max8997_platform_data *pdata;
> ? ? ? ?struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
> ? ? ? ?struct i2c_client *rtc; /* slave addr 0x0c */
> ? ? ? ?struct i2c_client *haptic; /* slave addr 0x90 */
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index 818486c..ba92375 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -75,6 +75,7 @@ enum max8998_regulators {
> ?struct max8997_regulator_data {
> ? ? ? ?int id;
> ? ? ? ?struct regulator_init_data *initdata;
> + ? ? ? struct device_node *reg_node;
> ?};
>
> ?enum max8997_muic_usb_type {
> --
> 1.6.6.rc2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html



-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-03-28 17:03     ` Karol Lewandowski
  -1 siblings, 0 replies; 36+ messages in thread
From: Karol Lewandowski @ 2012-03-28 17:03 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: linux-kernel, devicetree-discuss, rob.herring, grant.likely,
	kgene.kim, broonie, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

On 24.03.2012 10:49, Thomas Abraham wrote:

Hi Thomas!

> Add device tree based discovery support for max8997.
... 
> +Regulators: The regulators of max8997 that have to be instantiated should be
> +included in a sub-node named 'regulators'. Regulator nodes included in this
> +sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
> +represents the LDO or BUCK number as per the datasheet of max8997.
> +
> +    For LDO's:
> +		LDOn {
> +			standard regulator bindings here
> +		};
> +
> +    For BUCK's:
> +		BUCKn {
> +			standard regulator bindings here
> +		};
> +


Small note - driver supports[1] configuring following regulators by
using respective DT node names:

 - EN32KHz_AP
 - EN32KHz_CP
 - ENVICHG
 - ESAFEOUT1
 - ESAFEOUT2
 - CHARGER
 - CHARGER_CV
 - CHARGER_TOPOFF

I wonder if these should be mentioned in documentation too.

[1] These are used in e.g. mach-nuri.c

> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c> index 9657929..dce8aaf 100644

> --- a/drivers/regulator/max8997.c
> +++ b/drivers/regulator/max8997.c
..
> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
> +					struct max8997_platform_data *pdata)
> +{
> +	struct device_node *pmic_np, *regulators_np, *reg_np;
> +	struct max8997_regulator_data *rdata;
> +	unsigned int i, dvs_voltage_nr = 1, ret;
> +
> +	pmic_np = iodev->dev->of_node;
> +	if (!pmic_np) {
> +		dev_err(iodev->dev, "could not find pmic sub-node\n");
> +		return -ENODEV;
> +	}
> +
> +	regulators_np = of_find_node_by_name(pmic_np, "regulators");
> +	if (!regulators_np) {
> +		dev_err(iodev->dev, "could not find regulators sub-node\n");
> +		return -EINVAL;
> +	}
> +
> +	/* count the number of regulators to be supported in pmic */
> +	pdata->num_regulators = 0;
> +	for_each_child_of_node(regulators_np, reg_np)
> +		pdata->num_regulators++;
> +
> +	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
> +				pdata->num_regulators, GFP_KERNEL);
> +	if (!rdata) {
> +		dev_err(iodev->dev, "could not allocate memory for "
> +						"regulator data\n");
> +		return -ENOMEM;
> +	}

> +	pdata->regulators = rdata;

> +	for_each_child_of_node(regulators_np, reg_np) {
> +		for (i = 0; i < ARRAY_SIZE(regulators); i++)
> +			if (!of_node_cmp(reg_np->name, regulators[i].name))
> +				break;
> +		rdata->id = i;


rdata->id will be equal to ARRAY_SIZE(regulators) when one adds DT node
name (below "regulators") which is different from what can be found in
regulators[] table.

On my test machine this results in hard lockup - possibly because
something tries to access regulators[ARRAY_SIZE(regulators)]
later on.

Following patch fixes this on my machine (using DTS with misspelled LDO1 for LDx1):

diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index dce8aaf..c20fd72 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -1011,6 +1011,13 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
                for (i = 0; i < ARRAY_SIZE(regulators); i++)
                        if (!of_node_cmp(reg_np->name, regulators[i].name))
                                break;
+
+               if (i == ARRAY_SIZE(regulators)) {
+                       dev_warn(iodev->dev, "don't know how to configure regulator %s\n",
+                                reg_np->name);
+                       continue;
+               }
+
                rdata->id = i;
                rdata->initdata = of_get_regulator_init_data(
                                                iodev->dev, reg_np);


Regards,
-- 
Karol Lewandowski | Samsung Poland R&D Center | Linux/Platform

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-03-28 17:03     ` Karol Lewandowski
  0 siblings, 0 replies; 36+ messages in thread
From: Karol Lewandowski @ 2012-03-28 17:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 24.03.2012 10:49, Thomas Abraham wrote:

Hi Thomas!

> Add device tree based discovery support for max8997.
... 
> +Regulators: The regulators of max8997 that have to be instantiated should be
> +included in a sub-node named 'regulators'. Regulator nodes included in this
> +sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
> +represents the LDO or BUCK number as per the datasheet of max8997.
> +
> +    For LDO's:
> +		LDOn {
> +			standard regulator bindings here
> +		};
> +
> +    For BUCK's:
> +		BUCKn {
> +			standard regulator bindings here
> +		};
> +


Small note - driver supports[1] configuring following regulators by
using respective DT node names:

 - EN32KHz_AP
 - EN32KHz_CP
 - ENVICHG
 - ESAFEOUT1
 - ESAFEOUT2
 - CHARGER
 - CHARGER_CV
 - CHARGER_TOPOFF

I wonder if these should be mentioned in documentation too.

[1] These are used in e.g. mach-nuri.c

> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c> index 9657929..dce8aaf 100644

> --- a/drivers/regulator/max8997.c
> +++ b/drivers/regulator/max8997.c
..
> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
> +					struct max8997_platform_data *pdata)
> +{
> +	struct device_node *pmic_np, *regulators_np, *reg_np;
> +	struct max8997_regulator_data *rdata;
> +	unsigned int i, dvs_voltage_nr = 1, ret;
> +
> +	pmic_np = iodev->dev->of_node;
> +	if (!pmic_np) {
> +		dev_err(iodev->dev, "could not find pmic sub-node\n");
> +		return -ENODEV;
> +	}
> +
> +	regulators_np = of_find_node_by_name(pmic_np, "regulators");
> +	if (!regulators_np) {
> +		dev_err(iodev->dev, "could not find regulators sub-node\n");
> +		return -EINVAL;
> +	}
> +
> +	/* count the number of regulators to be supported in pmic */
> +	pdata->num_regulators = 0;
> +	for_each_child_of_node(regulators_np, reg_np)
> +		pdata->num_regulators++;
> +
> +	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
> +				pdata->num_regulators, GFP_KERNEL);
> +	if (!rdata) {
> +		dev_err(iodev->dev, "could not allocate memory for "
> +						"regulator data\n");
> +		return -ENOMEM;
> +	}

> +	pdata->regulators = rdata;

> +	for_each_child_of_node(regulators_np, reg_np) {
> +		for (i = 0; i < ARRAY_SIZE(regulators); i++)
> +			if (!of_node_cmp(reg_np->name, regulators[i].name))
> +				break;
> +		rdata->id = i;


rdata->id will be equal to ARRAY_SIZE(regulators) when one adds DT node
name (below "regulators") which is different from what can be found in
regulators[] table.

On my test machine this results in hard lockup - possibly because
something tries to access regulators[ARRAY_SIZE(regulators)]
later on.

Following patch fixes this on my machine (using DTS with misspelled LDO1 for LDx1):

diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index dce8aaf..c20fd72 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -1011,6 +1011,13 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
                for (i = 0; i < ARRAY_SIZE(regulators); i++)
                        if (!of_node_cmp(reg_np->name, regulators[i].name))
                                break;
+
+               if (i == ARRAY_SIZE(regulators)) {
+                       dev_warn(iodev->dev, "don't know how to configure regulator %s\n",
+                                reg_np->name);
+                       continue;
+               }
+
                rdata->id = i;
                rdata->initdata = of_get_regulator_init_data(
                                                iodev->dev, reg_np);


Regards,
-- 
Karol Lewandowski | Samsung Poland R&D Center | Linux/Platform

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

* Re: [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-03-30 22:06     ` Grant Likely
  -1 siblings, 0 replies; 36+ messages in thread
From: Grant Likely @ 2012-03-30 22:06 UTC (permalink / raw)
  To: Thomas Abraham, linux-kernel
  Cc: k.lewandowsk, devicetree-discuss, rob.herring, kgene.kim,
	broonie, myungjoo.ham, kyungmin.park, linux-arm-kernel,
	linux-samsung-soc, patches

On Sat, 24 Mar 2012 15:19:49 +0530, Thomas Abraham <thomas.abraham@linaro.org> wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.
> 
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>  arch/arm/mach-exynos/mach-nuri.c    |    4 --
>  arch/arm/mach-exynos/mach-origen.c  |    1 -
>  drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
>  drivers/mfd/max8997.c               |    1 -
>  include/linux/mfd/max8997-private.h |    4 ++-
>  include/linux/mfd/max8997.h         |    1 -
>  6 files changed, 39 insertions(+), 33 deletions(-)
> 
> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
> index 7ac81ce..b21d85d 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
>  static void __init nuri_power_init(void)
>  {
>  	int gpio;
> -	int irq_base = IRQ_GPIO_END + 1;
>  	int ta_en = 0;
>  
> -	nuri_max8997_pdata.irq_base = irq_base;
> -	irq_base += MAX8997_IRQ_NR;
> -
>  	gpio = EXYNOS4_GPX0(7);
>  	gpio_request(gpio, "AP_PMIC_IRQ");
>  	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
> index 827cb99..d3b2e9d 100644
> --- a/arch/arm/mach-exynos/mach-origen.c
> +++ b/arch/arm/mach-exynos/mach-origen.c
> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
>  	.buck1_gpiodvs	= false,
>  	.buck2_gpiodvs	= false,
>  	.buck5_gpiodvs	= false,
> -	.irq_base	= IRQ_GPIO_END + 1,
>  
>  	.ignore_gpiodvs_side_effect = true,
>  	.buck125_default_idx = 0x0,
> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
> index 09274cf..00390a1 100644
> --- a/drivers/mfd/max8997-irq.c
> +++ b/drivers/mfd/max8997-irq.c
> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
>  static const inline struct max8997_irq_data *
>  irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
>  {
> -	return &max8997_irqs[irq - max8997->irq_base];
> +	struct irq_data *data = irq_get_irq_data(irq);
> +	return &max8997_irqs[data->hwirq];
>  }

Haha, this is kind of bogus now.  There are only two users of this
function, and *both* of them already have the irq_data pointer.
Instead of this, delete this function entirely and make each caller
derefernce max8997_irqs directly:

	const struct max8997_irq_data *irq_data = &max8997_irqs[data->hwirq];

Otherwise, looks good.  After fixing you can add my:

Acked-by: Grant Likely <grant.likely@secretlab.ca>

>  
>  static void max8997_irq_mask(struct irq_data *data)
> @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  	u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
>  	u8 irq_src;
>  	int ret;
> -	int i;
> +	int i, cur_irq;
>  
>  	ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
>  	if (ret < 0) {
> @@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  	/* Report */
>  	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
> -			handle_nested_irq(max8997->irq_base + i);
> +		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
> +			cur_irq = irq_find_mapping(max8997->irq_domain, i);
> +			if (cur_irq)
> +				handle_nested_irq(cur_irq);
> +		}
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  int max8997_irq_resume(struct max8997_dev *max8997)
>  {
> -	if (max8997->irq && max8997->irq_base)
> -		max8997_irq_thread(max8997->irq_base, max8997);
> +	if (max8997->irq && max8997->irq_domain)
> +		max8997_irq_thread(0, max8997);
> +	return 0;
> +}
> +
> +static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
> +					irq_hw_number_t hw)
> +{
> +	struct max8997_dev *max8997 = d->host_data;
> +
> +	irq_set_chip_data(irq, max8997);
> +	irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
> +	irq_set_nested_thread(irq, 1);
> +#ifdef CONFIG_ARM
> +	set_irq_flags(irq, IRQF_VALID);
> +#else
> +	irq_set_noprobe(irq);
> +#endif
>  	return 0;
>  }
>  
> +static struct irq_domain_ops max8997_irq_domain_ops = {
> +	.map = max8997_irq_domain_map,
> +};
> +
>  int max8997_irq_init(struct max8997_dev *max8997)
>  {
> +	struct irq_domain *domain;
>  	int i;
> -	int cur_irq;
>  	int ret;
>  	u8 val;
>  
>  	if (!max8997->irq) {
>  		dev_warn(max8997->dev, "No interrupt specified.\n");
> -		max8997->irq_base = 0;
> -		return 0;
> -	}
> -
> -	if (!max8997->irq_base) {
> -		dev_err(max8997->dev, "No interrupt base specified.\n");
>  		return 0;
>  	}
>  
> @@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
>  					true : false;
>  	}
>  
> -	/* Register with genirq */
> -	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		cur_irq = i + max8997->irq_base;
> -		irq_set_chip_data(cur_irq, max8997);
> -		irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
> -				handle_edge_irq);
> -		irq_set_nested_thread(cur_irq, 1);
> -#ifdef CONFIG_ARM
> -		set_irq_flags(cur_irq, IRQF_VALID);
> -#else
> -		irq_set_noprobe(cur_irq);
> -#endif
> +	domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
> +					&max8997_irq_domain_ops, &max8997);
> +	if (!domain) {
> +		dev_err(max8997->dev, "could not create irq domain\n");
> +		return -ENODEV;
>  	}
>  
>  	ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index cb83a7a..20ecad3 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
>  	if (!pdata)
>  		goto err;
>  
> -	max8997->irq_base = pdata->irq_base;
>  	max8997->ono = pdata->ono;
>  
>  	mutex_init(&max8997->iolock);
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 3f4deb6..830152c 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -23,6 +23,8 @@
>  #define __LINUX_MFD_MAX8997_PRIV_H
>  
>  #include <linux/i2c.h>
> +#include <linux/export.h>
> +#include <linux/irqdomain.h>
>  
>  #define MAX8997_REG_INVALID	(0xff)
>  
> @@ -325,7 +327,7 @@ struct max8997_dev {
>  
>  	int irq;
>  	int ono;
> -	int irq_base;
> +	struct irq_domain *irq_domain;
>  	struct mutex irqlock;
>  	int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
>  	int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index fff5905..818486c 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -155,7 +155,6 @@ struct max8997_led_platform_data {
>  
>  struct max8997_platform_data {
>  	/* IRQ */
> -	int irq_base;
>  	int ono;
>  	int wakeup;
>  
> -- 
> 1.6.6.rc2
> 

-- 
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies,Ltd.

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-03-30 22:06     ` Grant Likely
  0 siblings, 0 replies; 36+ messages in thread
From: Grant Likely @ 2012-03-30 22:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, 24 Mar 2012 15:19:49 +0530, Thomas Abraham <thomas.abraham@linaro.org> wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.
> 
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>  arch/arm/mach-exynos/mach-nuri.c    |    4 --
>  arch/arm/mach-exynos/mach-origen.c  |    1 -
>  drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
>  drivers/mfd/max8997.c               |    1 -
>  include/linux/mfd/max8997-private.h |    4 ++-
>  include/linux/mfd/max8997.h         |    1 -
>  6 files changed, 39 insertions(+), 33 deletions(-)
> 
> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
> index 7ac81ce..b21d85d 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
>  static void __init nuri_power_init(void)
>  {
>  	int gpio;
> -	int irq_base = IRQ_GPIO_END + 1;
>  	int ta_en = 0;
>  
> -	nuri_max8997_pdata.irq_base = irq_base;
> -	irq_base += MAX8997_IRQ_NR;
> -
>  	gpio = EXYNOS4_GPX0(7);
>  	gpio_request(gpio, "AP_PMIC_IRQ");
>  	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
> index 827cb99..d3b2e9d 100644
> --- a/arch/arm/mach-exynos/mach-origen.c
> +++ b/arch/arm/mach-exynos/mach-origen.c
> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
>  	.buck1_gpiodvs	= false,
>  	.buck2_gpiodvs	= false,
>  	.buck5_gpiodvs	= false,
> -	.irq_base	= IRQ_GPIO_END + 1,
>  
>  	.ignore_gpiodvs_side_effect = true,
>  	.buck125_default_idx = 0x0,
> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
> index 09274cf..00390a1 100644
> --- a/drivers/mfd/max8997-irq.c
> +++ b/drivers/mfd/max8997-irq.c
> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
>  static const inline struct max8997_irq_data *
>  irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
>  {
> -	return &max8997_irqs[irq - max8997->irq_base];
> +	struct irq_data *data = irq_get_irq_data(irq);
> +	return &max8997_irqs[data->hwirq];
>  }

Haha, this is kind of bogus now.  There are only two users of this
function, and *both* of them already have the irq_data pointer.
Instead of this, delete this function entirely and make each caller
derefernce max8997_irqs directly:

	const struct max8997_irq_data *irq_data = &max8997_irqs[data->hwirq];

Otherwise, looks good.  After fixing you can add my:

Acked-by: Grant Likely <grant.likely@secretlab.ca>

>  
>  static void max8997_irq_mask(struct irq_data *data)
> @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  	u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
>  	u8 irq_src;
>  	int ret;
> -	int i;
> +	int i, cur_irq;
>  
>  	ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
>  	if (ret < 0) {
> @@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  	/* Report */
>  	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
> -			handle_nested_irq(max8997->irq_base + i);
> +		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
> +			cur_irq = irq_find_mapping(max8997->irq_domain, i);
> +			if (cur_irq)
> +				handle_nested_irq(cur_irq);
> +		}
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  int max8997_irq_resume(struct max8997_dev *max8997)
>  {
> -	if (max8997->irq && max8997->irq_base)
> -		max8997_irq_thread(max8997->irq_base, max8997);
> +	if (max8997->irq && max8997->irq_domain)
> +		max8997_irq_thread(0, max8997);
> +	return 0;
> +}
> +
> +static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
> +					irq_hw_number_t hw)
> +{
> +	struct max8997_dev *max8997 = d->host_data;
> +
> +	irq_set_chip_data(irq, max8997);
> +	irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
> +	irq_set_nested_thread(irq, 1);
> +#ifdef CONFIG_ARM
> +	set_irq_flags(irq, IRQF_VALID);
> +#else
> +	irq_set_noprobe(irq);
> +#endif
>  	return 0;
>  }
>  
> +static struct irq_domain_ops max8997_irq_domain_ops = {
> +	.map = max8997_irq_domain_map,
> +};
> +
>  int max8997_irq_init(struct max8997_dev *max8997)
>  {
> +	struct irq_domain *domain;
>  	int i;
> -	int cur_irq;
>  	int ret;
>  	u8 val;
>  
>  	if (!max8997->irq) {
>  		dev_warn(max8997->dev, "No interrupt specified.\n");
> -		max8997->irq_base = 0;
> -		return 0;
> -	}
> -
> -	if (!max8997->irq_base) {
> -		dev_err(max8997->dev, "No interrupt base specified.\n");
>  		return 0;
>  	}
>  
> @@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
>  					true : false;
>  	}
>  
> -	/* Register with genirq */
> -	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		cur_irq = i + max8997->irq_base;
> -		irq_set_chip_data(cur_irq, max8997);
> -		irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
> -				handle_edge_irq);
> -		irq_set_nested_thread(cur_irq, 1);
> -#ifdef CONFIG_ARM
> -		set_irq_flags(cur_irq, IRQF_VALID);
> -#else
> -		irq_set_noprobe(cur_irq);
> -#endif
> +	domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
> +					&max8997_irq_domain_ops, &max8997);
> +	if (!domain) {
> +		dev_err(max8997->dev, "could not create irq domain\n");
> +		return -ENODEV;
>  	}
>  
>  	ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index cb83a7a..20ecad3 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
>  	if (!pdata)
>  		goto err;
>  
> -	max8997->irq_base = pdata->irq_base;
>  	max8997->ono = pdata->ono;
>  
>  	mutex_init(&max8997->iolock);
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 3f4deb6..830152c 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -23,6 +23,8 @@
>  #define __LINUX_MFD_MAX8997_PRIV_H
>  
>  #include <linux/i2c.h>
> +#include <linux/export.h>
> +#include <linux/irqdomain.h>
>  
>  #define MAX8997_REG_INVALID	(0xff)
>  
> @@ -325,7 +327,7 @@ struct max8997_dev {
>  
>  	int irq;
>  	int ono;
> -	int irq_base;
> +	struct irq_domain *irq_domain;
>  	struct mutex irqlock;
>  	int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
>  	int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index fff5905..818486c 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -155,7 +155,6 @@ struct max8997_led_platform_data {
>  
>  struct max8997_platform_data {
>  	/* IRQ */
> -	int irq_base;
>  	int ono;
>  	int wakeup;
>  
> -- 
> 1.6.6.rc2
> 

-- 
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies,Ltd.

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-03-30 22:09     ` Grant Likely
  -1 siblings, 0 replies; 36+ messages in thread
From: Grant Likely @ 2012-03-30 22:09 UTC (permalink / raw)
  To: Thomas Abraham, linux-kernel
  Cc: k.lewandowsk, devicetree-discuss, rob.herring, kgene.kim,
	broonie, myungjoo.ham, kyungmin.park, linux-arm-kernel,
	linux-samsung-soc, patches, Rajendra Nayak

On Sat, 24 Mar 2012 15:19:50 +0530, Thomas Abraham <thomas.abraham@linaro.org> wrote:
> Add device tree based discovery support for max8997.
> 
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Cc: Rajendra Nayak <rnayak@ti.com>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
>  drivers/mfd/max8997.c                              |   73 ++++++++++-
>  drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
>  include/linux/mfd/max8997-private.h                |    1 +
>  include/linux/mfd/max8997.h                        |    1 +
>  5 files changed, 347 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> 
> diff --git a/Documentation/devicetree/bindings/regulator/max8997-pmic.txt b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> new file mode 100644
> index 0000000..90a730b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> @@ -0,0 +1,133 @@
> +* Maxim MAX8997 Voltage and Current Regulator
> +
> +The Maxim MAX8997 is a multi-function device which includes volatage and
> +current regulators, rtc, charger controller and other sub-blocks. It is
> +interfaced to the host controller using a i2c interface. Each sub-block is
> +addressed by the host system using different i2c slave address. This document
> +describes the bindings for 'pmic' sub-block of max8997.
> +
> +Required properties:
> +- compatible: Should be "maxim,max8997-pmic".
> +- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
> +
> +- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck1 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.
> +
> +- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck2 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.
> +
> +- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck5 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.

These are *really long* property names.  Anything over 32 characters
seems excessive to me.

Other than that the binding looks good.

g.


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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-03-30 22:09     ` Grant Likely
  0 siblings, 0 replies; 36+ messages in thread
From: Grant Likely @ 2012-03-30 22:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, 24 Mar 2012 15:19:50 +0530, Thomas Abraham <thomas.abraham@linaro.org> wrote:
> Add device tree based discovery support for max8997.
> 
> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Cc: Rajendra Nayak <rnayak@ti.com>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
>  .../devicetree/bindings/regulator/max8997-pmic.txt |  133 ++++++++++++++++++
>  drivers/mfd/max8997.c                              |   73 ++++++++++-
>  drivers/regulator/max8997.c                        |  143 +++++++++++++++++++-
>  include/linux/mfd/max8997-private.h                |    1 +
>  include/linux/mfd/max8997.h                        |    1 +
>  5 files changed, 347 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> 
> diff --git a/Documentation/devicetree/bindings/regulator/max8997-pmic.txt b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> new file mode 100644
> index 0000000..90a730b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/max8997-pmic.txt
> @@ -0,0 +1,133 @@
> +* Maxim MAX8997 Voltage and Current Regulator
> +
> +The Maxim MAX8997 is a multi-function device which includes volatage and
> +current regulators, rtc, charger controller and other sub-blocks. It is
> +interfaced to the host controller using a i2c interface. Each sub-block is
> +addressed by the host system using different i2c slave address. This document
> +describes the bindings for 'pmic' sub-block of max8997.
> +
> +Required properties:
> +- compatible: Should be "maxim,max8997-pmic".
> +- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
> +
> +- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck1 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.
> +
> +- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck2 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.
> +
> +- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
> +  units for buck5 when changing voltage using gpio dvs. Refer to [1] below
> +  for additional information.

These are *really long* property names.  Anything over 32 characters
seems excessive to me.

Other than that the binding looks good.

g.

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

* Re: [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-04-04 21:22     ` Mark Brown
  -1 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-04 21:22 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: linux-kernel, k.lewandowsk, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Samuel Ortiz

[-- Attachment #1: Type: text/plain, Size: 7265 bytes --]

On Sat, Mar 24, 2012 at 03:19:49PM +0530, Thomas Abraham wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.

> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

CCing in Samuel for the MFD review - review tends to be faster if you CC
maintainers!  Samuel, there's a followup patch for the regulator API
which is likely to collide with some API updates so is it OK to merge
via regulator if the patch is OK?

> ---
>  arch/arm/mach-exynos/mach-nuri.c    |    4 --
>  arch/arm/mach-exynos/mach-origen.c  |    1 -
>  drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
>  drivers/mfd/max8997.c               |    1 -
>  include/linux/mfd/max8997-private.h |    4 ++-
>  include/linux/mfd/max8997.h         |    1 -
>  6 files changed, 39 insertions(+), 33 deletions(-)
> 
> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
> index 7ac81ce..b21d85d 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
>  static void __init nuri_power_init(void)
>  {
>  	int gpio;
> -	int irq_base = IRQ_GPIO_END + 1;
>  	int ta_en = 0;
>  
> -	nuri_max8997_pdata.irq_base = irq_base;
> -	irq_base += MAX8997_IRQ_NR;
> -
>  	gpio = EXYNOS4_GPX0(7);
>  	gpio_request(gpio, "AP_PMIC_IRQ");
>  	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
> index 827cb99..d3b2e9d 100644
> --- a/arch/arm/mach-exynos/mach-origen.c
> +++ b/arch/arm/mach-exynos/mach-origen.c
> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
>  	.buck1_gpiodvs	= false,
>  	.buck2_gpiodvs	= false,
>  	.buck5_gpiodvs	= false,
> -	.irq_base	= IRQ_GPIO_END + 1,
>  
>  	.ignore_gpiodvs_side_effect = true,
>  	.buck125_default_idx = 0x0,
> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
> index 09274cf..00390a1 100644
> --- a/drivers/mfd/max8997-irq.c
> +++ b/drivers/mfd/max8997-irq.c
> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
>  static const inline struct max8997_irq_data *
>  irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
>  {
> -	return &max8997_irqs[irq - max8997->irq_base];
> +	struct irq_data *data = irq_get_irq_data(irq);
> +	return &max8997_irqs[data->hwirq];
>  }
>  
>  static void max8997_irq_mask(struct irq_data *data)
> @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  	u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
>  	u8 irq_src;
>  	int ret;
> -	int i;
> +	int i, cur_irq;
>  
>  	ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
>  	if (ret < 0) {
> @@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  	/* Report */
>  	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
> -			handle_nested_irq(max8997->irq_base + i);
> +		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
> +			cur_irq = irq_find_mapping(max8997->irq_domain, i);
> +			if (cur_irq)
> +				handle_nested_irq(cur_irq);
> +		}
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  int max8997_irq_resume(struct max8997_dev *max8997)
>  {
> -	if (max8997->irq && max8997->irq_base)
> -		max8997_irq_thread(max8997->irq_base, max8997);
> +	if (max8997->irq && max8997->irq_domain)
> +		max8997_irq_thread(0, max8997);
> +	return 0;
> +}
> +
> +static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
> +					irq_hw_number_t hw)
> +{
> +	struct max8997_dev *max8997 = d->host_data;
> +
> +	irq_set_chip_data(irq, max8997);
> +	irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
> +	irq_set_nested_thread(irq, 1);
> +#ifdef CONFIG_ARM
> +	set_irq_flags(irq, IRQF_VALID);
> +#else
> +	irq_set_noprobe(irq);
> +#endif
>  	return 0;
>  }
>  
> +static struct irq_domain_ops max8997_irq_domain_ops = {
> +	.map = max8997_irq_domain_map,
> +};
> +
>  int max8997_irq_init(struct max8997_dev *max8997)
>  {
> +	struct irq_domain *domain;
>  	int i;
> -	int cur_irq;
>  	int ret;
>  	u8 val;
>  
>  	if (!max8997->irq) {
>  		dev_warn(max8997->dev, "No interrupt specified.\n");
> -		max8997->irq_base = 0;
> -		return 0;
> -	}
> -
> -	if (!max8997->irq_base) {
> -		dev_err(max8997->dev, "No interrupt base specified.\n");
>  		return 0;
>  	}
>  
> @@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
>  					true : false;
>  	}
>  
> -	/* Register with genirq */
> -	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		cur_irq = i + max8997->irq_base;
> -		irq_set_chip_data(cur_irq, max8997);
> -		irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
> -				handle_edge_irq);
> -		irq_set_nested_thread(cur_irq, 1);
> -#ifdef CONFIG_ARM
> -		set_irq_flags(cur_irq, IRQF_VALID);
> -#else
> -		irq_set_noprobe(cur_irq);
> -#endif
> +	domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
> +					&max8997_irq_domain_ops, &max8997);
> +	if (!domain) {
> +		dev_err(max8997->dev, "could not create irq domain\n");
> +		return -ENODEV;
>  	}
>  
>  	ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index cb83a7a..20ecad3 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
>  	if (!pdata)
>  		goto err;
>  
> -	max8997->irq_base = pdata->irq_base;
>  	max8997->ono = pdata->ono;
>  
>  	mutex_init(&max8997->iolock);
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 3f4deb6..830152c 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -23,6 +23,8 @@
>  #define __LINUX_MFD_MAX8997_PRIV_H
>  
>  #include <linux/i2c.h>
> +#include <linux/export.h>
> +#include <linux/irqdomain.h>
>  
>  #define MAX8997_REG_INVALID	(0xff)
>  
> @@ -325,7 +327,7 @@ struct max8997_dev {
>  
>  	int irq;
>  	int ono;
> -	int irq_base;
> +	struct irq_domain *irq_domain;
>  	struct mutex irqlock;
>  	int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
>  	int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index fff5905..818486c 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -155,7 +155,6 @@ struct max8997_led_platform_data {
>  
>  struct max8997_platform_data {
>  	/* IRQ */
> -	int irq_base;
>  	int ono;
>  	int wakeup;
>  
> -- 
> 1.6.6.rc2
> 

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-04-04 21:22     ` Mark Brown
  0 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-04 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 24, 2012 at 03:19:49PM +0530, Thomas Abraham wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.

> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

CCing in Samuel for the MFD review - review tends to be faster if you CC
maintainers!  Samuel, there's a followup patch for the regulator API
which is likely to collide with some API updates so is it OK to merge
via regulator if the patch is OK?

> ---
>  arch/arm/mach-exynos/mach-nuri.c    |    4 --
>  arch/arm/mach-exynos/mach-origen.c  |    1 -
>  drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
>  drivers/mfd/max8997.c               |    1 -
>  include/linux/mfd/max8997-private.h |    4 ++-
>  include/linux/mfd/max8997.h         |    1 -
>  6 files changed, 39 insertions(+), 33 deletions(-)
> 
> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
> index 7ac81ce..b21d85d 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
>  static void __init nuri_power_init(void)
>  {
>  	int gpio;
> -	int irq_base = IRQ_GPIO_END + 1;
>  	int ta_en = 0;
>  
> -	nuri_max8997_pdata.irq_base = irq_base;
> -	irq_base += MAX8997_IRQ_NR;
> -
>  	gpio = EXYNOS4_GPX0(7);
>  	gpio_request(gpio, "AP_PMIC_IRQ");
>  	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
> index 827cb99..d3b2e9d 100644
> --- a/arch/arm/mach-exynos/mach-origen.c
> +++ b/arch/arm/mach-exynos/mach-origen.c
> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
>  	.buck1_gpiodvs	= false,
>  	.buck2_gpiodvs	= false,
>  	.buck5_gpiodvs	= false,
> -	.irq_base	= IRQ_GPIO_END + 1,
>  
>  	.ignore_gpiodvs_side_effect = true,
>  	.buck125_default_idx = 0x0,
> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
> index 09274cf..00390a1 100644
> --- a/drivers/mfd/max8997-irq.c
> +++ b/drivers/mfd/max8997-irq.c
> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
>  static const inline struct max8997_irq_data *
>  irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
>  {
> -	return &max8997_irqs[irq - max8997->irq_base];
> +	struct irq_data *data = irq_get_irq_data(irq);
> +	return &max8997_irqs[data->hwirq];
>  }
>  
>  static void max8997_irq_mask(struct irq_data *data)
> @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  	u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
>  	u8 irq_src;
>  	int ret;
> -	int i;
> +	int i, cur_irq;
>  
>  	ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
>  	if (ret < 0) {
> @@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  	/* Report */
>  	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
> -			handle_nested_irq(max8997->irq_base + i);
> +		if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
> +			cur_irq = irq_find_mapping(max8997->irq_domain, i);
> +			if (cur_irq)
> +				handle_nested_irq(cur_irq);
> +		}
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
>  
>  int max8997_irq_resume(struct max8997_dev *max8997)
>  {
> -	if (max8997->irq && max8997->irq_base)
> -		max8997_irq_thread(max8997->irq_base, max8997);
> +	if (max8997->irq && max8997->irq_domain)
> +		max8997_irq_thread(0, max8997);
> +	return 0;
> +}
> +
> +static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
> +					irq_hw_number_t hw)
> +{
> +	struct max8997_dev *max8997 = d->host_data;
> +
> +	irq_set_chip_data(irq, max8997);
> +	irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
> +	irq_set_nested_thread(irq, 1);
> +#ifdef CONFIG_ARM
> +	set_irq_flags(irq, IRQF_VALID);
> +#else
> +	irq_set_noprobe(irq);
> +#endif
>  	return 0;
>  }
>  
> +static struct irq_domain_ops max8997_irq_domain_ops = {
> +	.map = max8997_irq_domain_map,
> +};
> +
>  int max8997_irq_init(struct max8997_dev *max8997)
>  {
> +	struct irq_domain *domain;
>  	int i;
> -	int cur_irq;
>  	int ret;
>  	u8 val;
>  
>  	if (!max8997->irq) {
>  		dev_warn(max8997->dev, "No interrupt specified.\n");
> -		max8997->irq_base = 0;
> -		return 0;
> -	}
> -
> -	if (!max8997->irq_base) {
> -		dev_err(max8997->dev, "No interrupt base specified.\n");
>  		return 0;
>  	}
>  
> @@ -327,18 +345,11 @@ int max8997_irq_init(struct max8997_dev *max8997)
>  					true : false;
>  	}
>  
> -	/* Register with genirq */
> -	for (i = 0; i < MAX8997_IRQ_NR; i++) {
> -		cur_irq = i + max8997->irq_base;
> -		irq_set_chip_data(cur_irq, max8997);
> -		irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
> -				handle_edge_irq);
> -		irq_set_nested_thread(cur_irq, 1);
> -#ifdef CONFIG_ARM
> -		set_irq_flags(cur_irq, IRQF_VALID);
> -#else
> -		irq_set_noprobe(cur_irq);
> -#endif
> +	domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
> +					&max8997_irq_domain_ops, &max8997);
> +	if (!domain) {
> +		dev_err(max8997->dev, "could not create irq domain\n");
> +		return -ENODEV;
>  	}
>  
>  	ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
> index cb83a7a..20ecad3 100644
> --- a/drivers/mfd/max8997.c
> +++ b/drivers/mfd/max8997.c
> @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
>  	if (!pdata)
>  		goto err;
>  
> -	max8997->irq_base = pdata->irq_base;
>  	max8997->ono = pdata->ono;
>  
>  	mutex_init(&max8997->iolock);
> diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
> index 3f4deb6..830152c 100644
> --- a/include/linux/mfd/max8997-private.h
> +++ b/include/linux/mfd/max8997-private.h
> @@ -23,6 +23,8 @@
>  #define __LINUX_MFD_MAX8997_PRIV_H
>  
>  #include <linux/i2c.h>
> +#include <linux/export.h>
> +#include <linux/irqdomain.h>
>  
>  #define MAX8997_REG_INVALID	(0xff)
>  
> @@ -325,7 +327,7 @@ struct max8997_dev {
>  
>  	int irq;
>  	int ono;
> -	int irq_base;
> +	struct irq_domain *irq_domain;
>  	struct mutex irqlock;
>  	int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
>  	int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
> diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
> index fff5905..818486c 100644
> --- a/include/linux/mfd/max8997.h
> +++ b/include/linux/mfd/max8997.h
> @@ -155,7 +155,6 @@ struct max8997_led_platform_data {
>  
>  struct max8997_platform_data {
>  	/* IRQ */
> -	int irq_base;
>  	int ono;
>  	int wakeup;
>  
> -- 
> 1.6.6.rc2
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120404/02f575f1/attachment-0001.sig>

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

* Re: [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
  2012-04-04 21:22     ` Mark Brown
@ 2012-04-16 15:32       ` Samuel Ortiz
  -1 siblings, 0 replies; 36+ messages in thread
From: Samuel Ortiz @ 2012-04-16 15:32 UTC (permalink / raw)
  To: Mark Brown
  Cc: Thomas Abraham, linux-kernel, k.lewandowsk, devicetree-discuss,
	rob.herring, grant.likely, kgene.kim, myungjoo.ham,
	kyungmin.park, linux-arm-kernel, linux-samsung-soc, patches

Hi Mark,

On Wed, Apr 04, 2012 at 10:22:57PM +0100, Mark Brown wrote:
> On Sat, Mar 24, 2012 at 03:19:49PM +0530, Thomas Abraham wrote:
> > Add irq domain support for max8997 interrupts. The reverse mapping method
> > used is linear mapping since the sub-drivers of max8997 such as regulator
> > and charger drivers can use the max8997 irq_domain to get the linux irq
> > number for max8997 interrupts. All uses of irq_base in platform data and
> > max8997 driver private data are removed.
> 
> > Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> > Acked-by: Grant Likely <grant.likely@secretlab.ca>
> 
> CCing in Samuel for the MFD review - review tends to be faster if you CC
> maintainers!  Samuel, there's a followup patch for the regulator API
> which is likely to collide with some API updates so is it OK to merge
> via regulator if the patch is OK?
Yes, the patch looks fine, you can merge it through the regulator tree with my

Acked-by: Samuel Ortiz <sameo@linux.intel.com>

if you think that's necessary.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-04-16 15:32       ` Samuel Ortiz
  0 siblings, 0 replies; 36+ messages in thread
From: Samuel Ortiz @ 2012-04-16 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On Wed, Apr 04, 2012 at 10:22:57PM +0100, Mark Brown wrote:
> On Sat, Mar 24, 2012 at 03:19:49PM +0530, Thomas Abraham wrote:
> > Add irq domain support for max8997 interrupts. The reverse mapping method
> > used is linear mapping since the sub-drivers of max8997 such as regulator
> > and charger drivers can use the max8997 irq_domain to get the linux irq
> > number for max8997 interrupts. All uses of irq_base in platform data and
> > max8997 driver private data are removed.
> 
> > Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
> > Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> > Acked-by: Grant Likely <grant.likely@secretlab.ca>
> 
> CCing in Samuel for the MFD review - review tends to be faster if you CC
> maintainers!  Samuel, there's a followup patch for the regulator API
> which is likely to collide with some API updates so is it OK to merge
> via regulator if the patch is OK?
Yes, the patch looks fine, you can merge it through the regulator tree with my

Acked-by: Samuel Ortiz <sameo@linux.intel.com>

if you think that's necessary.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

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

* Re: [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-04-16 18:47     ` Mark Brown
  -1 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-16 18:47 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: linux-kernel, k.lewandowsk, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches

[-- Attachment #1: Type: text/plain, Size: 426 bytes --]

On Sat, Mar 24, 2012 at 03:19:49PM +0530, Thomas Abraham wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-04-16 18:47     ` Mark Brown
  0 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-16 18:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 24, 2012 at 03:19:49PM +0530, Thomas Abraham wrote:
> Add irq domain support for max8997 interrupts. The reverse mapping method
> used is linear mapping since the sub-drivers of max8997 such as regulator
> and charger drivers can use the max8997 irq_domain to get the linux irq
> number for max8997 interrupts. All uses of irq_base in platform data and
> max8997 driver private data are removed.

Applied, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120416/05c3cb4d/attachment.sig>

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-03-24  9:49   ` Thomas Abraham
@ 2012-04-16 18:51     ` Mark Brown
  -1 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-16 18:51 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: linux-kernel, k.lewandowsk, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

[-- Attachment #1: Type: text/plain, Size: 422 bytes --]

On Sat, Mar 24, 2012 at 03:19:50PM +0530, Thomas Abraham wrote:
> Add device tree based discovery support for max8997.

I tried to apply this but it's collided with some other changes in the
driver which have arrived in the meantime and the rejects were too large
to fix up.  I suspect it's mostly just the change in parameters for
regulator_register().  Can you please regenerate against my current
topic/drivers branch?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-04-16 18:51     ` Mark Brown
  0 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-16 18:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 24, 2012 at 03:19:50PM +0530, Thomas Abraham wrote:
> Add device tree based discovery support for max8997.

I tried to apply this but it's collided with some other changes in the
driver which have arrived in the meantime and the rejects were too large
to fix up.  I suspect it's mostly just the change in parameters for
regulator_register().  Can you please regenerate against my current
topic/drivers branch?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120416/d0eff970/attachment.sig>

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-04-16 18:51     ` Mark Brown
@ 2012-04-16 18:56       ` Thomas Abraham
  -1 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-16 18:56 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-kernel, k.lewandowsk, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

On 17 April 2012 00:21, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> On Sat, Mar 24, 2012 at 03:19:50PM +0530, Thomas Abraham wrote:
>> Add device tree based discovery support for max8997.
>
> I tried to apply this but it's collided with some other changes in the
> driver which have arrived in the meantime and the rejects were too large
> to fix up.  I suspect it's mostly just the change in parameters for
> regulator_register().  Can you please regenerate against my current
> topic/drivers branch?

Hi Mark,

Sure, I will do redo this patch based on your current 'topic/drivers' branch.

Thanks,
Thomas.

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-04-16 18:56       ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-16 18:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 April 2012 00:21, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> On Sat, Mar 24, 2012 at 03:19:50PM +0530, Thomas Abraham wrote:
>> Add device tree based discovery support for max8997.
>
> I tried to apply this but it's collided with some other changes in the
> driver which have arrived in the meantime and the rejects were too large
> to fix up. ?I suspect it's mostly just the change in parameters for
> regulator_register(). ?Can you please regenerate against my current
> topic/drivers branch?

Hi Mark,

Sure, I will do redo this patch based on your current 'topic/drivers' branch.

Thanks,
Thomas.

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

* Re: [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
  2012-03-30 22:06     ` Grant Likely
@ 2012-04-17 18:11       ` Thomas Abraham
  -1 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-17 18:11 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, k.lewandowsk, devicetree-discuss, rob.herring,
	kgene.kim, broonie, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches

On 31 March 2012 03:36, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Sat, 24 Mar 2012 15:19:49 +0530, Thomas Abraham <thomas.abraham@linaro.org> wrote:
>> Add irq domain support for max8997 interrupts. The reverse mapping method
>> used is linear mapping since the sub-drivers of max8997 such as regulator
>> and charger drivers can use the max8997 irq_domain to get the linux irq
>> number for max8997 interrupts. All uses of irq_base in platform data and
>> max8997 driver private data are removed.
>>
>> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> Acked-by: Grant Likely <grant.likely@secretlab.ca>
>> ---
>>  arch/arm/mach-exynos/mach-nuri.c    |    4 --
>>  arch/arm/mach-exynos/mach-origen.c  |    1 -
>>  drivers/mfd/max8997-irq.c           |   61 ++++++++++++++++++++--------------
>>  drivers/mfd/max8997.c               |    1 -
>>  include/linux/mfd/max8997-private.h |    4 ++-
>>  include/linux/mfd/max8997.h         |    1 -
>>  6 files changed, 39 insertions(+), 33 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
>> index 7ac81ce..b21d85d 100644
>> --- a/arch/arm/mach-exynos/mach-nuri.c
>> +++ b/arch/arm/mach-exynos/mach-nuri.c
>> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
>>  static void __init nuri_power_init(void)
>>  {
>>       int gpio;
>> -     int irq_base = IRQ_GPIO_END + 1;
>>       int ta_en = 0;
>>
>> -     nuri_max8997_pdata.irq_base = irq_base;
>> -     irq_base += MAX8997_IRQ_NR;
>> -
>>       gpio = EXYNOS4_GPX0(7);
>>       gpio_request(gpio, "AP_PMIC_IRQ");
>>       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
>> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
>> index 827cb99..d3b2e9d 100644
>> --- a/arch/arm/mach-exynos/mach-origen.c
>> +++ b/arch/arm/mach-exynos/mach-origen.c
>> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
>>       .buck1_gpiodvs  = false,
>>       .buck2_gpiodvs  = false,
>>       .buck5_gpiodvs  = false,
>> -     .irq_base       = IRQ_GPIO_END + 1,
>>
>>       .ignore_gpiodvs_side_effect = true,
>>       .buck125_default_idx = 0x0,
>> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
>> index 09274cf..00390a1 100644
>> --- a/drivers/mfd/max8997-irq.c
>> +++ b/drivers/mfd/max8997-irq.c
>> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
>>  static const inline struct max8997_irq_data *
>>  irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
>>  {
>> -     return &max8997_irqs[irq - max8997->irq_base];
>> +     struct irq_data *data = irq_get_irq_data(irq);
>> +     return &max8997_irqs[data->hwirq];
>>  }
>
> Haha, this is kind of bogus now.  There are only two users of this
> function, and *both* of them already have the irq_data pointer.
> Instead of this, delete this function entirely and make each caller
> derefernce max8997_irqs directly:
>
>        const struct max8997_irq_data *irq_data = &max8997_irqs[data->hwirq];
>
> Otherwise, looks good.  After fixing you can add my:
>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

Hi Grant,

Thanks for the suggestion. I have modified the code accordingly and
included your ack.

Regards,
Thomas.

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

* [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts
@ 2012-04-17 18:11       ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-17 18:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 31 March 2012 03:36, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Sat, 24 Mar 2012 15:19:49 +0530, Thomas Abraham <thomas.abraham@linaro.org> wrote:
>> Add irq domain support for max8997 interrupts. The reverse mapping method
>> used is linear mapping since the sub-drivers of max8997 such as regulator
>> and charger drivers can use the max8997 irq_domain to get the linux irq
>> number for max8997 interrupts. All uses of irq_base in platform data and
>> max8997 driver private data are removed.
>>
>> Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
>> Acked-by: Grant Likely <grant.likely@secretlab.ca>
>> ---
>> ?arch/arm/mach-exynos/mach-nuri.c ? ?| ? ?4 --
>> ?arch/arm/mach-exynos/mach-origen.c ?| ? ?1 -
>> ?drivers/mfd/max8997-irq.c ? ? ? ? ? | ? 61 ++++++++++++++++++++--------------
>> ?drivers/mfd/max8997.c ? ? ? ? ? ? ? | ? ?1 -
>> ?include/linux/mfd/max8997-private.h | ? ?4 ++-
>> ?include/linux/mfd/max8997.h ? ? ? ? | ? ?1 -
>> ?6 files changed, 39 insertions(+), 33 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
>> index 7ac81ce..b21d85d 100644
>> --- a/arch/arm/mach-exynos/mach-nuri.c
>> +++ b/arch/arm/mach-exynos/mach-nuri.c
>> @@ -1077,12 +1077,8 @@ static struct platform_device nuri_max8903_device = {
>> ?static void __init nuri_power_init(void)
>> ?{
>> ? ? ? int gpio;
>> - ? ? int irq_base = IRQ_GPIO_END + 1;
>> ? ? ? int ta_en = 0;
>>
>> - ? ? nuri_max8997_pdata.irq_base = irq_base;
>> - ? ? irq_base += MAX8997_IRQ_NR;
>> -
>> ? ? ? gpio = EXYNOS4_GPX0(7);
>> ? ? ? gpio_request(gpio, "AP_PMIC_IRQ");
>> ? ? ? s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
>> diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
>> index 827cb99..d3b2e9d 100644
>> --- a/arch/arm/mach-exynos/mach-origen.c
>> +++ b/arch/arm/mach-exynos/mach-origen.c
>> @@ -424,7 +424,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
>> ? ? ? .buck1_gpiodvs ?= false,
>> ? ? ? .buck2_gpiodvs ?= false,
>> ? ? ? .buck5_gpiodvs ?= false,
>> - ? ? .irq_base ? ? ? = IRQ_GPIO_END + 1,
>>
>> ? ? ? .ignore_gpiodvs_side_effect = true,
>> ? ? ? .buck125_default_idx = 0x0,
>> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
>> index 09274cf..00390a1 100644
>> --- a/drivers/mfd/max8997-irq.c
>> +++ b/drivers/mfd/max8997-irq.c
>> @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
>> ?static const inline struct max8997_irq_data *
>> ?irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
>> ?{
>> - ? ? return &max8997_irqs[irq - max8997->irq_base];
>> + ? ? struct irq_data *data = irq_get_irq_data(irq);
>> + ? ? return &max8997_irqs[data->hwirq];
>> ?}
>
> Haha, this is kind of bogus now. ?There are only two users of this
> function, and *both* of them already have the irq_data pointer.
> Instead of this, delete this function entirely and make each caller
> derefernce max8997_irqs directly:
>
> ? ? ? ?const struct max8997_irq_data *irq_data = &max8997_irqs[data->hwirq];
>
> Otherwise, looks good. ?After fixing you can add my:
>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

Hi Grant,

Thanks for the suggestion. I have modified the code accordingly and
included your ack.

Regards,
Thomas.

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-03-28 17:03     ` Karol Lewandowski
@ 2012-04-17 18:35       ` Thomas Abraham
  -1 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-17 18:35 UTC (permalink / raw)
  To: Karol Lewandowski
  Cc: linux-kernel, devicetree-discuss, rob.herring, grant.likely,
	kgene.kim, broonie, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

On 28 March 2012 22:33, Karol Lewandowski <k.lewandowsk@samsung.com> wrote:
> On 24.03.2012 10:49, Thomas Abraham wrote:
>
> Hi Thomas!
>
>> Add device tree based discovery support for max8997.
> ...
>> +Regulators: The regulators of max8997 that have to be instantiated should be
>> +included in a sub-node named 'regulators'. Regulator nodes included in this
>> +sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
>> +represents the LDO or BUCK number as per the datasheet of max8997.
>> +
>> +    For LDO's:
>> +             LDOn {
>> +                     standard regulator bindings here
>> +             };
>> +
>> +    For BUCK's:
>> +             BUCKn {
>> +                     standard regulator bindings here
>> +             };
>> +
>
>
> Small note - driver supports[1] configuring following regulators by
> using respective DT node names:
>
>  - EN32KHz_AP
>  - EN32KHz_CP
>  - ENVICHG
>  - ESAFEOUT1
>  - ESAFEOUT2
>  - CHARGER
>  - CHARGER_CV
>  - CHARGER_TOPOFF
>
> I wonder if these should be mentioned in documentation too.
>
> [1] These are used in e.g. mach-nuri.c

Yes, I missed the above regulators in the documentation. I have
included them now and will resubmit this patch.

>
>> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c> index 9657929..dce8aaf 100644
>
>> --- a/drivers/regulator/max8997.c
>> +++ b/drivers/regulator/max8997.c
> ..
>> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
>> +                                     struct max8997_platform_data *pdata)
>> +{
>> +     struct device_node *pmic_np, *regulators_np, *reg_np;
>> +     struct max8997_regulator_data *rdata;
>> +     unsigned int i, dvs_voltage_nr = 1, ret;
>> +
>> +     pmic_np = iodev->dev->of_node;
>> +     if (!pmic_np) {
>> +             dev_err(iodev->dev, "could not find pmic sub-node\n");
>> +             return -ENODEV;
>> +     }
>> +
>> +     regulators_np = of_find_node_by_name(pmic_np, "regulators");
>> +     if (!regulators_np) {
>> +             dev_err(iodev->dev, "could not find regulators sub-node\n");
>> +             return -EINVAL;
>> +     }
>> +
>> +     /* count the number of regulators to be supported in pmic */
>> +     pdata->num_regulators = 0;
>> +     for_each_child_of_node(regulators_np, reg_np)
>> +             pdata->num_regulators++;
>> +
>> +     rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
>> +                             pdata->num_regulators, GFP_KERNEL);
>> +     if (!rdata) {
>> +             dev_err(iodev->dev, "could not allocate memory for "
>> +                                             "regulator data\n");
>> +             return -ENOMEM;
>> +     }
>
>> +     pdata->regulators = rdata;
>
>> +     for_each_child_of_node(regulators_np, reg_np) {
>> +             for (i = 0; i < ARRAY_SIZE(regulators); i++)
>> +                     if (!of_node_cmp(reg_np->name, regulators[i].name))
>> +                             break;
>> +             rdata->id = i;
>
>
> rdata->id will be equal to ARRAY_SIZE(regulators) when one adds DT node
> name (below "regulators") which is different from what can be found in
> regulators[] table.
>
> On my test machine this results in hard lockup - possibly because
> something tries to access regulators[ARRAY_SIZE(regulators)]
> later on.
>
> Following patch fixes this on my machine (using DTS with misspelled LDO1 for LDx1):
>
> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
> index dce8aaf..c20fd72 100644
> --- a/drivers/regulator/max8997.c
> +++ b/drivers/regulator/max8997.c
> @@ -1011,6 +1011,13 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
>                for (i = 0; i < ARRAY_SIZE(regulators); i++)
>                        if (!of_node_cmp(reg_np->name, regulators[i].name))
>                                break;
> +
> +               if (i == ARRAY_SIZE(regulators)) {
> +                       dev_warn(iodev->dev, "don't know how to configure regulator %s\n",
> +                                reg_np->name);
> +                       continue;
> +               }
> +
>                rdata->id = i;
>                rdata->initdata = of_get_regulator_init_data(
>                                                iodev->dev, reg_np);
>

Thanks for this fix. I have merged this change into this patch.

Regards,
Thomas.

>
> Regards,
> --
> Karol Lewandowski | Samsung Poland R&D Center | Linux/Platform

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-04-17 18:35       ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-17 18:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 28 March 2012 22:33, Karol Lewandowski <k.lewandowsk@samsung.com> wrote:
> On 24.03.2012 10:49, Thomas Abraham wrote:
>
> Hi Thomas!
>
>> Add device tree based discovery support for max8997.
> ...
>> +Regulators: The regulators of max8997 that have to be instantiated should be
>> +included in a sub-node named 'regulators'. Regulator nodes included in this
>> +sub-node should be of the format as below. Note: The 'n' in LDOn and BUCKn
>> +represents the LDO or BUCK number as per the datasheet of max8997.
>> +
>> + ? ?For LDO's:
>> + ? ? ? ? ? ? LDOn {
>> + ? ? ? ? ? ? ? ? ? ? standard regulator bindings here
>> + ? ? ? ? ? ? };
>> +
>> + ? ?For BUCK's:
>> + ? ? ? ? ? ? BUCKn {
>> + ? ? ? ? ? ? ? ? ? ? standard regulator bindings here
>> + ? ? ? ? ? ? };
>> +
>
>
> Small note - driver supports[1] configuring following regulators by
> using respective DT node names:
>
> ?- EN32KHz_AP
> ?- EN32KHz_CP
> ?- ENVICHG
> ?- ESAFEOUT1
> ?- ESAFEOUT2
> ?- CHARGER
> ?- CHARGER_CV
> ?- CHARGER_TOPOFF
>
> I wonder if these should be mentioned in documentation too.
>
> [1] These are used in e.g. mach-nuri.c

Yes, I missed the above regulators in the documentation. I have
included them now and will resubmit this patch.

>
>> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c> index 9657929..dce8aaf 100644
>
>> --- a/drivers/regulator/max8997.c
>> +++ b/drivers/regulator/max8997.c
> ..
>> +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct max8997_platform_data *pdata)
>> +{
>> + ? ? struct device_node *pmic_np, *regulators_np, *reg_np;
>> + ? ? struct max8997_regulator_data *rdata;
>> + ? ? unsigned int i, dvs_voltage_nr = 1, ret;
>> +
>> + ? ? pmic_np = iodev->dev->of_node;
>> + ? ? if (!pmic_np) {
>> + ? ? ? ? ? ? dev_err(iodev->dev, "could not find pmic sub-node\n");
>> + ? ? ? ? ? ? return -ENODEV;
>> + ? ? }
>> +
>> + ? ? regulators_np = of_find_node_by_name(pmic_np, "regulators");
>> + ? ? if (!regulators_np) {
>> + ? ? ? ? ? ? dev_err(iodev->dev, "could not find regulators sub-node\n");
>> + ? ? ? ? ? ? return -EINVAL;
>> + ? ? }
>> +
>> + ? ? /* count the number of regulators to be supported in pmic */
>> + ? ? pdata->num_regulators = 0;
>> + ? ? for_each_child_of_node(regulators_np, reg_np)
>> + ? ? ? ? ? ? pdata->num_regulators++;
>> +
>> + ? ? rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata->num_regulators, GFP_KERNEL);
>> + ? ? if (!rdata) {
>> + ? ? ? ? ? ? dev_err(iodev->dev, "could not allocate memory for "
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "regulator data\n");
>> + ? ? ? ? ? ? return -ENOMEM;
>> + ? ? }
>
>> + ? ? pdata->regulators = rdata;
>
>> + ? ? for_each_child_of_node(regulators_np, reg_np) {
>> + ? ? ? ? ? ? for (i = 0; i < ARRAY_SIZE(regulators); i++)
>> + ? ? ? ? ? ? ? ? ? ? if (!of_node_cmp(reg_np->name, regulators[i].name))
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
>> + ? ? ? ? ? ? rdata->id = i;
>
>
> rdata->id will be equal to ARRAY_SIZE(regulators) when one adds DT node
> name (below "regulators") which is different from what can be found in
> regulators[] table.
>
> On my test machine this results in hard lockup - possibly because
> something tries to access regulators[ARRAY_SIZE(regulators)]
> later on.
>
> Following patch fixes this on my machine (using DTS with misspelled LDO1 for LDx1):
>
> diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
> index dce8aaf..c20fd72 100644
> --- a/drivers/regulator/max8997.c
> +++ b/drivers/regulator/max8997.c
> @@ -1011,6 +1011,13 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
> ? ? ? ? ? ? ? ?for (i = 0; i < ARRAY_SIZE(regulators); i++)
> ? ? ? ? ? ? ? ? ? ? ? ?if (!of_node_cmp(reg_np->name, regulators[i].name))
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
> +
> + ? ? ? ? ? ? ? if (i == ARRAY_SIZE(regulators)) {
> + ? ? ? ? ? ? ? ? ? ? ? dev_warn(iodev->dev, "don't know how to configure regulator %s\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?reg_np->name);
> + ? ? ? ? ? ? ? ? ? ? ? continue;
> + ? ? ? ? ? ? ? }
> +
> ? ? ? ? ? ? ? ?rdata->id = i;
> ? ? ? ? ? ? ? ?rdata->initdata = of_get_regulator_init_data(
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?iodev->dev, reg_np);
>

Thanks for this fix. I have merged this change into this patch.

Regards,
Thomas.

>
> Regards,
> --
> Karol Lewandowski | Samsung Poland R&D Center | Linux/Platform

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-04-17 18:35       ` Thomas Abraham
@ 2012-04-17 18:38         ` Mark Brown
  -1 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-17 18:38 UTC (permalink / raw)
  To: Thomas Abraham
  Cc: Karol Lewandowski, linux-kernel, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

[-- Attachment #1: Type: text/plain, Size: 694 bytes --]

On Wed, Apr 18, 2012 at 12:05:59AM +0530, Thomas Abraham wrote:
> On 28 March 2012 22:33, Karol Lewandowski <k.lewandowsk@samsung.com> wrote:

> >> +    For BUCK's:

No 's here, BTW.

> >  - EN32KHz_AP
> >  - EN32KHz_CP
> >  - ENVICHG
> >  - ESAFEOUT1
> >  - ESAFEOUT2
> >  - CHARGER
> >  - CHARGER_CV
> >  - CHARGER_TOPOFF

> > I wonder if these should be mentioned in documentation too.

> Yes, I missed the above regulators in the documentation. I have
> included them now and will resubmit this patch.

Please omit the clocks; these are obviously a bodge due to the inability
to support clocks off-SoC so we shouldn't be enshrining them in the
device tree bindings.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-04-17 18:38         ` Mark Brown
  0 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2012-04-17 18:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 18, 2012 at 12:05:59AM +0530, Thomas Abraham wrote:
> On 28 March 2012 22:33, Karol Lewandowski <k.lewandowsk@samsung.com> wrote:

> >> + ? ?For BUCK's:

No 's here, BTW.

> > ?- EN32KHz_AP
> > ?- EN32KHz_CP
> > ?- ENVICHG
> > ?- ESAFEOUT1
> > ?- ESAFEOUT2
> > ?- CHARGER
> > ?- CHARGER_CV
> > ?- CHARGER_TOPOFF

> > I wonder if these should be mentioned in documentation too.

> Yes, I missed the above regulators in the documentation. I have
> included them now and will resubmit this patch.

Please omit the clocks; these are obviously a bodge due to the inability
to support clocks off-SoC so we shouldn't be enshrining them in the
device tree bindings.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120417/9df2abff/attachment-0001.sig>

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

* Re: [PATCH v4 2/2] regulator: add device tree support for max8997
  2012-04-17 18:38         ` Mark Brown
@ 2012-04-18  8:16           ` Thomas Abraham
  -1 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-18  8:16 UTC (permalink / raw)
  To: Mark Brown
  Cc: Karol Lewandowski, linux-kernel, devicetree-discuss, rob.herring,
	grant.likely, kgene.kim, myungjoo.ham, kyungmin.park,
	linux-arm-kernel, linux-samsung-soc, patches, Rajendra Nayak

Hi Mark,

On 18 April 2012 00:08, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> On Wed, Apr 18, 2012 at 12:05:59AM +0530, Thomas Abraham wrote:
>> On 28 March 2012 22:33, Karol Lewandowski <k.lewandowsk@samsung.com> wrote:
>
>> >> +    For BUCK's:
>
> No 's here, BTW.

Ok.

>
>> >  - EN32KHz_AP
>> >  - EN32KHz_CP
>> >  - ENVICHG
>> >  - ESAFEOUT1
>> >  - ESAFEOUT2
>> >  - CHARGER
>> >  - CHARGER_CV
>> >  - CHARGER_TOPOFF
>
>> > I wonder if these should be mentioned in documentation too.
>
>> Yes, I missed the above regulators in the documentation. I have
>> included them now and will resubmit this patch.
>
> Please omit the clocks; these are obviously a bodge due to the inability
> to support clocks off-SoC so we shouldn't be enshrining them in the
> device tree bindings.

Thanks for the suggestion. I have removed EN32KHz_AP and EN32KHz_CP
from the list. The rest are either voltage (fixed) or current
regulators.

Regards,
Thomas.

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

* [PATCH v4 2/2] regulator: add device tree support for max8997
@ 2012-04-18  8:16           ` Thomas Abraham
  0 siblings, 0 replies; 36+ messages in thread
From: Thomas Abraham @ 2012-04-18  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On 18 April 2012 00:08, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> On Wed, Apr 18, 2012 at 12:05:59AM +0530, Thomas Abraham wrote:
>> On 28 March 2012 22:33, Karol Lewandowski <k.lewandowsk@samsung.com> wrote:
>
>> >> + ? ?For BUCK's:
>
> No 's here, BTW.

Ok.

>
>> > ?- EN32KHz_AP
>> > ?- EN32KHz_CP
>> > ?- ENVICHG
>> > ?- ESAFEOUT1
>> > ?- ESAFEOUT2
>> > ?- CHARGER
>> > ?- CHARGER_CV
>> > ?- CHARGER_TOPOFF
>
>> > I wonder if these should be mentioned in documentation too.
>
>> Yes, I missed the above regulators in the documentation. I have
>> included them now and will resubmit this patch.
>
> Please omit the clocks; these are obviously a bodge due to the inability
> to support clocks off-SoC so we shouldn't be enshrining them in the
> device tree bindings.

Thanks for the suggestion. I have removed EN32KHz_AP and EN32KHz_CP
from the list. The rest are either voltage (fixed) or current
regulators.

Regards,
Thomas.

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

end of thread, other threads:[~2012-04-18  8:17 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-24  9:49 [PATCH v4 0/2] regulator: add irq domain and device tree support for MAX8997 Thomas Abraham
2012-03-24  9:49 ` Thomas Abraham
2012-03-24  9:49 ` Thomas Abraham
2012-03-24  9:49 ` [PATCH v4 1/2] mfd: add irq domain support for max8997 interrupts Thomas Abraham
2012-03-24  9:49   ` Thomas Abraham
2012-03-24  9:49   ` Thomas Abraham
2012-03-26 12:20   ` MyungJoo Ham
2012-03-26 12:20     ` MyungJoo Ham
2012-03-30 22:06   ` Grant Likely
2012-03-30 22:06     ` Grant Likely
2012-04-17 18:11     ` Thomas Abraham
2012-04-17 18:11       ` Thomas Abraham
2012-04-04 21:22   ` Mark Brown
2012-04-04 21:22     ` Mark Brown
2012-04-16 15:32     ` Samuel Ortiz
2012-04-16 15:32       ` Samuel Ortiz
2012-04-16 18:47   ` Mark Brown
2012-04-16 18:47     ` Mark Brown
2012-03-24  9:49 ` [PATCH v4 2/2] regulator: add device tree support for max8997 Thomas Abraham
2012-03-24  9:49   ` Thomas Abraham
2012-03-27  6:40   ` MyungJoo Ham
2012-03-27  6:40     ` MyungJoo Ham
2012-03-28 17:03   ` Karol Lewandowski
2012-03-28 17:03     ` Karol Lewandowski
2012-04-17 18:35     ` Thomas Abraham
2012-04-17 18:35       ` Thomas Abraham
2012-04-17 18:38       ` Mark Brown
2012-04-17 18:38         ` Mark Brown
2012-04-18  8:16         ` Thomas Abraham
2012-04-18  8:16           ` Thomas Abraham
2012-03-30 22:09   ` Grant Likely
2012-03-30 22:09     ` Grant Likely
2012-04-16 18:51   ` Mark Brown
2012-04-16 18:51     ` Mark Brown
2012-04-16 18:56     ` Thomas Abraham
2012-04-16 18:56       ` Thomas Abraham

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.