diff options
Diffstat (limited to 'drivers/mfd/stmpe.c')
| -rw-r--r-- | drivers/mfd/stmpe.c | 86 |
1 files changed, 38 insertions, 48 deletions
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 1dd39483e7c1..3c5c2f157f52 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -8,14 +8,13 @@ */ #include <linux/err.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/export.h> #include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/pm.h> #include <linux/slab.h> #include <linux/mfd/core.h> @@ -30,17 +29,12 @@ * @irq_trigger: IRQ trigger to use for the interrupt to the host * @autosleep: bool to enable/disable stmpe autosleep * @autosleep_timeout: inactivity timeout in milliseconds for autosleep - * @irq_over_gpio: true if gpio is used to get irq - * @irq_gpio: gpio number over which irq will be requested (significant only if - * irq_over_gpio is true) */ struct stmpe_platform_data { int id; unsigned int blocks; unsigned int irq_trigger; bool autosleep; - bool irq_over_gpio; - int irq_gpio; int autosleep_timeout; }; @@ -1095,7 +1089,7 @@ static irqreturn_t stmpe_irq(int irq, void *data) if (variant->id_val == STMPE801_ID || variant->id_val == STMPE1600_ID) { - int base = irq_create_mapping(stmpe->domain, 0); + int base = irq_find_mapping(stmpe->domain, 0); handle_nested_irq(base); return IRQ_HANDLED; @@ -1123,7 +1117,7 @@ static irqreturn_t stmpe_irq(int irq, void *data) while (status) { int bit = __ffs(status); int line = bank * 8 + bit; - int nestedirq = irq_create_mapping(stmpe->domain, line); + int nestedirq = irq_find_mapping(stmpe->domain, line); handle_nested_irq(nestedirq); status &= ~(1 << bit); @@ -1225,8 +1219,8 @@ static int stmpe_irq_init(struct stmpe *stmpe, struct device_node *np) int base = 0; int num_irqs = stmpe->variant->num_irqs; - stmpe->domain = irq_domain_add_simple(np, num_irqs, base, - &stmpe_irq_ops, stmpe); + stmpe->domain = irq_domain_create_simple(of_fwnode_handle(np), num_irqs, + base, &stmpe_irq_ops, stmpe); if (!stmpe->domain) { dev_err(stmpe->dev, "Failed to create irqdomain\n"); return -ENOSYS; @@ -1349,32 +1343,22 @@ static void stmpe_of_probe(struct stmpe_platform_data *pdata, if (pdata->id < 0) pdata->id = -1; - pdata->irq_gpio = of_get_named_gpio_flags(np, "irq-gpio", 0, - &pdata->irq_trigger); - if (gpio_is_valid(pdata->irq_gpio)) - pdata->irq_over_gpio = 1; - else - pdata->irq_trigger = IRQF_TRIGGER_NONE; - of_property_read_u32(np, "st,autosleep-timeout", &pdata->autosleep_timeout); pdata->autosleep = (pdata->autosleep_timeout) ? true : false; - for_each_child_of_node(np, child) { - if (of_node_name_eq(child, "stmpe_gpio")) { + for_each_available_child_of_node(np, child) { + if (of_device_is_compatible(child, stmpe_gpio_cell.of_compatible)) pdata->blocks |= STMPE_BLOCK_GPIO; - } else if (of_node_name_eq(child, "stmpe_keypad")) { + else if (of_device_is_compatible(child, stmpe_keypad_cell.of_compatible)) pdata->blocks |= STMPE_BLOCK_KEYPAD; - } else if (of_node_name_eq(child, "stmpe_touchscreen")) { + else if (of_device_is_compatible(child, stmpe_ts_cell.of_compatible)) pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN; - } else if (of_node_name_eq(child, "stmpe_adc")) { + else if (of_device_is_compatible(child, stmpe_adc_cell.of_compatible)) pdata->blocks |= STMPE_BLOCK_ADC; - } else if (of_node_name_eq(child, "stmpe_pwm")) { + else if (of_device_is_compatible(child, stmpe_pwm_cell.of_compatible)) pdata->blocks |= STMPE_BLOCK_PWM; - } else if (of_node_name_eq(child, "stmpe_rotator")) { - pdata->blocks |= STMPE_BLOCK_ROTATOR; - } } } @@ -1384,6 +1368,7 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) struct stmpe_platform_data *pdata; struct device_node *np = ci->dev->of_node; struct stmpe *stmpe; + struct gpio_desc *irq_gpio; int ret; u32 val; @@ -1393,7 +1378,7 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) stmpe_of_probe(pdata, np); - if (of_find_property(np, "interrupts", NULL) == NULL) + if (!of_property_present(np, "interrupts")) ci->irq = -1; stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL); @@ -1437,18 +1422,20 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) if (ci->init) ci->init(stmpe); - if (pdata->irq_over_gpio) { - ret = devm_gpio_request_one(ci->dev, pdata->irq_gpio, - GPIOF_DIR_IN, "stmpe"); - if (ret) { - dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", - ret); - return ret; - } + irq_gpio = devm_gpiod_get_optional(ci->dev, "irq", GPIOD_ASIS); + ret = PTR_ERR_OR_ZERO(irq_gpio); + if (ret) { + dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", ret); + return ret; + } - stmpe->irq = gpio_to_irq(pdata->irq_gpio); + if (irq_gpio) { + stmpe->irq = gpiod_to_irq(irq_gpio); + pdata->irq_trigger = gpiod_is_active_low(irq_gpio) ? + IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; } else { stmpe->irq = ci->irq; + pdata->irq_trigger = IRQF_TRIGGER_NONE; } if (stmpe->irq < 0) { @@ -1495,22 +1482,24 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) return ret; } +EXPORT_SYMBOL_GPL(stmpe_probe); -int stmpe_remove(struct stmpe *stmpe) +void stmpe_remove(struct stmpe *stmpe) { - if (!IS_ERR(stmpe->vio)) + if (stmpe->domain) + irq_domain_remove(stmpe->domain); + + if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio)) regulator_disable(stmpe->vio); - if (!IS_ERR(stmpe->vcc)) + if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc)) regulator_disable(stmpe->vcc); __stmpe_disable(stmpe, STMPE_BLOCK_ADC); mfd_remove_devices(stmpe->dev); - - return 0; } +EXPORT_SYMBOL_GPL(stmpe_remove); -#ifdef CONFIG_PM static int stmpe_suspend(struct device *dev) { struct stmpe *stmpe = dev_get_drvdata(dev); @@ -1531,8 +1520,9 @@ static int stmpe_resume(struct device *dev) return 0; } -const struct dev_pm_ops stmpe_dev_pm_ops = { - .suspend = stmpe_suspend, - .resume = stmpe_resume, -}; -#endif +EXPORT_GPL_SIMPLE_DEV_PM_OPS(stmpe_dev_pm_ops, + stmpe_suspend, stmpe_resume); + +MODULE_DESCRIPTION("STMPE Core driver"); +MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); +MODULE_LICENSE("GPL"); |
