public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] mfd: tps65910: use regmap irq framework for interrupt
@ 2012-10-09 11:28 Laxman Dewangan
  2012-10-09 11:28 ` [PATCH 1/5] mfd: tps65910: use regmap irq framework for interrupt support Laxman Dewangan
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Laxman Dewangan @ 2012-10-09 11:28 UTC (permalink / raw)
  To: broonie, gregkh, sameo; +Cc: swarren, linux-kernel, Laxman Dewangan

This patch series has following change:
- Use regmap irq framework for interrupt registration. Corrected the
  register bit definition for interrupts.
- Move the irq table to tps65910.c and get rid of tps65910-irq.c.
- Raarrange the init sequence of different sub moduled of tps65910 like
  irq, clock and then mfd devices.
- Export the irq domain handle from regmap to use in mfd driver.
- Pass the irq domain in mfd_add_devices to have proper interrupt mapping
  for sub devices like RTC.

Laxman Dewangan (5):
  mfd: tps65910: use regmap irq framework for interrupt support
  mfd: tps65910: move interrupt implementation code to mfd file
  mfd: tps65910: Initialize mfd devices after all initialization done
  regmap: add API to get irq_domain from regmap irq
  mfd: tps65910: pass irq_domain when adding mfd sub devices

 drivers/base/regmap/regmap-irq.c |   16 +++
 drivers/mfd/Makefile             |    2 +-
 drivers/mfd/tps65910-irq.c       |  260 --------------------------------------
 drivers/mfd/tps65910.c           |  235 +++++++++++++++++++++++++++++++++--
 include/linux/mfd/tps65910.h     |  143 +++++++++++++++-------
 include/linux/regmap.h           |    1 +
 6 files changed, 343 insertions(+), 314 deletions(-)
 delete mode 100644 drivers/mfd/tps65910-irq.c


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

* [PATCH 1/5] mfd: tps65910: use regmap irq framework for interrupt support
  2012-10-09 11:28 [PATCH 0/5] mfd: tps65910: use regmap irq framework for interrupt Laxman Dewangan
@ 2012-10-09 11:28 ` Laxman Dewangan
  2012-10-10  3:07   ` Mark Brown
  2012-10-09 11:28 ` [PATCH 2/5] mfd: tps65910: move interrupt implementation code to mfd file Laxman Dewangan
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Laxman Dewangan @ 2012-10-09 11:28 UTC (permalink / raw)
  To: broonie, gregkh, sameo; +Cc: swarren, linux-kernel, Laxman Dewangan

Implement irq support of tps65910 with regmap irq framework
in place of implementing locally.
This reduces the code size significantly and easy to maintain.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
 drivers/mfd/tps65910-irq.c   |  375 ++++++++++++++++++++----------------------
 include/linux/mfd/tps65910.h |  139 +++++++++++-----
 2 files changed, 278 insertions(+), 236 deletions(-)

diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c
index 09aab3e..554543a 100644
--- a/drivers/mfd/tps65910-irq.c
+++ b/drivers/mfd/tps65910-irq.c
@@ -24,171 +24,184 @@
 #include <linux/gpio.h>
 #include <linux/mfd/tps65910.h>
 
