aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohan Bjornstedt <johan.bjornstedt@stericsson.com>2013-01-11 08:12:50 -0500
committerAnton Vorontsov <anton@enomsg.org>2013-01-15 20:10:17 -0500
commit3988a4df3499e604a3f2ae979372d27fc5664f77 (patch)
treeefe7b3265c2e4b9a6cdd51d268ce733ced2c3959 /drivers
parentdefbfa9cf879c8e7dde6f7ee9aa95a010efa2e34 (diff)
ab8500_bm: Skip first CCEOC irq for instant current
When enabling the CCEOC irq we might get false interrupt from ab8500-driver due to the latched value will be saved and interpreted as an IRQ when enabled Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Johan Bjornstedt <johan.bjornstedt@stericsson.com> Signed-off-by: Henrik Solver <henrik.solver@stericsson.com> Reviewed-by: Karl KOMIEROWSKI <karl.komierowski@stericsson.com> Signed-off-by: Anton Vorontsov <anton@enomsg.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/power/ab8500_btemp.c11
-rw-r--r--drivers/power/ab8500_fg.c63
2 files changed, 59 insertions, 15 deletions
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index e1d28039ce7b..4a570b6c9e47 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -374,13 +374,10 @@ static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di)
374 return ret; 374 return ret;
375 } 375 }
376 376
377 /* 377 do {
378 * Since there is no interrupt when current measurement is done, 378 msleep(20);
379 * loop for over 250ms (250ms is one sample conversion time 379 } while (!ab8500_fg_inst_curr_started(di->fg));
380 * with 32.768 Khz RTC clock). Note that a stop time must be set 380
381 * since the ab8500_btemp_read_batctrl_voltage call can block and
382 * take an unknown amount of time to complete.
383 */
384 i = 0; 381 i = 0;
385 382
386 do { 383 do {
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
index 3d05c73813c8..0f40c968286c 100644
--- a/drivers/power/ab8500_fg.c
+++ b/drivers/power/ab8500_fg.c
@@ -160,6 +160,7 @@ struct inst_curr_result_list {
160 * @recovery_cnt: Counter for recovery mode 160 * @recovery_cnt: Counter for recovery mode
161 * @high_curr_cnt: Counter for high current mode 161 * @high_curr_cnt: Counter for high current mode
162 * @init_cnt: Counter for init mode 162 * @init_cnt: Counter for init mode
163 * @nbr_cceoc_irq_cnt Counter for number of CCEOC irqs received since enabled
163 * @recovery_needed: Indicate if recovery is needed 164 * @recovery_needed: Indicate if recovery is needed
164 * @high_curr_mode: Indicate if we're in high current mode 165 * @high_curr_mode: Indicate if we're in high current mode
165 * @init_capacity: Indicate if initial capacity measuring should be done 166 * @init_capacity: Indicate if initial capacity measuring should be done
@@ -167,6 +168,7 @@ struct inst_curr_result_list {
167 * @calib_state State during offset calibration 168 * @calib_state State during offset calibration
168 * @discharge_state: Current discharge state 169 * @discharge_state: Current discharge state
169 * @charge_state: Current charge state 170 * @charge_state: Current charge state
171 * @ab8500_fg_started Completion struct used for the instant current start
170 * @ab8500_fg_complete Completion struct used for the instant current reading 172 * @ab8500_fg_complete Completion struct used for the instant current reading
171 * @flags: Structure for information about events triggered 173 * @flags: Structure for information about events triggered
172 * @bat_cap: Structure for battery capacity specific parameters 174 * @bat_cap: Structure for battery capacity specific parameters
@@ -199,6 +201,7 @@ struct ab8500_fg {
199 int recovery_cnt; 201 int recovery_cnt;
200 int high_curr_cnt; 202 int high_curr_cnt;
201 int init_cnt; 203 int init_cnt;
204 int nbr_cceoc_irq_cnt;
202 bool recovery_needed; 205 bool recovery_needed;
203 bool high_curr_mode; 206 bool high_curr_mode;
204 bool init_capacity; 207 bool init_capacity;
@@ -206,6 +209,7 @@ struct ab8500_fg {
206 enum ab8500_fg_calibration_state calib_state; 209 enum ab8500_fg_calibration_state calib_state;
207 enum ab8500_fg_discharge_state discharge_state; 210 enum ab8500_fg_discharge_state discharge_state;
208 enum ab8500_fg_charge_state charge_state; 211 enum ab8500_fg_charge_state charge_state;
212 struct completion ab8500_fg_started;
209 struct completion ab8500_fg_complete; 213 struct completion ab8500_fg_complete;
210 struct ab8500_fg_flags flags; 214 struct ab8500_fg_flags flags;
211 struct ab8500_fg_battery_capacity bat_cap; 215 struct ab8500_fg_battery_capacity bat_cap;
@@ -524,13 +528,14 @@ cc_err:
524 * Note: This is part "one" and has to be called before 528 * Note: This is part "one" and has to be called before
525 * ab8500_fg_inst_curr_finalize() 529 * ab8500_fg_inst_curr_finalize()
526 */ 530 */
527 int ab8500_fg_inst_curr_start(struct ab8500_fg *di) 531int ab8500_fg_inst_curr_start(struct ab8500_fg *di)
528{ 532{
529 u8 reg_val; 533 u8 reg_val;
530 int ret; 534 int ret;
531 535
532 mutex_lock(&di->cc_lock); 536 mutex_lock(&di->cc_lock);
533 537
538 di->nbr_cceoc_irq_cnt = 0;
534 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, 539 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC,
535 AB8500_RTC_CC_CONF_REG, &reg_val); 540 AB8500_RTC_CC_CONF_REG, &reg_val);
536 if (ret < 0) 541 if (ret < 0)
@@ -558,6 +563,7 @@ cc_err:
558 } 563 }
559 564
560 /* Return and WFI */ 565 /* Return and WFI */
566 INIT_COMPLETION(di->ab8500_fg_started);
561 INIT_COMPLETION(di->ab8500_fg_complete); 567 INIT_COMPLETION(di->ab8500_fg_complete);
562 enable_irq(di->irq); 568 enable_irq(di->irq);
563 569
@@ -569,6 +575,17 @@ fail:
569} 575}
570 576
571/** 577/**
578 * ab8500_fg_inst_curr_started() - check if fg conversion has started
579 * @di: pointer to the ab8500_fg structure
580 *
581 * Returns 1 if conversion started, 0 if still waiting
582 */
583int ab8500_fg_inst_curr_started(struct ab8500_fg *di)
584{
585 return completion_done(&di->ab8500_fg_started);
586}
587
588/**
572 * ab8500_fg_inst_curr_done() - check if fg conversion is done 589 * ab8500_fg_inst_curr_done() - check if fg conversion is done
573 * @di: pointer to the ab8500_fg structure 590 * @di: pointer to the ab8500_fg structure
574 * 591 *
@@ -596,13 +613,15 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res)
596 int timeout; 613 int timeout;
597 614
598 if (!completion_done(&di->ab8500_fg_complete)) { 615 if (!completion_done(&di->ab8500_fg_complete)) {
599 timeout = wait_for_completion_timeout(&di->ab8500_fg_complete, 616 timeout = wait_for_completion_timeout(
617 &di->ab8500_fg_complete,
600 INS_CURR_TIMEOUT); 618 INS_CURR_TIMEOUT);
601 dev_dbg(di->dev, "Finalize time: %d ms\n", 619 dev_dbg(di->dev, "Finalize time: %d ms\n",
602 ((INS_CURR_TIMEOUT - timeout) * 1000) / HZ); 620 ((INS_CURR_TIMEOUT - timeout) * 1000) / HZ);
603 if (!timeout) { 621 if (!timeout) {
604 ret = -ETIME; 622 ret = -ETIME;
605 disable_irq(di->irq); 623 disable_irq(di->irq);
624 di->nbr_cceoc_irq_cnt = 0;
606 dev_err(di->dev, "completion timed out [%d]\n", 625 dev_err(di->dev, "completion timed out [%d]\n",
607 __LINE__); 626 __LINE__);
608 goto fail; 627 goto fail;
@@ -610,6 +629,7 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res)
610 } 629 }
611 630
612 disable_irq(di->irq); 631 disable_irq(di->irq);
632 di->nbr_cceoc_irq_cnt = 0;
613 633
614 ret = abx500_mask_and_set_register_interruptible(di->dev, 634 ret = abx500_mask_and_set_register_interruptible(di->dev,
615 AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG, 635 AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG,
@@ -684,6 +704,7 @@ fail:
684int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di) 704int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di)
685{ 705{
686 int ret; 706 int ret;
707 int timeout;
687 int res = 0; 708 int res = 0;
688 709
689 ret = ab8500_fg_inst_curr_start(di); 710 ret = ab8500_fg_inst_curr_start(di);
@@ -692,13 +713,32 @@ int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di)
692 return 0; 713 return 0;
693 } 714 }
694 715
716 /* Wait for CC to actually start */
717 if (!completion_done(&di->ab8500_fg_started)) {
718 timeout = wait_for_completion_timeout(
719 &di->ab8500_fg_started,
720 INS_CURR_TIMEOUT);
721 dev_dbg(di->dev, "Start time: %d ms\n",
722 ((INS_CURR_TIMEOUT - timeout) * 1000) / HZ);
723 if (!timeout) {
724 ret = -ETIME;
725 dev_err(di->dev, "completion timed out [%d]\n",
726 __LINE__);
727 goto fail;
728 }
729 }
730
695 ret = ab8500_fg_inst_curr_finalize(di, &res); 731 ret = ab8500_fg_inst_curr_finalize(di, &res);
696 if (ret) { 732 if (ret) {
697 dev_err(di->dev, "Failed to finalize fg_inst\n"); 733 dev_err(di->dev, "Failed to finalize fg_inst\n");
698 return 0; 734 return 0;
699 } 735 }
700 736
737 dev_dbg(di->dev, "%s instant current: %d", __func__, res);
701 return res; 738 return res;
739fail:
740 mutex_unlock(&di->cc_lock);
741 return ret;
702} 742}
703 743
704/** 744/**
@@ -1523,8 +1563,6 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di)
1523 1563
1524 case AB8500_FG_DISCHARGE_WAKEUP: 1564 case AB8500_FG_DISCHARGE_WAKEUP:
1525 ab8500_fg_coulomb_counter(di, true); 1565 ab8500_fg_coulomb_counter(di, true);
1526 di->inst_curr = ab8500_fg_inst_curr_blocking(di);
1527
1528 ab8500_fg_calc_cap_discharge_voltage(di, true); 1566 ab8500_fg_calc_cap_discharge_voltage(di, true);
1529 1567
1530 di->fg_samples = SEC_TO_SAMPLE( 1568 di->fg_samples = SEC_TO_SAMPLE(
@@ -1641,8 +1679,6 @@ static void ab8500_fg_periodic_work(struct work_struct *work)
1641 fg_periodic_work.work); 1679 fg_periodic_work.work);
1642 1680
1643 if (di->init_capacity) { 1681 if (di->init_capacity) {
1644 /* A dummy read that will return 0 */
1645 di->inst_curr = ab8500_fg_inst_curr_blocking(di);
1646 /* Get an initial capacity calculation */ 1682 /* Get an initial capacity calculation */
1647 ab8500_fg_calc_cap_discharge_voltage(di, true); 1683 ab8500_fg_calc_cap_discharge_voltage(di, true);
1648 ab8500_fg_check_capacity_limits(di, true); 1684 ab8500_fg_check_capacity_limits(di, true);
@@ -1828,7 +1864,13 @@ static void ab8500_fg_instant_work(struct work_struct *work)
1828static irqreturn_t ab8500_fg_cc_data_end_handler(int irq, void *_di) 1864static irqreturn_t ab8500_fg_cc_data_end_handler(int irq, void *_di)
1829{ 1865{
1830 struct ab8500_fg *di = _di; 1866 struct ab8500_fg *di = _di;
1831 complete(&di->ab8500_fg_complete); 1867 if (!di->nbr_cceoc_irq_cnt) {
1868 di->nbr_cceoc_irq_cnt++;
1869 complete(&di->ab8500_fg_started);
1870 } else {
1871 di->nbr_cceoc_irq_cnt = 0;
1872 complete(&di->ab8500_fg_complete);
1873 }
1832 return IRQ_HANDLED; 1874 return IRQ_HANDLED;
1833} 1875}
1834 1876
@@ -2551,7 +2593,11 @@ static int ab8500_fg_probe(struct platform_device *pdev)
2551 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); 2593 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer);
2552 ab8500_fg_coulomb_counter(di, true); 2594 ab8500_fg_coulomb_counter(di, true);
2553 2595
2554 /* Initialize completion used to notify completion of inst current */ 2596 /*
2597 * Initialize completion used to notify completion and start
2598 * of inst current
2599 */
2600 init_completion(&di->ab8500_fg_started);
2555 init_completion(&di->ab8500_fg_complete); 2601 init_completion(&di->ab8500_fg_complete);
2556 2602
2557 /* Register interrupts */ 2603 /* Register interrupts */
@@ -2571,6 +2617,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
2571 } 2617 }
2572 di->irq = platform_get_irq_byname(pdev, "CCEOC"); 2618 di->irq = platform_get_irq_byname(pdev, "CCEOC");
2573 disable_irq(di->irq); 2619 disable_irq(di->irq);
2620 di->nbr_cceoc_irq_cnt = 0;
2574 2621
2575 platform_set_drvdata(pdev, di); 2622 platform_set_drvdata(pdev, di);
2576 2623