diff options
author | M BenZoubeir <mustapha.ben.zoubeir-xsig@stericsson.com> | 2012-09-13 04:34:18 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-03-06 23:35:51 -0500 |
commit | f4095a0f06476e5914f2c58b4e96258b2e2ba6b7 (patch) | |
tree | 74acc75bc17ef1e7a8cbf57dd1b541d9aa239872 /drivers/power/pm2301_charger.c | |
parent | b3ea5f451e4e435b650e34142f8552002dc21297 (diff) |
pm2301-charger: Adjust interrupt handler behavior
Signed-off-by: M BenZoubeir <mustapha.ben.zoubeir-xsig@stericsson.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Diffstat (limited to 'drivers/power/pm2301_charger.c')
-rw-r--r-- | drivers/power/pm2301_charger.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index b8eafc3850d0..eed8a89ba4f0 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c | |||
@@ -493,14 +493,16 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data) | |||
493 | struct pm2xxx_interrupts *interrupt = pm2->pm2_int; | 493 | struct pm2xxx_interrupts *interrupt = pm2->pm2_int; |
494 | int i; | 494 | int i; |
495 | 495 | ||
496 | for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { | 496 | do { |
497 | pm2xxx_reg_read(pm2, | 497 | for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { |
498 | pm2xxx_reg_read(pm2, | ||
498 | pm2xxx_interrupt_registers[i], | 499 | pm2xxx_interrupt_registers[i], |
499 | &(interrupt->reg[i])); | 500 | &(interrupt->reg[i])); |
500 | 501 | ||
501 | if (interrupt->reg[i] > 0) | 502 | if (interrupt->reg[i] > 0) |
502 | interrupt->handler[i](pm2, interrupt->reg[i]); | 503 | interrupt->handler[i](pm2, interrupt->reg[i]); |
503 | } | 504 | } |
505 | } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0); | ||
504 | 506 | ||
505 | return IRQ_HANDLED; | 507 | return IRQ_HANDLED; |
506 | } | 508 | } |
@@ -951,6 +953,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
951 | struct pm2xxx_charger *pm2; | 953 | struct pm2xxx_charger *pm2; |
952 | int ret = 0; | 954 | int ret = 0; |
953 | u8 val; | 955 | u8 val; |
956 | int i; | ||
954 | 957 | ||
955 | pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL); | 958 | pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL); |
956 | if (!pm2) { | 959 | if (!pm2) { |
@@ -1062,24 +1065,25 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
1062 | } | 1065 | } |
1063 | 1066 | ||
1064 | /* Register interrupts */ | 1067 | /* Register interrupts */ |
1065 | ret = request_threaded_irq(pm2->pdata->irq_number, NULL, | 1068 | ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), |
1069 | NULL, | ||
1066 | pm2xxx_charger_irq[0].isr, | 1070 | pm2xxx_charger_irq[0].isr, |
1067 | pm2->pdata->irq_type, | 1071 | pm2->pdata->irq_type, |
1068 | pm2xxx_charger_irq[0].name, pm2); | 1072 | pm2xxx_charger_irq[0].name, pm2); |
1069 | 1073 | ||
1070 | if (ret != 0) { | 1074 | if (ret != 0) { |
1071 | dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n", | 1075 | dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n", |
1072 | pm2xxx_charger_irq[0].name, pm2->pdata->irq_number, ret); | 1076 | pm2xxx_charger_irq[0].name, |
1077 | gpio_to_irq(pm2->pdata->gpio_irq_number), ret); | ||
1073 | goto unregister_pm2xxx_charger; | 1078 | goto unregister_pm2xxx_charger; |
1074 | } | 1079 | } |
1075 | /* pm interrupt can wake up system */ | 1080 | /* pm interrupt can wake up system */ |
1076 | ret = enable_irq_wake(pm2->pdata->irq_number); | 1081 | ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); |
1077 | if (ret) { | 1082 | if (ret) { |
1078 | dev_err(pm2->dev, "failed to set irq wake\n"); | 1083 | dev_err(pm2->dev, "failed to set irq wake\n"); |
1079 | goto unregister_pm2xxx_interrupt; | 1084 | goto unregister_pm2xxx_interrupt; |
1080 | } | 1085 | } |
1081 | 1086 | ||
1082 | /*Initialize lock*/ | ||
1083 | mutex_init(&pm2->lock); | 1087 | mutex_init(&pm2->lock); |
1084 | 1088 | ||
1085 | /* | 1089 | /* |
@@ -1099,16 +1103,16 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
1099 | } | 1103 | } |
1100 | 1104 | ||
1101 | set_lpn_pin(pm2); | 1105 | set_lpn_pin(pm2); |
1106 | |||
1107 | /* read interrupt registers */ | ||
1108 | for (i = 0; i < PM2XXX_NUM_INT_REG; i++) | ||
1109 | pm2xxx_reg_read(pm2, | ||
1110 | pm2xxx_interrupt_registers[i], | ||
1111 | &val); | ||
1112 | |||
1102 | ret = pm2xxx_charger_detection(pm2, &val); | 1113 | ret = pm2xxx_charger_detection(pm2, &val); |
1103 | 1114 | ||
1104 | if ((ret == 0) && val) { | 1115 | if ((ret == 0) && val) { |
1105 | /* | ||
1106 | * When boot is due to AC charger plug-in, | ||
1107 | * read interrupt registers | ||
1108 | */ | ||
1109 | pm2xxx_reg_read(pm2, PM2XXX_REG_INT1, &val); | ||
1110 | pm2xxx_reg_read(pm2, PM2XXX_REG_INT2, &val); | ||
1111 | pm2xxx_reg_read(pm2, PM2XXX_REG_INT4, &val); | ||
1112 | pm2->ac.charger_connected = 1; | 1116 | pm2->ac.charger_connected = 1; |
1113 | ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, | 1117 | ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, |
1114 | AB8500_MAIN_CH_DET); | 1118 | AB8500_MAIN_CH_DET); |
@@ -1122,10 +1126,10 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
1122 | free_gpio: | 1126 | free_gpio: |
1123 | gpio_free(pm2->lpn_pin); | 1127 | gpio_free(pm2->lpn_pin); |
1124 | disable_pm2_irq_wake: | 1128 | disable_pm2_irq_wake: |
1125 | disable_irq_wake(pm2->pdata->irq_number); | 1129 | disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); |
1126 | unregister_pm2xxx_interrupt: | 1130 | unregister_pm2xxx_interrupt: |
1127 | /* disable interrupt */ | 1131 | /* disable interrupt */ |
1128 | free_irq(pm2->pdata->irq_number, pm2); | 1132 | free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); |
1129 | unregister_pm2xxx_charger: | 1133 | unregister_pm2xxx_charger: |
1130 | /* unregister power supply */ | 1134 | /* unregister power supply */ |
1131 | power_supply_unregister(&pm2->ac_chg.psy); | 1135 | power_supply_unregister(&pm2->ac_chg.psy); |
@@ -1148,10 +1152,10 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) | |||
1148 | pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); | 1152 | pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); |
1149 | 1153 | ||
1150 | /* Disable wake by pm interrupt */ | 1154 | /* Disable wake by pm interrupt */ |
1151 | disable_irq_wake(pm2->pdata->irq_number); | 1155 | disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); |
1152 | 1156 | ||
1153 | /* Disable interrupts */ | 1157 | /* Disable interrupts */ |
1154 | free_irq(pm2->pdata->irq_number, pm2); | 1158 | free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); |
1155 | 1159 | ||
1156 | /* Delete the work queue */ | 1160 | /* Delete the work queue */ |
1157 | destroy_workqueue(pm2->charger_wq); | 1161 | destroy_workqueue(pm2->charger_wq); |
@@ -1163,7 +1167,6 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) | |||
1163 | 1167 | ||
1164 | power_supply_unregister(&pm2->ac_chg.psy); | 1168 | power_supply_unregister(&pm2->ac_chg.psy); |
1165 | 1169 | ||
1166 | /*Free GPIO60*/ | ||
1167 | gpio_free(pm2->lpn_pin); | 1170 | gpio_free(pm2->lpn_pin); |
1168 | 1171 | ||
1169 | kfree(pm2); | 1172 | kfree(pm2); |