-/*
- * This is a threaded IRQ handler so can access I2C/SPI.  Since all
- * interrupts are clear on read the IRQ line will be reasserted and
- * the physical IRQ will be handled again if another interrupt is
- * asserted while we run - in the normal course of events this is a
- * rare occurrence so we save I2C/SPI reads.  We're also assuming that
- * it's rare to get lots of interrupts firing simultaneously so try to
- * minimise I/O.
- */
-static irqreturn_t tps65910_irq(int irq, void *irq_data)
-{
-	struct tps65910 *tps65910 = irq_data;
-	unsigned int reg;
-	u32 irq_sts;
-	u32 irq_mask;
-	int i;
-
-	tps65910_reg_read(tps65910, TPS65910_INT_STS, &reg);
-	irq_sts = reg;
-	tps65910_reg_read(tps65910, TPS65910_INT_STS2, &reg);
-	irq_sts |= reg << 8;
-	switch (tps65910_chip_id(tps65910)) {
-	case TPS65911:
-		tps65910_reg_read(tps65910, TPS65910_INT_STS3, &reg);
-		irq_sts |= reg << 16;
-	}
-
-	tps65910_reg_read(tps65910, TPS65910_INT_MSK, &reg);
-	irq_mask = reg;
-	tps65910_reg_read(tps65910, TPS65910_INT_MSK2, &reg);
-	irq_mask |= reg << 8;
-	switch (tps65910_chip_id(tps65910)) {
-	case TPS65911:
-		tps65910_reg_read(tps65910, TPS65910_INT_MSK3, &reg);
-		irq_mask |= reg << 16;
-	}
-
-	irq_sts &= ~irq_mask;
-
-	if (!irq_sts)
-		return IRQ_NONE;
-
-	for (i = 0; i < tps65910->irq_num; i++) {
-
-		if (!(irq_sts & (1 << i)))
-			continue;
-
-		handle_nested_irq(irq_find_mapping(tps65910->domain, i));
-	}
-
-	/* Write the STS register back to clear IRQs we handled */
-	reg = irq_sts & 0xFF;
-	irq_sts >>= 8;
-	tps65910_reg_write(tps65910, TPS65910_INT_STS, reg);
-	reg = irq_sts & 0xFF;
-	tps65910_reg_write(tps65910, TPS65910_INT_STS2, reg);
-	switch (tps65910_chip_id(tps65910)) {
-	case TPS65911:
-		reg = irq_sts >> 8;
-		tps65910_reg_write(tps65910, TPS65910_INT_STS3, reg);
-	}
-
-	return IRQ_HANDLED;
-}
-
-static void tps65910_irq_lock(struct irq_data *data)
-{
-	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
-
-	mutex_lock(&tps65910->irq_lock);
-}
-
-static void tps65910_irq_sync_unlock(struct irq_data *data)
-{
-	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
-	u32 reg_mask;
-	unsigned int reg;
-
-	tps65910_reg_read(tps65910, TPS65910_INT_MSK, &reg);
-	reg_mask = reg;
-	tps65910_reg_read(tps65910, TPS65910_INT_MSK2, &reg);
-	reg_mask |= reg << 8;
-	switch (tps65910_chip_id(tps65910)) {
-	case TPS65911:
-		tps65910_reg_read(tps65910, TPS65910_INT_MSK3, &reg);
-		reg_mask |= reg << 16;
-	}
 
-	if (tps65910->irq_mask != reg_mask) {
-		reg = tps65910->irq_mask & 0xFF;
-		tps65910_reg_write(tps65910, TPS65910_INT_MSK, reg);
-		reg = tps65910->irq_mask >> 8 & 0xFF;
-		tps65910_reg_write(tps65910, TPS65910_INT_MSK2, reg);
-		switch (tps65910_chip_id(tps65910)) {
-		case TPS65911:
-			reg = tps65910->irq_mask >> 16;
-			tps65910_reg_write(tps65910, TPS65910_INT_MSK3, reg);
-		}
-	}
-	mutex_unlock(&tps65910->irq_lock);
-}
-
-static void tps65910_irq_enable(struct irq_data *data)
-{
-	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
-
-	tps65910->irq_mask &= ~(1 << data->hwirq);
-}
-
-static void tps65910_irq_disable(struct irq_data *data)
-{
-	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
-
-	tps65910->irq_mask |= (1 << data->hwirq);
-}
+static const struct regmap_irq tps65911_irqs[] = {
+	/* INT_STS */
+	[TPS65911_IRQ_PWRHOLD_F] = {
+		.mask = INT_MSK_PWRHOLD_F_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_VBAT_VMHI] = {
+		.mask = INT_MSK_VMBHI_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_PWRON] = {
+		.mask = INT_MSK_PWRON_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_PWRON_LP] = {
+		.mask = INT_MSK_PWRON_LP_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_PWRHOLD_R] = {
+		.mask = INT_MSK_PWRHOLD_R_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_HOTDIE] = {
+		.mask = INT_MSK_HOTDIE_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_RTC_ALARM] = {
+		.mask = INT_MSK_RTC_ALARM_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_RTC_PERIOD] = {
+		.mask = INT_MSK_RTC_PERIOD_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+
+	/* INT_STS2 */
+	[TPS65911_IRQ_GPIO0_R] = {
+		.mask = INT_MSK2_GPIO0_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO0_F] = {
+		.mask = INT_MSK2_GPIO0_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO1_R] = {
+		.mask = INT_MSK2_GPIO1_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO1_F] = {
+		.mask = INT_MSK2_GPIO1_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO2_R] = {
+		.mask = INT_MSK2_GPIO2_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO2_F] = {
+		.mask = INT_MSK2_GPIO2_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO3_R] = {
+		.mask = INT_MSK2_GPIO3_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO3_F] = {
+		.mask = INT_MSK2_GPIO3_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+
+	/* INT_STS3 */
+	[TPS65911_IRQ_GPIO4_R] = {
+		.mask = INT_MSK3_GPIO4_R_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_GPIO4_F] = {
+		.mask = INT_MSK3_GPIO4_F_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_GPIO5_R] = {
+		.mask = INT_MSK3_GPIO5_R_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_GPIO5_F] = {
+		.mask = INT_MSK3_GPIO5_F_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_WTCHDG] = {
+		.mask = INT_MSK3_WTCHDG_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_VMBCH2_H] = {
+		.mask = INT_MSK3_VMBCH2_H_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_VMBCH2_L] = {
+		.mask = INT_MSK3_VMBCH2_L_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_PWRDN] = {
+		.mask = INT_MSK3_PWRDN_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+};
 
-#ifdef CONFIG_PM_SLEEP
-static int tps65910_irq_set_wake(struct irq_data *data, unsigned int enable)
-{
-	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
-	return irq_set_irq_wake(tps65910->chip_irq, enable);
-}
-#else
-#define tps65910_irq_set_wake NULL
-#endif
+static const struct regmap_irq tps65910_irqs[] = {
+	/* INT_STS */
+	[TPS65910_IRQ_VBAT_VMBDCH] = {
+		.mask = TPS65910_INT_MSK_VMBDCH_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_VBAT_VMHI] = {
+		.mask = TPS65910_INT_MSK_VMBHI_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_PWRON] = {
+		.mask = TPS65910_INT_MSK_PWRON_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_PWRON_LP] = {
+		.mask = TPS65910_INT_MSK_PWRON_LP_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_PWRHOLD] = {
+		.mask = TPS65910_INT_MSK_PWRHOLD_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_HOTDIE] = {
+		.mask = TPS65910_INT_MSK_HOTDIE_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_RTC_ALARM] = {
+		.mask = TPS65910_INT_MSK_RTC_ALARM_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_RTC_PERIOD] = {
+		.mask = TPS65910_INT_MSK_RTC_PERIOD_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+
+	/* INT_STS2 */
+	[TPS65910_IRQ_GPIO_R] = {
+		.mask = TPS65910_INT_MSK2_GPIO0_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65910_IRQ_GPIO_F] = {
+		.mask = TPS65910_INT_MSK2_GPIO0_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+};
 
-static struct irq_chip tps65910_irq_chip = {
+static struct regmap_irq_chip tps65911_irq_chip = {
 	.name = "tps65910",
-	.irq_bus_lock = tps65910_irq_lock,
-	.irq_bus_sync_unlock = tps65910_irq_sync_unlock,
-	.irq_disable = tps65910_irq_disable,
-	.irq_enable = tps65910_irq_enable,
-	.irq_set_wake = tps65910_irq_set_wake,
+	.irqs = tps65911_irqs,
+	.num_irqs = ARRAY_SIZE(tps65911_irqs),
+	.num_regs = 3,
+	.irq_reg_stride = 2,
+	.status_base = TPS65910_INT_STS,
+	.mask_base = TPS65910_INT_MSK,
+	.ack_base = TPS65910_INT_MSK,
 };
 
-static int tps65910_irq_map(struct irq_domain *h, unsigned int virq,
-				irq_hw_number_t hw)
-{
-	struct tps65910 *tps65910 = h->host_data;
-
-	irq_set_chip_data(virq, tps65910);
-	irq_set_chip_and_handler(virq, &tps65910_irq_chip, handle_edge_irq);
-	irq_set_nested_thread(virq, 1);
-
-	/* ARM needs us to explicitly flag the IRQ as valid
-	 * and will set them noprobe when we do so. */
-#ifdef CONFIG_ARM
-	set_irq_flags(virq, IRQF_VALID);
-#else
-	irq_set_noprobe(virq);
-#endif
-
-	return 0;
-}
-
-static struct irq_domain_ops tps65910_domain_ops = {
-	.map	= tps65910_irq_map,
-	.xlate	= irq_domain_xlate_twocell,
+static struct regmap_irq_chip tps65910_irq_chip = {
+	.name = "tps65910",
+	.irqs = tps65910_irqs,
+	.num_irqs = ARRAY_SIZE(tps65910_irqs),
+	.num_regs = 2,
+	.irq_reg_stride = 2,
+	.status_base = TPS65910_INT_STS,
+	.mask_base = TPS65910_INT_MSK,
+	.ack_base = TPS65910_INT_MSK,
 };
 
 int tps65910_irq_init(struct tps65910 *tps65910, int irq,
 		    struct tps65910_platform_data *pdata)
 {
-	int ret;
-	int flags = IRQF_ONESHOT;
+	int ret = 0;
+	static struct regmap_irq_chip *tps6591x_irqs_chip;
 
 	if (!irq) {
 		dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
@@ -200,61 +213,31 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq,
 		return -EINVAL;
 	}
 
+
 	switch (tps65910_chip_id(tps65910)) {
 	case TPS65910:
-		tps65910->irq_num = TPS65910_NUM_IRQ;
+		tps6591x_irqs_chip = &tps65910_irq_chip;
 		break;
 	case TPS65911:
-		tps65910->irq_num = TPS65911_NUM_IRQ;
+		tps6591x_irqs_chip = &tps65911_irq_chip;
 		break;
 	}
 
-	if (pdata->irq_base > 0) {
-		pdata->irq_base = irq_alloc_descs(pdata->irq_base, 0,
-					tps65910->irq_num, -1);
-		if (pdata->irq_base < 0) {
-			dev_warn(tps65910->dev, "Failed to alloc IRQs: %d\n",
-					pdata->irq_base);
-			return pdata->irq_base;
-		}
-	}
-
-	tps65910->irq_mask = 0xFFFFFF;
-
-	mutex_init(&tps65910->irq_lock);
 	tps65910->chip_irq = irq;
-	tps65910->irq_base = pdata->irq_base;
-
-	if (pdata->irq_base > 0)
-		tps65910->domain = irq_domain_add_legacy(tps65910->dev->of_node,
-					tps65910->irq_num,
-					pdata->irq_base,
-					0,
-					&tps65910_domain_ops, tps65910);
-	else
-		tps65910->domain = irq_domain_add_linear(tps65910->dev->of_node,
-					tps65910->irq_num,
-					&tps65910_domain_ops, tps65910);
-
-	if (!tps65910->domain) {
-		dev_err(tps65910->dev, "Failed to create IRQ domain\n");
-		return -ENOMEM;
+	ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
+		IRQF_ONESHOT, pdata->irq_base,
+		tps6591x_irqs_chip, &tps65910->irq_data);
+	if (ret < 0) {
+		dev_warn(tps65910->dev,
+				"Failed to add irq_chip %d\n", ret);
+		return ret;
 	}
-
-	ret = request_threaded_irq(irq, NULL, tps65910_irq, flags,
-				   "tps65910", tps65910);
-
-	irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
-
-	if (ret != 0)
-		dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret);
-
 	return ret;
 }
 
 int tps65910_irq_exit(struct tps65910 *tps65910)
 {
-	if (tps65910->chip_irq)
-		free_irq(tps65910->chip_irq, tps65910);
+	if (tps65910->chip_irq > 0)
+		regmap_del_irq_chip(tps65910->chip_irq, tps65910->irq_data);
 	return 0;
 }
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
index 02e894f..b564ac2 100644
--- a/include/linux/mfd/tps65910.h
+++ b/include/linux/mfd/tps65910.h
@@ -572,6 +572,49 @@
 #define SPARE_SPARE_MASK				0xFF
 #define SPARE_SPARE_SHIFT				0
 
+#define TPS65910_INT_STS_RTC_PERIOD_IT_MASK			0x80
+#define TPS65910_INT_STS_RTC_PERIOD_IT_SHIFT			7
+#define TPS65910_INT_STS_RTC_ALARM_IT_MASK			0x40
+#define TPS65910_INT_STS_RTC_ALARM_IT_SHIFT			6
+#define TPS65910_INT_STS_HOTDIE_IT_MASK				0x20
+#define TPS65910_INT_STS_HOTDIE_IT_SHIFT			5
+#define TPS65910_INT_STS_PWRHOLD_F_IT_MASK			0x10
+#define TPS65910_INT_STS_PWRHOLD_F_IT_SHIFT			4
+#define TPS65910_INT_STS_PWRON_LP_IT_MASK			0x08
+#define TPS65910_INT_STS_PWRON_LP_IT_SHIFT			3
+#define TPS65910_INT_STS_PWRON_IT_MASK				0x04
+#define TPS65910_INT_STS_PWRON_IT_SHIFT				2
+#define TPS65910_INT_STS_VMBHI_IT_MASK				0x02
+#define TPS65910_INT_STS_VMBHI_IT_SHIFT				1
+#define TPS65910_INT_STS_VMBDCH_IT_MASK				0x01
+#define TPS65910_INT_STS_VMBDCH_IT_SHIFT			0
+
+#define TPS65910_INT_MSK_RTC_PERIOD_IT_MSK_MASK			0x80
+#define TPS65910_INT_MSK_RTC_PERIOD_IT_MSK_SHIFT		7
+#define TPS65910_INT_MSK_RTC_ALARM_IT_MSK_MASK			0x40
+#define TPS65910_INT_MSK_RTC_ALARM_IT_MSK_SHIFT			6
+#define TPS65910_INT_MSK_HOTDIE_IT_MSK_MASK			0x20
+#define TPS65910_INT_MSK_HOTDIE_IT_MSK_SHIFT			5
+#define TPS65910_INT_MSK_PWRHOLD_IT_MSK_MASK			0x10
+#define TPS65910_INT_MSK_PWRHOLD_IT_MSK_SHIFT			4
+#define TPS65910_INT_MSK_PWRON_LP_IT_MSK_MASK			0x08
+#define TPS65910_INT_MSK_PWRON_LP_IT_MSK_SHIFT			3
+#define TPS65910_INT_MSK_PWRON_IT_MSK_MASK			0x04
+#define TPS65910_INT_MSK_PWRON_IT_MSK_SHIFT			2
+#define TPS65910_INT_MSK_VMBHI_IT_MSK_MASK			0x02
+#define TPS65910_INT_MSK_VMBHI_IT_MSK_SHIFT			1
+#define TPS65910_INT_MSK_VMBDCH_IT_MSK_MASK			0x01
+#define TPS65910_INT_MSK_VMBDCH_IT_MSK_SHIFT			0
+
+#define TPS65910_INT_STS2_GPIO0_F_IT_SHIFT			2
+#define TPS65910_INT_STS2_GPIO0_F_IT_MASK			0x02
+#define TPS65910_INT_STS2_GPIO0_R_IT_SHIFT			1
+#define TPS65910_INT_STS2_GPIO0_R_IT_MASK			0x01
+
+#define TPS65910_INT_MSK2_GPIO0_F_IT_MSK_SHIFT			2
+#define TPS65910_INT_MSK2_GPIO0_F_IT_MSK_MASK			0x02
+#define TPS65910_INT_MSK2_GPIO0_R_IT_MSK_SHIFT			1
+#define TPS65910_INT_MSK2_GPIO0_R_IT_MSK_MASK			0x01
 
 /*Register INT_STS  (0x80) register.RegisterDescription */
 #define INT_STS_RTC_PERIOD_IT_MASK			0x80
@@ -580,16 +623,16 @@
 #define INT_STS_RTC_ALARM_IT_SHIFT			6
 #define INT_STS_HOTDIE_IT_MASK				0x20
 #define INT_STS_HOTDIE_IT_SHIFT				5
-#define INT_STS_PWRHOLD_IT_MASK				0x10
-#define INT_STS_PWRHOLD_IT_SHIFT			4
+#define INT_STS_PWRHOLD_R_IT_MASK			0x10
+#define INT_STS_PWRHOLD_R_IT_SHIFT			4
 #define INT_STS_PWRON_LP_IT_MASK			0x08
 #define INT_STS_PWRON_LP_IT_SHIFT			3
 #define INT_STS_PWRON_IT_MASK				0x04
 #define INT_STS_PWRON_IT_SHIFT				2
 #define INT_STS_VMBHI_IT_MASK				0x02
 #define INT_STS_VMBHI_IT_SHIFT				1
-#define INT_STS_VMBDCH_IT_MASK				0x01
-#define INT_STS_VMBDCH_IT_SHIFT				0
+#define INT_STS_PWRHOLD_F_IT_MASK			0x01
+#define INT_STS_PWRHOLD_F_IT_SHIFT			0
 
 
 /*Register INT_MSK  (0x80) register.RegisterDescription */
@@ -599,16 +642,16 @@
 #define INT_MSK_RTC_ALARM_IT_MSK_SHIFT			6
 #define INT_MSK_HOTDIE_IT_MSK_MASK			0x20
 #define INT_MSK_HOTDIE_IT_MSK_SHIFT			5
-#define INT_MSK_PWRHOLD_IT_MSK_MASK			0x10
-#define INT_MSK_PWRHOLD_IT_MSK_SHIFT			4
+#define INT_MSK_PWRHOLD_R_IT_MSK_MASK			0x10
+#define INT_MSK_PWRHOLD_R_IT_MSK_SHIFT			4
 #define INT_MSK_PWRON_LP_IT_MSK_MASK			0x08
 #define INT_MSK_PWRON_LP_IT_MSK_SHIFT			3
 #define INT_MSK_PWRON_IT_MSK_MASK			0x04
 #define INT_MSK_PWRON_IT_MSK_SHIFT			2
 #define INT_MSK_VMBHI_IT_MSK_MASK			0x02
 #define INT_MSK_VMBHI_IT_MSK_SHIFT			1
-#define INT_MSK_VMBDCH_IT_MSK_MASK			0x01
-#define INT_MSK_VMBDCH_IT_MSK_SHIFT			0
+#define INT_MSK_PWRHOLD_F_IT_MSK_MASK			0x01
+#define INT_MSK_PWRHOLD_F_IT_MSK_SHIFT			0
 
 
 /*Register INT_STS2  (0x80) register.RegisterDescription */
@@ -650,6 +693,14 @@
 
 
 /*Register INT_STS3  (0x80) register.RegisterDescription */
+#define INT_STS3_PWRDN_IT_MASK				0x80
+#define INT_STS3_PWRDN_IT_SHIFT				7
+#define INT_STS3_VMBCH2_L_IT_MASK			0x40
+#define INT_STS3_VMBCH2_L_IT_SHIFT			6
+#define INT_STS3_VMBCH2_H_IT_MASK			0x20
+#define INT_STS3_VMBCH2_H_IT_SHIFT			5
+#define INT_STS3_WTCHDG_IT_MASK				0x10
+#define INT_STS3_WTCHDG_IT_SHIFT			4
 #define INT_STS3_GPIO5_F_IT_MASK			0x08
 #define INT_STS3_GPIO5_F_IT_SHIFT			3
 #define INT_STS3_GPIO5_R_IT_MASK			0x04
@@ -661,6 +712,14 @@
 
 
 /*Register INT_MSK3  (0x80) register.RegisterDescription */
+#define INT_MSK3_PWRDN_IT_MSK_MASK			0x80
+#define INT_MSK3_PWRDN_IT_MSK_SHIFT			7
+#define INT_MSK3_VMBCH2_L_IT_MSK_MASK			0x40
+#define INT_MSK3_VMBCH2_L_IT_MSK_SHIFT			6
+#define INT_MSK3_VMBCH2_H_IT_MSK_MASK			0x20
+#define INT_MSK3_VMBCH2_H_IT_MSK_SHIFT			5
+#define INT_MSK3_WTCHDG_IT_MSK_MASK			0x10
+#define INT_MSK3_WTCHDG_IT_MSK_SHIFT			4
 #define INT_MSK3_GPIO5_F_IT_MSK_MASK			0x08
 #define INT_MSK3_GPIO5_F_IT_MSK_SHIFT			3
 #define INT_MSK3_GPIO5_R_IT_MSK_MASK			0x04
@@ -721,34 +780,32 @@
 #define TPS65910_IRQ_GPIO_F				9
 #define TPS65910_NUM_IRQ				10
 
-#define TPS65911_IRQ_VBAT_VMBDCH			0
-#define TPS65911_IRQ_VBAT_VMBDCH2L			1
-#define TPS65911_IRQ_VBAT_VMBDCH2H			2
-#define TPS65911_IRQ_VBAT_VMHI				3
-#define TPS65911_IRQ_PWRON				4
-#define TPS65911_IRQ_PWRON_LP				5
-#define TPS65911_IRQ_PWRHOLD_F				6
-#define TPS65911_IRQ_PWRHOLD_R				7
-#define TPS65911_IRQ_HOTDIE				8
-#define TPS65911_IRQ_RTC_ALARM				9
-#define TPS65911_IRQ_RTC_PERIOD				10
-#define TPS65911_IRQ_GPIO0_R				11
-#define TPS65911_IRQ_GPIO0_F				12
-#define TPS65911_IRQ_GPIO1_R				13
-#define TPS65911_IRQ_GPIO1_F				14
-#define TPS65911_IRQ_GPIO2_R				15
-#define TPS65911_IRQ_GPIO2_F				16
-#define TPS65911_IRQ_GPIO3_R				17
-#define TPS65911_IRQ_GPIO3_F				18
-#define TPS65911_IRQ_GPIO4_R				19
-#define TPS65911_IRQ_GPIO4_F				20
-#define TPS65911_IRQ_GPIO5_R				21
-#define TPS65911_IRQ_GPIO5_F				22
-#define TPS65911_IRQ_WTCHDG				23
-#define TPS65911_IRQ_PWRDN				24
-
-#define TPS65911_NUM_IRQ				25
-
+#define TPS65911_IRQ_PWRHOLD_F				0
+#define TPS65911_IRQ_VBAT_VMHI				1
+#define TPS65911_IRQ_PWRON				2
+#define TPS65911_IRQ_PWRON_LP				3
+#define TPS65911_IRQ_PWRHOLD_R				4
+#define TPS65911_IRQ_HOTDIE				5
+#define TPS65911_IRQ_RTC_ALARM				6
+#define TPS65911_IRQ_RTC_PERIOD				7
+#define TPS65911_IRQ_GPIO0_R				8
+#define TPS65911_IRQ_GPIO0_F				9
+#define TPS65911_IRQ_GPIO1_R				10
+#define TPS65911_IRQ_GPIO1_F				11
+#define TPS65911_IRQ_GPIO2_R				12
+#define TPS65911_IRQ_GPIO2_F				13
+#define TPS65911_IRQ_GPIO3_R				14
+#define TPS65911_IRQ_GPIO3_F				15
+#define TPS65911_IRQ_GPIO4_R				16
+#define TPS65911_IRQ_GPIO4_F				17
+#define TPS65911_IRQ_GPIO5_R				18
+#define TPS65911_IRQ_GPIO5_F				19
+#define TPS65911_IRQ_WTCHDG				20
+#define TPS65911_IRQ_VMBCH2_H				21
+#define TPS65911_IRQ_VMBCH2_L				22
+#define TPS65911_IRQ_PWRDN				23
+
+#define TPS65911_NUM_IRQ				24
 
 /* GPIO Register Definitions */
 #define TPS65910_GPIO_DEB				BIT(2)
@@ -848,11 +905,8 @@ struct tps65910 {
 	struct tps65910_board *of_plat_data;
 
 	/* IRQ Handling */
-	struct mutex irq_lock;
 	int chip_irq;
-	int irq_base;
-	int irq_num;
-	u32 irq_mask;
+	struct regmap_irq_chip_data *irq_data;
 	struct irq_domain *domain;
 };
 
@@ -900,4 +954,9 @@ static inline int tps65910_reg_update_bits(struct tps65910 *tps65910, u8 reg,
 	return regmap_update_bits(tps65910->regmap, reg, mask, val);
 }
 
+static inline int tps65910_irq_get_virq(struct tps65910 *tps65910, int irq)
+{
+	return regmap_irq_get_virq(tps65910->irq_data, irq);
+}
+
 #endif /*  __LINUX_MFD_TPS65910_H */
-- 
1.7.1.1


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

* [PATCH 2/5] mfd: tps65910: move interrupt implementation code to mfd file
  2012-10-09 11:28 [PATCH 0/5] mfd: tps65910: use regmap irq framework for interrupt Laxman Dewangan
  2012-10-09 11:28 ` [PATCH 1/5] mfd: tps65910: use regmap irq framework for interrupt support Laxman Dewangan
@ 2012-10-09 11:28 ` Laxman Dewangan
  2012-10-10  3:08   ` Mark Brown
  2012-10-09 11:28 ` [PATCH 3/5] mfd: tps65910: Initialize mfd devices after all initialization done Laxman Dewangan
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Laxman Dewangan @ 2012-10-09 11:28 UTC (permalink / raw)
  To: broonie, gregkh, sameo; +Cc: swarren, linux-kernel, Laxman Dewangan

In place of implementing the irq support in separate file,
moving implementation to main mfd file.
The irq files only contains the table and init steps only
and does not need extra file to have this only for this
purpose.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
 drivers/mfd/Makefile         |    2 +-
 drivers/mfd/tps65910-irq.c   |  243 ------------------------------------------
 drivers/mfd/tps65910.c       |  216 +++++++++++++++++++++++++++++++++++++
 include/linux/mfd/tps65910.h |    4 -
 4 files changed, 217 insertions(+), 248 deletions(-)
 delete mode 100644 drivers/mfd/tps65910-irq.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d8ccb63..47811a5 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -52,7 +52,7 @@ obj-$(CONFIG_TPS6105X)		+= tps6105x.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
-obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o tps65910-irq.o
+obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
 tps65912-objs                   := tps65912-core.o tps65912-irq.o
 obj-$(CONFIG_MFD_TPS65912)	+= tps65912.o
 obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c
deleted file mode 100644
index 554543a..0000000
--- a/drivers/mfd/tps65910-irq.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * tps65910-irq.c  --  TI TPS6591x
- *
- * Copyright 2010 Texas Instruments Inc.
- *
- * Author: Graeme Gregory <gg@slimlogic.co.uk>
- * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/gpio.h>
-#include <linux/mfd/tps65910.h>
-
-
-static const struct regmap_irq tps65911_irqs[] = {
-	/* INT_STS */
-	[TPS65911_IRQ_PWRHOLD_F] = {
-		.mask = INT_MSK_PWRHOLD_F_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65911_IRQ_VBAT_VMHI] = {
-		.mask = INT_MSK_VMBHI_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65911_IRQ_PWRON] = {
-		.mask = INT_MSK_PWRON_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65911_IRQ_PWRON_LP] = {
-		.mask = INT_MSK_PWRON_LP_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65911_IRQ_PWRHOLD_R] = {
-		.mask = INT_MSK_PWRHOLD_R_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65911_IRQ_HOTDIE] = {
-		.mask = INT_MSK_HOTDIE_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65911_IRQ_RTC_ALARM] = {
-		.mask = INT_MSK_RTC_ALARM_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65911_IRQ_RTC_PERIOD] = {
-		.mask = INT_MSK_RTC_PERIOD_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-
-	/* INT_STS2 */
-	[TPS65911_IRQ_GPIO0_R] = {
-		.mask = INT_MSK2_GPIO0_R_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65911_IRQ_GPIO0_F] = {
-		.mask = INT_MSK2_GPIO0_F_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65911_IRQ_GPIO1_R] = {
-		.mask = INT_MSK2_GPIO1_R_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65911_IRQ_GPIO1_F] = {
-		.mask = INT_MSK2_GPIO1_F_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65911_IRQ_GPIO2_R] = {
-		.mask = INT_MSK2_GPIO2_R_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65911_IRQ_GPIO2_F] = {
-		.mask = INT_MSK2_GPIO2_F_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65911_IRQ_GPIO3_R] = {
-		.mask = INT_MSK2_GPIO3_R_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65911_IRQ_GPIO3_F] = {
-		.mask = INT_MSK2_GPIO3_F_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-
-	/* INT_STS3 */
-	[TPS65911_IRQ_GPIO4_R] = {
-		.mask = INT_MSK3_GPIO4_R_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-	[TPS65911_IRQ_GPIO4_F] = {
-		.mask = INT_MSK3_GPIO4_F_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-	[TPS65911_IRQ_GPIO5_R] = {
-		.mask = INT_MSK3_GPIO5_R_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-	[TPS65911_IRQ_GPIO5_F] = {
-		.mask = INT_MSK3_GPIO5_F_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-	[TPS65911_IRQ_WTCHDG] = {
-		.mask = INT_MSK3_WTCHDG_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-	[TPS65911_IRQ_VMBCH2_H] = {
-		.mask = INT_MSK3_VMBCH2_H_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-	[TPS65911_IRQ_VMBCH2_L] = {
-		.mask = INT_MSK3_VMBCH2_L_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-	[TPS65911_IRQ_PWRDN] = {
-		.mask = INT_MSK3_PWRDN_IT_MSK_MASK,
-		.reg_offset = 2,
-	},
-};
-
-static const struct regmap_irq tps65910_irqs[] = {
-	/* INT_STS */
-	[TPS65910_IRQ_VBAT_VMBDCH] = {
-		.mask = TPS65910_INT_MSK_VMBDCH_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65910_IRQ_VBAT_VMHI] = {
-		.mask = TPS65910_INT_MSK_VMBHI_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65910_IRQ_PWRON] = {
-		.mask = TPS65910_INT_MSK_PWRON_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65910_IRQ_PWRON_LP] = {
-		.mask = TPS65910_INT_MSK_PWRON_LP_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65910_IRQ_PWRHOLD] = {
-		.mask = TPS65910_INT_MSK_PWRHOLD_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65910_IRQ_HOTDIE] = {
-		.mask = TPS65910_INT_MSK_HOTDIE_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65910_IRQ_RTC_ALARM] = {
-		.mask = TPS65910_INT_MSK_RTC_ALARM_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-	[TPS65910_IRQ_RTC_PERIOD] = {
-		.mask = TPS65910_INT_MSK_RTC_PERIOD_IT_MSK_MASK,
-		.reg_offset = 0,
-	},
-
-	/* INT_STS2 */
-	[TPS65910_IRQ_GPIO_R] = {
-		.mask = TPS65910_INT_MSK2_GPIO0_F_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-	[TPS65910_IRQ_GPIO_F] = {
-		.mask = TPS65910_INT_MSK2_GPIO0_R_IT_MSK_MASK,
-		.reg_offset = 1,
-	},
-};
-
-static struct regmap_irq_chip tps65911_irq_chip = {
-	.name = "tps65910",
-	.irqs = tps65911_irqs,
-	.num_irqs = ARRAY_SIZE(tps65911_irqs),
-	.num_regs = 3,
-	.irq_reg_stride = 2,
-	.status_base = TPS65910_INT_STS,
-	.mask_base = TPS65910_INT_MSK,
-	.ack_base = TPS65910_INT_MSK,
-};
-
-static struct regmap_irq_chip tps65910_irq_chip = {
-	.name = "tps65910",
-	.irqs = tps65910_irqs,
-	.num_irqs = ARRAY_SIZE(tps65910_irqs),
-	.num_regs = 2,
-	.irq_reg_stride = 2,
-	.status_base = TPS65910_INT_STS,
-	.mask_base = TPS65910_INT_MSK,
-	.ack_base = TPS65910_INT_MSK,
-};
-
-int tps65910_irq_init(struct tps65910 *tps65910, int irq,
-		    struct tps65910_platform_data *pdata)
-{
-	int ret = 0;
-	static struct regmap_irq_chip *tps6591x_irqs_chip;
-
-	if (!irq) {
-		dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
-		return -EINVAL;
-	}
-
-	if (!pdata) {
-		dev_warn(tps65910->dev, "No interrupt support, no pdata\n");
-		return -EINVAL;
-	}
-
-
-	switch (tps65910_chip_id(tps65910)) {
-	case TPS65910:
-		tps6591x_irqs_chip = &tps65910_irq_chip;
-		break;
-	case TPS65911:
-		tps6591x_irqs_chip = &tps65911_irq_chip;
-		break;
-	}
-
-	tps65910->chip_irq = irq;
-	ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
-		IRQF_ONESHOT, pdata->irq_base,
-		tps6591x_irqs_chip, &tps65910->irq_data);
-	if (ret < 0) {
-		dev_warn(tps65910->dev,
-				"Failed to add irq_chip %d\n", ret);
-		return ret;
-	}
-	return ret;
-}
-
-int tps65910_irq_exit(struct tps65910 *tps65910)
-{
-	if (tps65910->chip_irq > 0)
-		regmap_del_irq_chip(tps65910->chip_irq, tps65910->irq_data);
-	return 0;
-}
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 0d79ce2..11adedb 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -19,6 +19,9 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/mfd/core.h>
 #include <linux/regmap.h>
 #include <linux/mfd/tps65910.h>
@@ -50,6 +53,219 @@ static struct mfd_cell tps65910s[] = {
 };
 
 
+static const struct regmap_irq tps65911_irqs[] = {
+	/* INT_STS */
+	[TPS65911_IRQ_PWRHOLD_F] = {
+		.mask = INT_MSK_PWRHOLD_F_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_VBAT_VMHI] = {
+		.mask = INT_MSK_VMBHI_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_PWRON] = {
+		.mask = INT_MSK_PWRON_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_PWRON_LP] = {
+		.mask = INT_MSK_PWRON_LP_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_PWRHOLD_R] = {
+		.mask = INT_MSK_PWRHOLD_R_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_HOTDIE] = {
+		.mask = INT_MSK_HOTDIE_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_RTC_ALARM] = {
+		.mask = INT_MSK_RTC_ALARM_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65911_IRQ_RTC_PERIOD] = {
+		.mask = INT_MSK_RTC_PERIOD_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+
+	/* INT_STS2 */
+	[TPS65911_IRQ_GPIO0_R] = {
+		.mask = INT_MSK2_GPIO0_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO0_F] = {
+		.mask = INT_MSK2_GPIO0_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO1_R] = {
+		.mask = INT_MSK2_GPIO1_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO1_F] = {
+		.mask = INT_MSK2_GPIO1_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO2_R] = {
+		.mask = INT_MSK2_GPIO2_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO2_F] = {
+		.mask = INT_MSK2_GPIO2_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO3_R] = {
+		.mask = INT_MSK2_GPIO3_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65911_IRQ_GPIO3_F] = {
+		.mask = INT_MSK2_GPIO3_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+
+	/* INT_STS2 */
+	[TPS65911_IRQ_GPIO4_R] = {
+		.mask = INT_MSK3_GPIO4_R_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_GPIO4_F] = {
+		.mask = INT_MSK3_GPIO4_F_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_GPIO5_R] = {
+		.mask = INT_MSK3_GPIO5_R_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_GPIO5_F] = {
+		.mask = INT_MSK3_GPIO5_F_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_WTCHDG] = {
+		.mask = INT_MSK3_WTCHDG_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_VMBCH2_H] = {
+		.mask = INT_MSK3_VMBCH2_H_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_VMBCH2_L] = {
+		.mask = INT_MSK3_VMBCH2_L_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+	[TPS65911_IRQ_PWRDN] = {
+		.mask = INT_MSK3_PWRDN_IT_MSK_MASK,
+		.reg_offset = 2,
+	},
+};
+
+static const struct regmap_irq tps65910_irqs[] = {
+	/* INT_STS */
+	[TPS65910_IRQ_VBAT_VMBDCH] = {
+		.mask = TPS65910_INT_MSK_VMBDCH_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_VBAT_VMHI] = {
+		.mask = TPS65910_INT_MSK_VMBHI_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_PWRON] = {
+		.mask = TPS65910_INT_MSK_PWRON_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_PWRON_LP] = {
+		.mask = TPS65910_INT_MSK_PWRON_LP_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_PWRHOLD] = {
+		.mask = TPS65910_INT_MSK_PWRHOLD_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_HOTDIE] = {
+		.mask = TPS65910_INT_MSK_HOTDIE_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_RTC_ALARM] = {
+		.mask = TPS65910_INT_MSK_RTC_ALARM_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+	[TPS65910_IRQ_RTC_PERIOD] = {
+		.mask = TPS65910_INT_MSK_RTC_PERIOD_IT_MSK_MASK,
+		.reg_offset = 0,
+	},
+
+	/* INT_STS2 */
+	[TPS65910_IRQ_GPIO_R] = {
+		.mask = TPS65910_INT_MSK2_GPIO0_F_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+	[TPS65910_IRQ_GPIO_F] = {
+		.mask = TPS65910_INT_MSK2_GPIO0_R_IT_MSK_MASK,
+		.reg_offset = 1,
+	},
+};
+
+static struct regmap_irq_chip tps65911_irq_chip = {
+	.name = "tps65910",
+	.irqs = tps65911_irqs,
+	.num_irqs = ARRAY_SIZE(tps65911_irqs),
+	.num_regs = 3,
+	.irq_reg_stride = 2,
+	.status_base = TPS65910_INT_STS,
+	.mask_base = TPS65910_INT_MSK,
+	.ack_base = TPS65910_INT_MSK,
+};
+
+static struct regmap_irq_chip tps65910_irq_chip = {
+	.name = "tps65910",
+	.irqs = tps65910_irqs,
+	.num_irqs = ARRAY_SIZE(tps65910_irqs),
+	.num_regs = 2,
+	.irq_reg_stride = 2,
+	.status_base = TPS65910_INT_STS,
+	.mask_base = TPS65910_INT_MSK,
+	.ack_base = TPS65910_INT_MSK,
+};
+
+static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
+		    struct tps65910_platform_data *pdata)
+{
+	int ret = 0;
+	static struct regmap_irq_chip *tps6591x_irqs_chip;
+
+	if (!irq) {
+		dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
+		return -EINVAL;
+	}
+
+	if (!pdata) {
+		dev_warn(tps65910->dev, "No interrupt support, no pdata\n");
+		return -EINVAL;
+	}
+
+	switch (tps65910_chip_id(tps65910)) {
+	case TPS65910:
+		tps6591x_irqs_chip = &tps65910_irq_chip;
+		break;
+	case TPS65911:
+		tps6591x_irqs_chip = &tps65911_irq_chip;
+		break;
+	}
+
+	tps65910->chip_irq = irq;
+	ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
+		IRQF_ONESHOT, pdata->irq_base,
+		tps6591x_irqs_chip, &tps65910->irq_data);
+	if (ret < 0)
+		dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
+	return ret;
+}
+
+static int tps65910_irq_exit(struct tps65910 *tps65910)
+{
+	if (tps65910->chip_irq > 0)
+		regmap_del_irq_chip(tps65910->chip_irq, tps65910->irq_data);
+	return 0;
+}
+
 static bool is_volatile_reg(struct device *dev, unsigned int reg)
 {
 	struct tps65910 *tps65910 = dev_get_drvdata(dev);
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
index b564ac2..0b16903 100644
--- a/include/linux/mfd/tps65910.h
+++ b/include/linux/mfd/tps65910.h
@@ -915,10 +915,6 @@ struct tps65910_platform_data {
 	int irq_base;
 };
 
-int tps65910_irq_init(struct tps65910 *tps65910, int irq,
-		struct tps65910_platform_data *pdata);
-int tps65910_irq_exit(struct tps65910 *tps65910);
-
 static inline int tps65910_chip_id(struct tps65910 *tps65910)
 {
 	return tps65910->id;
-- 
1.7.1.1


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

* [PATCH 3/5] mfd: tps65910: Initialize mfd devices after all initialization done
  2012-10-09 11:28 [PATCH 0/5] mfd: tps65910: use regmap irq framework for interrupt Laxman Dewangan
  2012-10-09 11:28 ` [PATCH 1/5] mfd: tps65910: use regmap irq framework for interrupt support Laxman Dewangan
  2012-10-09 11:28 ` [PATCH 2/5] mfd: tps65910: move interrupt implementation code to mfd file Laxman Dewangan
@ 2012-10-09 11:28 ` Laxman Dewangan
  2012-10-10  3:09   ` Mark Brown
  2012-10-09 11:28 ` [PATCH 4/5] regmap: add API to get irq_domain from regmap irq Laxman Dewangan
  2012-10-09 11:28 ` [PATCH 5/5] mfd: tps65910: pass irq_domain when adding mfd sub devices Laxman Dewangan
  4 siblings, 1 reply; 10+ messages in thread
From: Laxman Dewangan @ 2012-10-09 11:28 UTC (permalink / raw)
  To: broonie, gregkh, sameo; +Cc: swarren, linux-kernel, Laxman Dewangan

Add sub devices of tps65910 after all initialization like interrupt,
clock etc. is done. This will make sure that require data gets
initialized properly before sub devices probe's get called.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
 drivers/mfd/tps65910.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 11adedb..f7f9d3a 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -495,18 +495,10 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = mfd_add_devices(tps65910->dev, -1,
-			      tps65910s, ARRAY_SIZE(tps65910s),
-			      NULL, 0, NULL);
-	if (ret < 0) {
-		dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
-		return ret;
-	}
-
 	init_data->irq = pmic_plat_data->irq;
 	init_data->irq_base = pmic_plat_data->irq_base;
-
 	tps65910_irq_init(tps65910, init_data->irq, init_data);
+
 	tps65910_ck32k_init(tps65910, pmic_plat_data);
 	tps65910_sleepinit(tps65910, pmic_plat_data);
 
@@ -515,6 +507,14 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
 		pm_power_off = tps65910_power_off;
 	}
 
+	ret = mfd_add_devices(tps65910->dev, -1,
+			      tps65910s, ARRAY_SIZE(tps65910s),
+			      NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
+		return ret;
+	}
+
 	return ret;
 }
 
-- 
1.7.1.1


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

* [PATCH 4/5] regmap: add API to get irq_domain from regmap irq
  2012-10-09 11:28 [PATCH 0/5] mfd: tps65910: use regmap irq framework for interrupt Laxman Dewangan
                   ` (2 preceding siblings ...)
  2012-10-09 11:28 ` [PATCH 3/5] mfd: tps65910: Initialize mfd devices after all initialization done Laxman Dewangan
@ 2012-10-09 11:28 ` Laxman Dewangan
  2012-10-10  2:08   ` Mark Brown
  2012-10-09 11:28 ` [PATCH 5/5] mfd: tps65910: pass irq_domain when adding mfd sub devices Laxman Dewangan
  4 siblings, 1 reply; 10+ messages in thread
From: Laxman Dewangan @ 2012-10-09 11:28 UTC (permalink / raw)
  To: broonie, gregkh, sameo; +Cc: swarren, linux-kernel, Laxman Dewangan

Add API regmap_irq_get_irq_domain() for getting the
irq domain from regmap irq.
The irq domain created on result of regmap_add_irq_chip()
from driver.
This API is useful in mfd driver when driver add mfd sub devices.
The sub devices IRQs can be passed through IORESOURCE_IRQ and it
need to be mapped properly  with device irq domain. The
mfd_add_devices() creates mapping when adding sub devices and for
this it is require to have irq domain.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
 drivers/base/regmap/regmap-irq.c |   16 ++++++++++++++++
 include/linux/regmap.h           |    1 +
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 5b6b1d8..70bce5f 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -458,3 +458,19 @@ int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq)
 	return irq_create_mapping(data->domain, irq);
 }
 EXPORT_SYMBOL_GPL(regmap_irq_get_virq);
+
+/**
+ * regmap_irq_get_irq_domain(): Return IRQ domain for of the interrupt added.
+ *
+ * Useful for drivers who locally create mapping from irq_domain which is
+ * created on result of the call regmap_add_irq_chip().
+ *
+ * @data: regmap_irq controller to operate on.
+ */
+struct irq_domain *regmap_irq_get_irq_domain(struct regmap_irq_chip_data *data)
+{
+	if (data)
+		return data->domain;
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(regmap_irq_get_irq_domain);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index e3bcc3f..3a6d7b8 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -317,6 +317,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data);
 int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data);
 int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq);
+struct irq_domain *regmap_irq_get_irq_domain(struct regmap_irq_chip_data *data);
 
 #else
 
-- 
1.7.1.1


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

* [PATCH 5/5] mfd: tps65910: pass irq_domain when adding mfd sub devices
  2012-10-09 11:28 [PATCH 0/5] mfd: tps65910: use regmap irq framework for interrupt Laxman Dewangan
                   ` (3 preceding siblings ...)
  2012-10-09 11:28 ` [PATCH 4/5] regmap: add API to get irq_domain from regmap irq Laxman Dewangan
@ 2012-10-09 11:28 ` Laxman Dewangan
  4 siblings, 0 replies; 10+ messages in thread
From: Laxman Dewangan @ 2012-10-09 11:28 UTC (permalink / raw)
  To: broonie, gregkh, sameo; +Cc: swarren, linux-kernel, Laxman Dewangan

When adding the sub device "tps65910-rtc", is it passed the
IO resource IRQ for the interrupt number.
This interrupt needs to map in the device irq domain. Pass
the irq domain of device in mfd_add_devices() so that proper
irq mapping can be done when adding the sub device RTC.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
 drivers/mfd/tps65910.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index f7f9d3a..8ca91dd 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -509,7 +509,8 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
 
 	ret = mfd_add_devices(tps65910->dev, -1,
 			      tps65910s, ARRAY_SIZE(tps65910s),
-			      NULL, 0, NULL);
+			      NULL, 0,
+			      regmap_irq_get_irq_domain(tps65910->irq_data));
 	if (ret < 0) {
 		dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
 		return ret;
-- 
1.7.1.1


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

* Re: [PATCH 4/5] regmap: add API to get irq_domain from regmap irq
  2012-10-09 11:28 ` [PATCH 4/5] regmap: add API to get irq_domain from regmap irq Laxman Dewangan
@ 2012-10-10  2:08   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2012-10-10  2:08 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: gregkh, sameo, swarren, linux-kernel

On Tue, Oct 09, 2012 at 04:58:35PM +0530, Laxman Dewangan wrote:
> Add API regmap_irq_get_irq_domain() for getting the
> irq domain from regmap irq.
> The irq domain created on result of regmap_add_irq_chip()
> from driver.

This needs stubbing.  

Please also fix the formatting of your commit log, you're either
wrapping randomly in the middle of paragraphs or not leaving blank lines
between paragraphs.

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

* Re: [PATCH 1/5] mfd: tps65910: use regmap irq framework for interrupt support
  2012-10-09 11:28 ` [PATCH 1/5] mfd: tps65910: use regmap irq framework for interrupt support Laxman Dewangan
@ 2012-10-10  3:07   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2012-10-10  3:07 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: gregkh, sameo, swarren, linux-kernel

On Tue, Oct 09, 2012 at 04:58:32PM +0530, Laxman Dewangan wrote:
> Implement irq support of tps65910 with regmap irq framework
> in place of implementing locally.
> This reduces the code size significantly and easy to maintain.

Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

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

* Re: [PATCH 2/5] mfd: tps65910: move interrupt implementation code to mfd file
  2012-10-09 11:28 ` [PATCH 2/5] mfd: tps65910: move interrupt implementation code to mfd file Laxman Dewangan
@ 2012-10-10  3:08   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2012-10-10  3:08 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: gregkh, sameo, swarren, linux-kernel

On Tue, Oct 09, 2012 at 04:58:33PM +0530, Laxman Dewangan wrote:
> In place of implementing the irq support in separate file,
> moving implementation to main mfd file.
> The irq files only contains the table and init steps only
> and does not need extra file to have this only for this
> purpose.

Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

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

* Re: [PATCH 3/5] mfd: tps65910: Initialize mfd devices after all initialization done
  2012-10-09 11:28 ` [PATCH 3/5] mfd: tps65910: Initialize mfd devices after all initialization done Laxman Dewangan
@ 2012-10-10  3:09   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2012-10-10  3:09 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: gregkh, sameo, swarren, linux-kernel

On Tue, Oct 09, 2012 at 04:58:34PM +0530, Laxman Dewangan wrote:
> Add sub devices of tps65910 after all initialization like interrupt,
> clock etc. is done. This will make sure that require data gets
> initialized properly before sub devices probe's get called.

Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

but isn't this needed as a bug fix and so shouldn't it be the first
patch in the series and go in for v3.7?

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

end of thread, other threads:[~2012-10-10  3:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-09 11:28 [PATCH 0/5] mfd: tps65910: use regmap irq framework for interrupt Laxman Dewangan
2012-10-09 11:28 ` [PATCH 1/5] mfd: tps65910: use regmap irq framework for interrupt support Laxman Dewangan
2012-10-10  3:07   ` Mark Brown
2012-10-09 11:28 ` [PATCH 2/5] mfd: tps65910: move interrupt implementation code to mfd file Laxman Dewangan
2012-10-10  3:08   ` Mark Brown
2012-10-09 11:28 ` [PATCH 3/5] mfd: tps65910: Initialize mfd devices after all initialization done Laxman Dewangan
2012-10-10  3:09   ` Mark Brown
2012-10-09 11:28 ` [PATCH 4/5] regmap: add API to get irq_domain from regmap irq Laxman Dewangan
2012-10-10  2:08   ` Mark Brown
2012-10-09 11:28 ` [PATCH 5/5] mfd: tps65910: pass irq_domain when adding mfd sub devices Laxman Dewangan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox