diff mbox

[1/6] mfd: max8925: add irqdomain for dt

Message ID 1359992448-22229-1-git-send-email-haojian.zhuang@linaro.org
State Accepted
Commit 4e405ae256b7e04f7c1213136f3bfd9fb76e2023
Headers show

Commit Message

Haojian Zhuang Feb. 4, 2013, 3:40 p.m. UTC
From: Qing Xu <qingx@marvell.com>

Add irqdomains for max8925's main irq, wrap irq register operations
into irqdomain's map func. it is necessary for dt support.

Also, add dt support for max8925 driver.

Signed-off-by: Qing Xu <qingx@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/mfd/max8925-core.c  |   73 +++++++++++++++++++++++++------------------
 drivers/mfd/max8925-i2c.c   |   36 +++++++++++++++++++--
 include/linux/mfd/max8925.h |    3 +-
 3 files changed, 78 insertions(+), 34 deletions(-)

Comments

Samuel Ortiz Feb. 5, 2013, 8:19 a.m. UTC | #1
Hi Haojian,

On Mon, Feb 04, 2013 at 11:40:42PM +0800, Haojian Zhuang wrote:
> From: Qing Xu <qingx@marvell.com>
> 
> Add irqdomains for max8925's main irq, wrap irq register operations
> into irqdomain's map func. it is necessary for dt support.
> 
> Also, add dt support for max8925 driver.
> 
> Signed-off-by: Qing Xu <qingx@marvell.com>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  drivers/mfd/max8925-core.c  |   73 +++++++++++++++++++++++++------------------
>  drivers/mfd/max8925-i2c.c   |   36 +++++++++++++++++++--
>  include/linux/mfd/max8925.h |    3 +-
>  3 files changed, 78 insertions(+), 34 deletions(-)
This and the next 5 patches applied, thanks for the heads up.

Cheers,
Samuel.
Qing Xu Feb. 5, 2013, 8:21 a.m. UTC | #2
On 02/05/2013 04:19 PM, Samuel Ortiz wrote:
> Hi Haojian,
>
> On Mon, Feb 04, 2013 at 11:40:42PM +0800, Haojian Zhuang wrote:
>> From: Qing Xu <qingx@marvell.com>
>>
>> Add irqdomains for max8925's main irq, wrap irq register operations
>> into irqdomain's map func. it is necessary for dt support.
>>
>> Also, add dt support for max8925 driver.
>>
>> Signed-off-by: Qing Xu <qingx@marvell.com>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
>> ---
>>   drivers/mfd/max8925-core.c  |   73 +++++++++++++++++++++++++------------------
>>   drivers/mfd/max8925-i2c.c   |   36 +++++++++++++++++++--
>>   include/linux/mfd/max8925.h |    3 +-
>>   3 files changed, 78 insertions(+), 34 deletions(-)
> This and the next 5 patches applied, thanks for the heads up.
>
> Cheers,
> Samuel.
>
Hi Samuel, Haojian,

Thank you very much!

-Qing
Haojian Zhuang Feb. 5, 2013, 8:40 a.m. UTC | #3
On Tue, Feb 5, 2013 at 4:19 PM, Samuel Ortiz <sameo@linux.intel.com> wrote:
> Hi Haojian,
>
> On Mon, Feb 04, 2013 at 11:40:42PM +0800, Haojian Zhuang wrote:
>> From: Qing Xu <qingx@marvell.com>
>>
>> Add irqdomains for max8925's main irq, wrap irq register operations
>> into irqdomain's map func. it is necessary for dt support.
>>
>> Also, add dt support for max8925 driver.
>>
>> Signed-off-by: Qing Xu <qingx@marvell.com>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
>> ---
>>  drivers/mfd/max8925-core.c  |   73 +++++++++++++++++++++++++------------------
>>  drivers/mfd/max8925-i2c.c   |   36 +++++++++++++++++++--
>>  include/linux/mfd/max8925.h |    3 +-
>>  3 files changed, 78 insertions(+), 34 deletions(-)
> This and the next 5 patches applied, thanks for the heads up.
>

Thanks :)

Best Regards
Haojian
diff mbox

Patch

diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index e32466e..0ad8d9a 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -14,10 +14,13 @@ 
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/machine.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/max8925.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 
 static struct resource bk_resources[] = {
 	{ 0x84, 0x84, "mode control", IORESOURCE_REG, },
@@ -639,17 +642,33 @@  static struct irq_chip max8925_irq_chip = {
 	.irq_disable	= max8925_irq_disable,
 };
 
+static int max8925_irq_domain_map(struct irq_domain *d, unsigned int virq,
+				 irq_hw_number_t hw)
+{
+	irq_set_chip_data(virq, d->host_data);
+	irq_set_chip_and_handler(virq, &max8925_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(virq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(virq, IRQF_VALID);
+#else
+	irq_set_noprobe(virq);
+#endif
+	return 0;
+}
+
+static struct irq_domain_ops max8925_irq_domain_ops = {
+	.map	= max8925_irq_domain_map,
+	.xlate	= irq_domain_xlate_onetwocell,
+};
+
+
 static int max8925_irq_init(struct max8925_chip *chip, int irq,
 			    struct max8925_platform_data *pdata)
 {
 	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
-	int i, ret;
-	int __irq;
+	int ret;
+	struct device_node *node = chip->dev->of_node;
 
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(chip->dev, "No interrupt support on IRQ base\n");
-		return -EINVAL;
-	}
 	/* clear all interrupts */
 	max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1);
 	max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2);
@@ -667,35 +686,30 @@  static int max8925_irq_init(struct max8925_chip *chip, int irq,
 	max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff);
 
 	mutex_init(&chip->irq_lock);
-	chip->core_irq = irq;
-	chip->irq_base = pdata->irq_base;
-
-	/* register with genirq */
-	for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
-		__irq = i + chip->irq_base;
-		irq_set_chip_data(__irq, chip);
-		irq_set_chip_and_handler(__irq, &max8925_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
-	}
-	if (!irq) {
-		dev_warn(chip->dev, "No interrupt support on core IRQ\n");
-		goto tsc_irq;
+	chip->irq_base = irq_alloc_descs(-1, 0, MAX8925_NR_IRQS, 0);
+	if (chip->irq_base < 0) {
+		dev_err(chip->dev, "Failed to allocate interrupts, ret:%d\n",
+			chip->irq_base);
+		return -EBUSY;
 	}
 
+	irq_domain_add_legacy(node, MAX8925_NR_IRQS, chip->irq_base, 0,
+			      &max8925_irq_domain_ops, chip);
+
+	/* request irq handler for pmic main irq*/
+	chip->core_irq = irq;
+	if (!chip->core_irq)
+		return -EBUSY;
 	ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT,
 				   "max8925", chip);
 	if (ret) {
 		dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
 		chip->core_irq = 0;
+		return -EBUSY;
 	}
 
-tsc_irq:
+	/* request irq handler for pmic tsc irq*/
+
 	/* mask TSC interrupt */
 	max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f);
 
@@ -704,7 +718,6 @@  tsc_irq:
 		return 0;
 	}
 	chip->tsc_irq = pdata->tsc_irq;
-
 	ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
 				   flags | IRQF_ONESHOT, "max8925-tsc", chip);
 	if (ret) {
@@ -875,11 +888,11 @@  int max8925_device_init(struct max8925_chip *chip,
 
 	if (pdata && pdata->power) {
 		ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
-					ARRAY_SIZE(power_devs),
+				      ARRAY_SIZE(power_devs),
 				      &power_supply_resources[0], 0, NULL);
 		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add power supply "
-				"subdev\n");
+			dev_err(chip->dev,
+				"Failed to add power supply subdev\n");
 			goto out_dev;
 		}
 	}
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index 00b5b45..92bbebd 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -135,13 +135,37 @@  static const struct i2c_device_id max8925_id_table[] = {
 };
 MODULE_DEVICE_TABLE(i2c, max8925_id_table);
 
+static int max8925_dt_init(struct device_node *np, struct device *dev,
+			   struct max8925_platform_data *pdata)
+{
+	int ret;
+
+	ret = of_property_read_u32(np, "maxim,tsc-irq", &pdata->tsc_irq);
+	if (ret) {
+		dev_err(dev, "Not found maxim,tsc-irq property\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int max8925_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 {
 	struct max8925_platform_data *pdata = client->dev.platform_data;
 	static struct max8925_chip *chip;
-
-	if (!pdata) {
+	struct device_node *node = client->dev.of_node;
+
+	if (node && !pdata) {
+		/* parse DT to get platform data */
+		pdata = devm_kzalloc(&client->dev,
+				     sizeof(struct max8925_platform_data),
+				     GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+
+		if (max8925_dt_init(node, &client->dev, pdata))
+			return -EINVAL;
+	} else if (!pdata) {
 		pr_info("%s: platform data is missing\n", __func__);
 		return -EINVAL;
 	}
@@ -203,11 +227,18 @@  static int max8925_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume);
 
+static const struct of_device_id max8925_dt_ids[] = {
+	{ .compatible = "maxim,max8925", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, max8925_dt_ids);
+
 static struct i2c_driver max8925_driver = {
 	.driver	= {
 		.name	= "max8925",
 		.owner	= THIS_MODULE,
 		.pm     = &max8925_pm_ops,
+		.of_match_table = of_match_ptr(max8925_dt_ids),
 	},
 	.probe		= max8925_probe,
 	.remove		= max8925_remove,
@@ -217,7 +248,6 @@  static struct i2c_driver max8925_driver = {
 static int __init max8925_i2c_init(void)
 {
 	int ret;
-
 	ret = i2c_add_driver(&max8925_driver);
 	if (ret != 0)
 		pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
index 74d8e29..ce8502e 100644
--- a/include/linux/mfd/max8925.h
+++ b/include/linux/mfd/max8925.h
@@ -190,6 +190,8 @@  enum {
 	MAX8925_NR_IRQS,
 };
 
+
+
 struct max8925_chip {
 	struct device		*dev;
 	struct i2c_client	*i2c;
@@ -201,7 +203,6 @@  struct max8925_chip {
 	int			irq_base;
 	int			core_irq;
 	int			tsc_irq;
-
 	unsigned int            wakeup_flag;
 };