|
@@ -3055,11 +3055,14 @@ static int ab8500_fg_remove(struct platform_device *pdev)
|
|
|
}
|
|
|
|
|
|
/* ab8500 fg driver interrupts and their respective isr */
|
|
|
-static struct ab8500_fg_interrupts ab8500_fg_irq[] = {
|
|
|
+static struct ab8500_fg_interrupts ab8500_fg_irq_th[] = {
|
|
|
{"NCONV_ACCU", ab8500_fg_cc_convend_handler},
|
|
|
{"BATT_OVV", ab8500_fg_batt_ovv_handler},
|
|
|
{"LOW_BAT_F", ab8500_fg_lowbatf_handler},
|
|
|
{"CC_INT_CALIB", ab8500_fg_cc_int_calib_handler},
|
|
|
+};
|
|
|
+
|
|
|
+static struct ab8500_fg_interrupts ab8500_fg_irq_bh[] = {
|
|
|
{"CCEOC", ab8500_fg_cc_data_end_handler},
|
|
|
};
|
|
|
|
|
@@ -3187,21 +3190,36 @@ static int ab8500_fg_probe(struct platform_device *pdev)
|
|
|
init_completion(&di->ab8500_fg_started);
|
|
|
init_completion(&di->ab8500_fg_complete);
|
|
|
|
|
|
- /* Register interrupts */
|
|
|
- for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) {
|
|
|
- irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name);
|
|
|
- ret = request_threaded_irq(irq, NULL, ab8500_fg_irq[i].isr,
|
|
|
- IRQF_SHARED | IRQF_NO_SUSPEND,
|
|
|
- ab8500_fg_irq[i].name, di);
|
|
|
+ /* Register primary interrupt handlers */
|
|
|
+ for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq_th); i++) {
|
|
|
+ irq = platform_get_irq_byname(pdev, ab8500_fg_irq_th[i].name);
|
|
|
+ ret = request_irq(irq, ab8500_fg_irq_th[i].isr,
|
|
|
+ IRQF_SHARED | IRQF_NO_SUSPEND,
|
|
|
+ ab8500_fg_irq_th[i].name, di);
|
|
|
|
|
|
if (ret != 0) {
|
|
|
- dev_err(di->dev, "failed to request %s IRQ %d: %d\n"
|
|
|
- , ab8500_fg_irq[i].name, irq, ret);
|
|
|
+ dev_err(di->dev, "failed to request %s IRQ %d: %d\n",
|
|
|
+ ab8500_fg_irq_th[i].name, irq, ret);
|
|
|
goto free_irq;
|
|
|
}
|
|
|
dev_dbg(di->dev, "Requested %s IRQ %d: %d\n",
|
|
|
- ab8500_fg_irq[i].name, irq, ret);
|
|
|
+ ab8500_fg_irq_th[i].name, irq, ret);
|
|
|
}
|
|
|
+
|
|
|
+ /* Register threaded interrupt handler */
|
|
|
+ irq = platform_get_irq_byname(pdev, ab8500_fg_irq_bh[0].name);
|
|
|
+ ret = request_threaded_irq(irq, NULL, ab8500_fg_irq_bh[0].isr,
|
|
|
+ IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
|
|
|
+ ab8500_fg_irq_bh[0].name, di);
|
|
|
+
|
|
|
+ if (ret != 0) {
|
|
|
+ dev_err(di->dev, "failed to request %s IRQ %d: %d\n",
|
|
|
+ ab8500_fg_irq_bh[0].name, irq, ret);
|
|
|
+ goto free_irq;
|
|
|
+ }
|
|
|
+ dev_dbg(di->dev, "Requested %s IRQ %d: %d\n",
|
|
|
+ ab8500_fg_irq_bh[0].name, irq, ret);
|
|
|
+
|
|
|
di->irq = platform_get_irq_byname(pdev, "CCEOC");
|
|
|
disable_irq(di->irq);
|
|
|
di->nbr_cceoc_irq_cnt = 0;
|
|
@@ -3238,11 +3256,13 @@ static int ab8500_fg_probe(struct platform_device *pdev)
|
|
|
free_irq:
|
|
|
power_supply_unregister(&di->fg_psy);
|
|
|
|
|
|
- /* We also have to free all successfully registered irqs */
|
|
|
- for (i = i - 1; i >= 0; i--) {
|
|
|
- irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name);
|
|
|
+ /* We also have to free all registered irqs */
|
|
|
+ for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq_th); i++) {
|
|
|
+ irq = platform_get_irq_byname(pdev, ab8500_fg_irq_th[i].name);
|
|
|
free_irq(irq, di);
|
|
|
}
|
|
|
+ irq = platform_get_irq_byname(pdev, ab8500_fg_irq_bh[0].name);
|
|
|
+ free_irq(irq, di);
|
|
|
free_inst_curr_wq:
|
|
|
destroy_workqueue(di->fg_wq);
|
|
|
return ret;
|