/* * For pretty much all potential sources a register cache sync * won't help, we've just got a software bug somewhere.
*/
dev_err(arizona->dev, "Control interface error\n");
ret = pm_runtime_resume_and_get(arizona->dev); if (ret < 0) {
dev_err(arizona->dev, "Failed to resume device: %d\n", ret); return IRQ_NONE;
}
do {
poll = false;
if (arizona->aod_irq_chip) { /* * Check the AOD status register to determine whether * the nested IRQ handler should be called.
*/
ret = regmap_read(arizona->regmap,
ARIZONA_AOD_IRQ1, &val); if (ret)
dev_warn(arizona->dev, "Failed to read AOD IRQ1 %d\n", ret); elseif (val)
handle_nested_irq(
irq_find_mapping(arizona->virq, 0));
}
/* * Check if one of the main interrupts is asserted and only * check that domain if it is.
*/
ret = regmap_read(arizona->regmap, ARIZONA_IRQ_PIN_STATUS,
&val); if (ret == 0 && val & ARIZONA_IRQ1_STS) {
handle_nested_irq(irq_find_mapping(arizona->virq, 1));
} elseif (ret != 0) {
dev_err(arizona->dev, "Failed to read main IRQ status: %d\n", ret);
}
/* * Poll the IRQ pin status to see if we're really done * if the interrupt controller can't do it for us.
*/ if (!arizona->pdata.irq_gpio) { break;
} elseif (arizona->pdata.irq_flags & IRQF_TRIGGER_RISING &&
gpio_get_value_cansleep(arizona->pdata.irq_gpio)) {
poll = true;
} elseif (arizona->pdata.irq_flags & IRQF_TRIGGER_FALLING &&
!gpio_get_value_cansleep(arizona->pdata.irq_gpio)) {
poll = true;
}
} while (poll);
/* Disable all wake sources by default */
regmap_write(arizona->regmap, ARIZONA_WAKE_CONTROL, 0);
/* Read the flags from the interrupt controller if not specified */ if (!arizona->pdata.irq_flags) {
irq_data = irq_get_irq_data(arizona->irq); if (!irq_data) {
dev_err(arizona->dev, "Invalid IRQ: %d\n",
arizona->irq); return -EINVAL;
}
arizona->pdata.irq_flags = irqd_get_trigger_type(irq_data); switch (arizona->pdata.irq_flags) { case IRQF_TRIGGER_LOW: case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: case IRQF_TRIGGER_FALLING: break;
if (arizona->pdata.irq_flags & (IRQF_TRIGGER_HIGH |
IRQF_TRIGGER_RISING)) {
ret = regmap_update_bits(arizona->regmap, ARIZONA_IRQ_CTRL_1,
ARIZONA_IRQ_POL, 0); if (ret != 0) {
dev_err(arizona->dev, "Couldn't set IRQ polarity: %d\n",
ret); goto err;
}
}
flags |= arizona->pdata.irq_flags;
/* Allocate a virtual IRQ domain to distribute to the regmap domains */
arizona->virq = irq_domain_create_linear(NULL, 2, &arizona_domain_ops, arizona); if (!arizona->virq) {
dev_err(arizona->dev, "Failed to add core IRQ domain\n");
ret = -EINVAL; goto err;
}
if (aod) {
virq = irq_create_mapping(arizona->virq, ARIZONA_AOD_IRQ_INDEX); if (!virq) {
dev_err(arizona->dev, "Failed to map AOD IRQs\n");
ret = -EINVAL; goto err_domain;
}
ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
0, aod, &arizona->aod_irq_chip); if (ret != 0) {
dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); goto err_map_aod;
}
}
virq = irq_create_mapping(arizona->virq, ARIZONA_MAIN_IRQ_INDEX); if (!virq) {
dev_err(arizona->dev, "Failed to map main IRQs\n");
ret = -EINVAL; goto err_aod;
}
ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
0, irq, &arizona->irq_chip); if (ret != 0) {
dev_err(arizona->dev, "Failed to add main IRQs: %d\n", ret); goto err_map_main_irq;
}
/* Used to emulate edge trigger and to work around broken pinmux */ if (arizona->pdata.irq_gpio) { if (gpio_to_irq(arizona->pdata.irq_gpio) != arizona->irq) {
dev_warn(arizona->dev, "IRQ %d is not GPIO %d (%d)\n",
arizona->irq, arizona->pdata.irq_gpio,
gpio_to_irq(arizona->pdata.irq_gpio));
arizona->irq = gpio_to_irq(arizona->pdata.irq_gpio);
}
ret = devm_gpio_request_one(arizona->dev,
arizona->pdata.irq_gpio,
GPIOF_IN, "arizona IRQ"); if (ret != 0) {
dev_err(arizona->dev, "Failed to request IRQ GPIO %d:: %d\n",
arizona->pdata.irq_gpio, ret);
arizona->pdata.irq_gpio = 0;
}
}
ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread,
flags, "arizona", arizona);
if (ret != 0) {
dev_err(arizona->dev, "Failed to request primary IRQ %d: %d\n",
arizona->irq, ret); goto err_main_irq;
}
/* Make sure the boot done IRQ is unmasked for resumes */
ret = arizona_request_irq(arizona, ARIZONA_IRQ_BOOT_DONE, "Boot done",
arizona_boot_done, arizona); if (ret != 0) {
dev_err(arizona->dev, "Failed to request boot done %d: %d\n",
arizona->irq, ret); goto err_boot_done;
}
/* Handle control interface errors in the core */ if (arizona->ctrlif_error) {
ret = arizona_request_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, "Control interface error",
arizona_ctrlif_err, arizona); if (ret != 0) {
dev_err(arizona->dev, "Failed to request CTRLIF_ERR %d: %d\n",
arizona->irq, ret); goto err_ctrlif;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.