diff options
| -rw-r--r-- | drivers/mfd/max8925-core.c | 73 | ||||
| -rw-r--r-- | drivers/mfd/max8925-i2c.c | 36 | ||||
| -rw-r--r-- | include/linux/mfd/max8925.h | 3 | 
3 files changed, 78 insertions, 34 deletions
| diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index e32466e865b9..0ad8d9a7c15a 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 00b5b456063d..92bbebd31598 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 74d8e2969630..ce8502e9e7dc 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;  }; | 
