diff options
author | merge <null@invalid> | 2008-12-08 22:50:52 +0000 |
---|---|---|
committer | Andy Green <agreen@pads.home.warmcat.com> | 2008-12-08 22:50:52 +0000 |
commit | ebb3f320edcc6c4665a71ea060ef2ce6a83402b0 (patch) | |
tree | bcc900f37c2f7ab72addce6555263bfe1dd85aca /drivers/power | |
parent | 31383993decd60a7cc783f402ad83ee8580008d3 (diff) |
MERGE-via-pending-tracking-hist-MERGE-via-stable-tracking-fix-s3c2410_ts-fifo-allocation-1228776491
pending-tracking-hist top was MERGE-via-stable-tracking-fix-s3c2410_ts-fifo-allocation-1228776491 / a85a8a282939b4f6800081f67e1d568e0b97bd7a ... parent commitmessage:
From: merge <null@invalid>
MERGE-via-stable-tracking-hist-fix-s3c2410_ts-fifo-allocation
stable-tracking-hist top was fix-s3c2410_ts-fifo-allocation / 56a57ba0d4c1d60869250d5f89fae61544f01012 ... parent commitmessage:
From: Nelson Castillo <nelsoneci@gmail.com>
Fix s3c2410_ts FIFO allocation
When I added the FIFO improving the interrupts handlers I introduced a bug.
The FIFO is allocated after the interrupts are requested. This makes the kernel
crash if the touchscreen generates activity before the allocation takes place.
This patch fixes the bug. I reproduced it and tested the fix in a GTA02.
- Fix bug
- Fix a typo
Reported-by: Andy Green <andy@openmoko.com>
Signed-off-by: Nelson Castillo <nelsoneci@gmail.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/pcf50633-charger.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 9bbfaac48a1..8e302c6c40e 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -23,9 +23,90 @@ * MA 02111-1307 USA */ +#include <linux/delay.h> #include <linux/mfd/pcf50633/core.h> #include <linux/mfd/pcf50633/mbc.h> +/* this tells us the answer to "how am I set for power?" */ + +enum pcf50633_power_avail pcf50633_check_power_available(struct pcf50633 *pcf) +{ + int ret; + int battery_ok; + int usb_present; + + /* first look for adapter and USB power status */ + + ret = pcf50633_reg_read(pcf, PCF50633_REG_MBCS1); + if (ret < 0) + return ret; + + if (ret & 8) /* adapter power present */ + return PCF50633_PA_ADAPTER; /* don't care about anything else */ + + usb_present = ret & 2; + + /* measure battery using PMU ADC */ + /* disable charging momentarily so we can measure battery */ + + ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, 1, 0); + if (ret < 0) + return ret; + + ret = pcf50633_adc_sync_read(pcf, PCF50633_ADCC1_MUX_BATSNS_RES, + PCF50633_ADCC1_AVERAGE_16); + if (ret < 0) + return ret; + + battery_ok = (ret > pcf->pdata->good_main_battery_adc_threshold); + + /* enable charging again */ + + ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, 1, 1); + if (ret < 0) + return ret; + + /* + * now we know battery and USB situation + * make the decision now if possible + */ + + if (!usb_present && !battery_ok) + return PCF50633_PA_DEAD_BATTERY_ONLY; + + if (!usb_present && battery_ok) + return PCF50633_PA_LIVE_BATTERY_ONLY; + + /* So USB is present... what current limit? */ + + ret = pcf50633_reg_read(pcf, PCF50633_REG_MBCC7); + if (ret < 0) + return ret; + + switch (ret & PCF50633_MBCC7_USB_MASK) { + + case PCF50633_MBCC7_USB_100mA: + if (battery_ok) + return PCF50633_PA_USB_100mA_AND_LIVE_BATTERY; + else + return PCF50633_PA_USB_100mA_AND_DEAD_BATTERY; + + case PCF50633_MBCC7_USB_500mA: + return PCF50633_PA_USB_500mA; + + case PCF50633_MBCC7_USB_1000mA: + return PCF50633_PA_USB_1A; + + default: + if (battery_ok) + return PCF50633_PA_LIVE_BATTERY_ONLY; + else + return PCF50633_PA_DEAD_BATTERY_ONLY; + } + + return PCF50633_PA_DEAD_BATTERY_ONLY; +} + void pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) { int ret; |