diff options
| author | Richard Purdie <rpurdie@rpsys.net> | 2008-01-20 16:48:44 +0000 |
|---|---|---|
| committer | Richard Purdie <rpurdie@rpsys.net> | 2008-01-20 16:48:44 +0000 |
| commit | a7d62d2e454c0ef4b398cbc3e32577aa46ea99b8 (patch) | |
| tree | 13fc934f7889cdaa703aeb83b280acdd85a3f159 /packages/linux | |
| parent | ea309efcf78e31727afdeaf025e3192e982d0834 (diff) | |
linux-rp-2.6.23: Clean up and drop unused or now unneeded patches
Diffstat (limited to 'packages/linux')
| -rw-r--r-- | packages/linux/linux-rp-2.6.23/mmcsd_no_scr_check-r2.patch | 29 | ||||
| -rw-r--r-- | packages/linux/linux-rp-2.6.23/pda-power.patch | 3373 | ||||
| -rw-r--r-- | packages/linux/linux-rp-2.6.23/vt_ioctl_race.patch | 46 | ||||
| -rw-r--r-- | packages/linux/linux-rp-2.6.23/w100fb-unused-var.patch | 17 | ||||
| -rw-r--r-- | packages/linux/linux-rp_2.6.23.bb | 35 |
5 files changed, 17 insertions, 3483 deletions
diff --git a/packages/linux/linux-rp-2.6.23/mmcsd_no_scr_check-r2.patch b/packages/linux/linux-rp-2.6.23/mmcsd_no_scr_check-r2.patch deleted file mode 100644 index ac2245f088..0000000000 --- a/packages/linux/linux-rp-2.6.23/mmcsd_no_scr_check-r2.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- - drivers/mmc/core/sd.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -Index: linux-2.6.23/drivers/mmc/core/sd.c -=================================================================== ---- linux-2.6.23.orig/drivers/mmc/core/sd.c 2007-10-17 11:33:26.000000000 +0200 -+++ linux-2.6.23/drivers/mmc/core/sd.c 2007-10-17 11:33:49.000000000 +0200 -@@ -173,14 +173,15 @@ - - scr_struct = UNSTUFF_BITS(resp, 60, 4); - if (scr_struct != 0) { -- printk(KERN_ERR "%s: unrecognised SCR structure version %d\n", -+ printk(KERN_WARNING "%s: unrecognised SCR structure version %d\n", - mmc_hostname(card->host), scr_struct); -- return -EINVAL; -+ scr->sda_vsn = 0; -+ scr->bus_widths = 0; -+ } else { -+ scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); -+ scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); - } - -- scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); -- scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); -- - return 0; - } - diff --git a/packages/linux/linux-rp-2.6.23/pda-power.patch b/packages/linux/linux-rp-2.6.23/pda-power.patch deleted file mode 100644 index face2f4ef2..0000000000 --- a/packages/linux/linux-rp-2.6.23/pda-power.patch +++ /dev/null @@ -1,3373 +0,0 @@ ---- - arch/arm/Kconfig | 2 - drivers/Kconfig | 2 - drivers/Makefile | 1 - drivers/power/Kconfig | 70 +++++ - drivers/power/Makefile | 28 ++ - drivers/power/adc_battery.c | 278 +++++++++++++++++++++ - drivers/power/apm_power.c | 247 +++++++++++++++++++ - drivers/power/ds2760_battery.c | 475 +++++++++++++++++++++++++++++++++++++ - drivers/power/micro_battery.c | 257 ++++++++++++++++++++ - drivers/power/olpc_battery.c | 302 +++++++++++++++++++++++ - drivers/power/pda_power.c | 263 ++++++++++++++++++++ - drivers/power/pmu_battery.c | 215 ++++++++++++++++ - drivers/power/power_supply.h | 42 +++ - drivers/power/power_supply_core.c | 168 +++++++++++++ - drivers/power/power_supply_leds.c | 188 ++++++++++++++ - drivers/power/power_supply_sysfs.c | 289 ++++++++++++++++++++++ - drivers/power/simpad-battery.c | 242 ++++++++++++++++++ - include/linux/power_supply.h | 175 +++++++++++++ - 18 files changed, 3244 insertions(+) - -Index: linux-2.6.22/drivers/power/adc_battery.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22/drivers/power/adc_battery.c 2007-08-23 12:26:28.000000000 +0200 -@@ -0,0 +1,278 @@ -+/* -+ * Copyright (c) 2007 Paul Sokolovsky -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+ -+//#define DEBUG -+ -+#include <linux/module.h> -+#include <linux/interrupt.h> -+#include <linux/pm.h> -+#include <linux/delay.h> -+#include <linux/workqueue.h> -+#include <linux/platform_device.h> -+#include <linux/power_supply.h> -+#include <linux/adc.h> -+#include <linux/adc_battery.h> -+ -+#include <asm/irq.h> -+ -+#define PIN_NO_VOLT 0 -+#define PIN_NO_CURR 1 -+#define PIN_NO_TEMP 2 -+ -+struct battery_adc_priv { -+ struct power_supply batt_cdev; -+ -+ struct battery_adc_platform_data *pdata; -+ -+ struct adc_request req; -+ struct adc_sense pins[3]; -+ struct adc_sense last_good_pins[3]; -+ -+ struct workqueue_struct *wq; -+ struct delayed_work work; -+}; -+ -+/* -+ * Battery properties -+ */ -+ -+static int adc_battery_get_property(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ struct battery_adc_priv* drvdata = (struct battery_adc_priv*)psy; -+ int voltage; -+ -+ switch (psp) { -+ case POWER_SUPPLY_PROP_STATUS: -+ val->intval = drvdata->pdata->charge_status; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: -+ val->intval = drvdata->pdata->battery_info.voltage_max_design; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: -+ val->intval = drvdata->pdata->battery_info.voltage_min_design; -+ break; -+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: -+ val->intval = drvdata->pdata->battery_info.charge_full_design; -+ break; -+ case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: -+ val->intval = drvdata->pdata->battery_info.charge_empty_design; -+ break; -+ case POWER_SUPPLY_PROP_VOLTAGE_NOW: -+ val->intval = drvdata->last_good_pins[PIN_NO_VOLT].value * drvdata->pdata->voltage_mult; -+ break; -+ case POWER_SUPPLY_PROP_CURRENT_NOW: -+ val->intval = drvdata->last_good_pins[PIN_NO_CURR].value * drvdata->pdata->current_mult; -+ break; -+ case POWER_SUPPLY_PROP_CHARGE_NOW: -+ /* We do calculations in mX, not uX, because todo it in uX we should use "long long"s, -+ * which is a mess (need to use do_div) when you need divide operation). */ -+ voltage = drvdata->last_good_pins[PIN_NO_VOLT].value * drvdata->pdata->voltage_mult; -+ val->intval = ((voltage/1000 - drvdata->pdata->battery_info.voltage_min_design/1000) * -+ (drvdata->pdata->battery_info.charge_full_design/1000 - -+ drvdata->pdata->battery_info.charge_empty_design/1000)) / -+ (drvdata->pdata->battery_info.voltage_max_design/1000 - -+ drvdata->pdata->battery_info.voltage_min_design/1000); -+ val->intval *= 1000; /* convert final result to uX */ -+ break; -+ case POWER_SUPPLY_PROP_TEMP: -+ val->intval = drvdata->last_good_pins[PIN_NO_TEMP].value * drvdata->pdata->temperature_mult / 1000; -+ break; -+ default: -+ return -EINVAL; -+ }; -+ return 0; -+} -+ -+/* -+ * Driver body -+ */ -+ -+static void adc_battery_query(struct battery_adc_priv *drvdata) -+{ -+ struct battery_adc_platform_data *pdata = drvdata->pdata; -+ int powered, charging; -+ -+ adc_request_sample(&drvdata->req); -+ -+ powered = power_supply_am_i_supplied(&drvdata->batt_cdev); -+ charging = pdata->is_charging ? pdata->is_charging() : -1; -+ -+ if (powered && charging) -+ pdata->charge_status = POWER_SUPPLY_STATUS_CHARGING; -+ else if (powered && !charging && charging != -1) -+ pdata->charge_status = POWER_SUPPLY_STATUS_FULL; -+ else -+ pdata->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; -+ -+ /* Throw away invalid samples, this may happen soon after resume for example. */ -+ if (drvdata->pins[PIN_NO_VOLT].value > 0) { -+ memcpy(drvdata->last_good_pins, drvdata->pins, sizeof(drvdata->pins)); -+#ifdef DEBUG -+ printk("%d %d %d\n", drvdata->pins[PIN_NO_VOLT].value, -+ drvdata->pins[PIN_NO_CURR].value, -+ drvdata->pins[PIN_NO_TEMP].value); -+#endif -+ } -+} -+ -+static void adc_battery_charge_power_changed(struct power_supply *bat) -+{ -+ struct battery_adc_priv *drvdata = (struct battery_adc_priv*)bat; -+ cancel_delayed_work(&drvdata->work); -+ queue_delayed_work(drvdata->wq, &drvdata->work, 0); -+} -+ -+static void adc_battery_work_func(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work = container_of(work, struct delayed_work, work); -+ struct battery_adc_priv *drvdata = container_of(delayed_work, struct battery_adc_priv, work); -+ -+ adc_battery_query(drvdata); -+ power_supply_changed(&drvdata->batt_cdev); -+ -+ queue_delayed_work(drvdata->wq, &drvdata->work, (5000 * HZ) / 1000); -+} -+ -+static int adc_battery_probe(struct platform_device *pdev) -+{ -+ int retval; -+ struct battery_adc_platform_data *pdata = pdev->dev.platform_data; -+ struct battery_adc_priv *drvdata; -+ int i, j; -+ enum power_supply_property props[] = { -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_CURRENT_NOW, -+ POWER_SUPPLY_PROP_CHARGE_NOW, -+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, -+ POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, -+ POWER_SUPPLY_PROP_TEMP, -+ }; -+ -+ // Initialize ts data structure. -+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); -+ if (!drvdata) -+ return -ENOMEM; -+ -+ drvdata->batt_cdev.name = pdata->battery_info.name; -+ drvdata->batt_cdev.use_for_apm = pdata->battery_info.use_for_apm; -+ drvdata->batt_cdev.num_properties = ARRAY_SIZE(props); -+ drvdata->batt_cdev.get_property = adc_battery_get_property; -+ drvdata->batt_cdev.external_power_changed = -+ adc_battery_charge_power_changed; -+ -+ if (!pdata->voltage_pin) { -+ drvdata->batt_cdev.num_properties--; -+ props[3] = -1; -+ } -+ if (!pdata->current_pin) { -+ drvdata->batt_cdev.num_properties--; -+ props[4] = -1; -+ } -+ if (!pdata->temperature_pin) { -+ drvdata->batt_cdev.num_properties--; -+ props[8] = -1; -+ } -+ -+ drvdata->batt_cdev.properties = kmalloc( -+ sizeof(*drvdata->batt_cdev.properties) * -+ drvdata->batt_cdev.num_properties, GFP_KERNEL); -+ if (!drvdata->batt_cdev.properties) -+ return -ENOMEM; -+ -+ j = 0; -+ for (i = 0; i < ARRAY_SIZE(props); i++) { -+ if (props[i] == -1) -+ continue; -+ drvdata->batt_cdev.properties[j++] = props[i]; -+ } -+ -+ retval = power_supply_register(&pdev->dev, &drvdata->batt_cdev); -+ if (retval) { -+ printk("adc-battery: Error registering battery classdev"); -+ return retval; -+ } -+ -+ drvdata->req.senses = drvdata->pins; -+ drvdata->req.num_senses = ARRAY_SIZE(drvdata->pins); -+ drvdata->pins[PIN_NO_VOLT].name = pdata->voltage_pin; -+ drvdata->pins[PIN_NO_CURR].name = pdata->current_pin; -+ drvdata->pins[PIN_NO_TEMP].name = pdata->temperature_pin; -+ -+ adc_request_register(&drvdata->req); -+ -+ /* Here we assume raw values in mV */ -+ if (!pdata->voltage_mult) -+ pdata->voltage_mult = 1000; -+ /* Here we assume raw values in mA */ -+ if (!pdata->current_mult) -+ pdata->current_mult = 1000; -+ /* Here we assume raw values in 1/10 C */ -+ if (!pdata->temperature_mult) -+ pdata->temperature_mult = 1000; -+ -+ drvdata->pdata = pdata; -+ pdata->drvdata = drvdata; /* Seems ugly, we need better solution */ -+ -+ platform_set_drvdata(pdev, drvdata); -+ -+ // Load initial values ASAP -+ adc_battery_query(drvdata); -+ -+ // Still schedule next sampling soon -+ INIT_DELAYED_WORK(&drvdata->work, adc_battery_work_func); -+ drvdata->wq = create_workqueue(pdev->dev.bus_id); -+ if (!drvdata->wq) -+ return -ESRCH; -+ -+ queue_delayed_work(drvdata->wq, &drvdata->work, (5000 * HZ) / 1000); -+ -+ return retval; -+} -+ -+static int adc_battery_remove(struct platform_device *pdev) -+{ -+ struct battery_adc_priv *drvdata = platform_get_drvdata(pdev); -+ cancel_delayed_work(&drvdata->work); -+ destroy_workqueue(drvdata->wq); -+ power_supply_unregister(&drvdata->batt_cdev); -+ adc_request_unregister(&drvdata->req); -+ kfree(drvdata->batt_cdev.properties); -+ return 0; -+} -+ -+static struct platform_driver adc_battery_driver = { -+ .driver = { -+ .name = "adc-battery", -+ }, -+ .probe = adc_battery_probe, -+ .remove = adc_battery_remove, -+}; -+ -+static int __init adc_battery_init(void) -+{ -+ return platform_driver_register(&adc_battery_driver); -+} -+ -+static void __exit adc_battery_exit(void) -+{ -+ platform_driver_unregister(&adc_battery_driver); -+} -+ -+module_init(adc_battery_init) -+module_exit(adc_battery_exit) -+ -+MODULE_AUTHOR("Paul Sokolovsky"); -+MODULE_DESCRIPTION("Battery driver for ADC device"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.22/drivers/power/apm_power.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22/drivers/power/apm_power.c 2007-08-23 12:13:52.000000000 +0200 -@@ -0,0 +1,247 @@ -+/* -+ * Copyright (c) 2007 Anton Vorontsov <cbou@mail.ru> -+ * Copyright (c) 2007 Eugeny Boger <eugenyboger@dgap.mipt.ru> -+ * -+ * Author: Eugeny Boger <eugenyboger@dgap.mipt.ru> -+ * -+ * Use consistent with the GNU GPL is permitted, -+ * provided that this copyright notice is -+ * preserved in its entirety in all copies and derived works. -+ */ -+ -+#include <linux/module.h> -+#include <linux/power_supply.h> -+#include <linux/apm-emulation.h> -+ -+#define PSY_PROP(psy, prop, val) psy->get_property(psy, \ -+ POWER_SUPPLY_PROP_##prop, val) -+ -+#define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \ -+ prop, val) -+ -+#define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) -+ -+static struct power_supply *main_battery; -+ -+static void find_main_battery(void) -+{ -+ struct device *dev; -+ struct power_supply *bat, *batm; -+ union power_supply_propval full; -+ int max_charge = 0; -+ -+ main_battery = NULL; -+ batm = NULL; -+ list_for_each_entry(dev, &power_supply_class->devices, node) { -+ bat = dev_get_drvdata(dev); -+ /* If none of battery devices cantains 'use_for_apm' flag, -+ choice one with maximum design charge */ -+ if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) { -+ if (full.intval > max_charge) { -+ batm = bat; -+ max_charge = full.intval; -+ } -+ } -+ -+ if (bat->use_for_apm) -+ main_battery = bat; -+ } -+ if (!main_battery) -+ main_battery = batm; -+ -+ return; -+} -+ -+static int calculate_time(int status) -+{ -+ union power_supply_propval charge_full, charge_empty; -+ union power_supply_propval charge, I; -+ -+ if (MPSY_PROP(CHARGE_FULL, &charge_full)) { -+ /* if battery can't report this property, use design value */ -+ if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full)) -+ return -1; -+ } -+ -+ if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) { -+ /* if battery can't report this property, use design value */ -+ if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty)) -+ charge_empty.intval = 0; -+ } -+ -+ if (MPSY_PROP(CHARGE_AVG, &charge)) { -+ /* if battery can't report average value, use momentary */ -+ if (MPSY_PROP(CHARGE_NOW, &charge)) -+ return -1; -+ } -+ -+ if (MPSY_PROP(CURRENT_AVG, &I)) { -+ /* if battery can't report average value, use momentary */ -+ if (MPSY_PROP(CURRENT_NOW, &I)) -+ return -1; -+ } -+ -+ if (I.intval == 0) -+ return 0; -+ else if (status == POWER_SUPPLY_STATUS_CHARGING) -+ return ((charge.intval - charge_full.intval) * 60L) / -+ I.intval; -+ else -+ return -((charge.intval - charge_empty.intval) * 60L) / -+ I.intval; -+} -+ -+static int calculate_capacity(int using_charge) -+{ -+ enum power_supply_property full_prop, empty_prop; -+ enum power_supply_property full_design_prop, empty_design_prop; -+ enum power_supply_property now_prop, avg_prop; -+ union power_supply_propval empty, full, cur; -+ int ret; -+ -+ if (using_charge) { -+ full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; -+ empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; -+ full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; -+ empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN; -+ now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; -+ avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; -+ } -+ else { -+ full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; -+ empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; -+ full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; -+ empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; -+ now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; -+ avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; -+ } -+ -+ if (_MPSY_PROP(full_prop, &full)) { -+ /* if battery can't report this property, use design value */ -+ if (_MPSY_PROP(full_design_prop, &full)) -+ return -1; -+ } -+ -+ if (_MPSY_PROP(avg_prop, &cur)) { -+ /* if battery can't report average value, use momentary */ -+ if (_MPSY_PROP(now_prop, &cur)) -+ return -1; -+ } -+ -+ if (_MPSY_PROP(empty_prop, &empty)) { -+ /* if battery can't report this property, use design value */ -+ if (_MPSY_PROP(empty_design_prop, &empty)) -+ empty.intval = 0; -+ } -+ -+ if (full.intval - empty.intval) -+ ret = ((cur.intval - empty.intval) * 100L) / -+ (full.intval - empty.intval); -+ else -+ return -1; -+ -+ if (ret > 100) -+ return 100; -+ else if (ret < 0) -+ return 0; -+ -+ return ret; -+} -+ -+static void apm_battery_apm_get_power_status(struct apm_power_info *info) -+{ -+ union power_supply_propval status; -+ union power_supply_propval capacity, time_to_full, time_to_empty; -+ -+ down(&power_supply_class->sem); -+ find_main_battery(); -+ if (!main_battery) { -+ up(&power_supply_class->sem); -+ return; -+ } -+ -+ /* status */ -+ -+ if (MPSY_PROP(STATUS, &status)) -+ status.intval = POWER_SUPPLY_STATUS_UNKNOWN; -+ -+ /* ac line status */ -+ -+ if ((status.intval == POWER_SUPPLY_STATUS_CHARGING) || -+ (status.intval == POWER_SUPPLY_STATUS_NOT_CHARGING) || -+ (status.intval == POWER_SUPPLY_STATUS_FULL)) -+ info->ac_line_status = APM_AC_ONLINE; -+ else -+ info->ac_line_status = APM_AC_OFFLINE; -+ -+ /* battery life (i.e. capacity, in percents) */ -+ -+ if (MPSY_PROP(CAPACITY, &capacity) == 0) -+ info->battery_life = capacity.intval; -+ else { -+ /* try calculate using energy */ -+ info->battery_life = calculate_capacity(0); -+ /* if failed try calculate using charge instead */ -+ if (info->battery_life == -1) -+ info->battery_life = calculate_capacity(1); -+ } -+ -+ /* charging status */ -+ -+ if (status.intval == POWER_SUPPLY_STATUS_CHARGING) -+ info->battery_status = APM_BATTERY_STATUS_CHARGING; -+ else { -+ if (info->battery_life > 50) -+ info->battery_status = APM_BATTERY_STATUS_HIGH; -+ else if (info->battery_life > 5) -+ info->battery_status = APM_BATTERY_STATUS_LOW; -+ else -+ info->battery_status = APM_BATTERY_STATUS_CRITICAL; -+ } -+ info->battery_flag = info->battery_status; -+ -+ /* time */ -+ -+ info->units = APM_UNITS_MINS; -+ -+ if (status.intval == POWER_SUPPLY_STATUS_CHARGING) { -+ if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) { -+ if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) -+ info->time = calculate_time(status.intval); -+ else -+ info->time = time_to_full.intval / 60; -+ } -+ } -+ else { -+ if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) { -+ if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) -+ info->time = calculate_time(status.intval); -+ else -+ info->time = time_to_empty.intval / 60; -+ } -+ } -+ -+ up(&power_supply_class->sem); -+ return; -+} -+ -+static int __init apm_battery_init(void) -+{ -+ printk(KERN_INFO "APM Battery Driver\n"); -+ -+ apm_get_power_status = apm_battery_apm_get_power_status; -+ return 0; -+} -+ -+static void __exit apm_battery_exit(void) -+{ -+ apm_get_power_status = NULL; -+ return; -+} -+ -+module_init(apm_battery_init); -+module_exit(apm_battery_exit); -+ -+MODULE_AUTHOR("Eugeny Boger <eugenyboger@dgap.mipt.ru>"); -+MODULE_DESCRIPTION("APM emulation driver for battery monitoring class"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.22/drivers/power/ds2760_battery.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22/drivers/power/ds2760_battery.c 2007-08-23 12:13:52.000000000 +0200 -@@ -0,0 +1,475 @@ -+/* -+ * Driver for batteries with DS2760 chips inside. -+ * -+ * Copyright (c) 2007 Anton Vorontsov -+ * 2004-2007 Matt Reimer -+ * 2004 Szabolcs Gyurko -+ * -+ * Use consistent with the GNU GPL is permitted, -+ * provided that this copyright notice is -+ * preserved in its entirety in all copies and derived works. -+ * -+ * Author: Anton Vorontsov <cbou@mail.ru> -+ * February 2007 -+ * -+ * Matt Reimer <mreimer@vpop.net> -+ * April 2004, 2005, 2007 -+ * -+ * Szabolcs Gyurko <szabolcs.gyurko@tlt.hu> -+ * September 2004 -+ */ -+ -+#include <linux/module.h> -+#include <linux/param.h> -+#include <linux/jiffies.h> -+#include <linux/workqueue.h> -+#include <linux/pm.h> -+#include <linux/platform_device.h> -+#include <linux/power_supply.h> -+ -+#include "../w1/w1.h" -+#include "../w1/slaves/w1_ds2760.h" -+ -+struct ds2760_device_info { -+ struct device *dev; -+ -+ /* DS2760 data, valid after calling ds2760_battery_read_status() */ -+ unsigned long update_time; /* jiffies when data read */ -+ char raw[DS2760_DATA_SIZE]; /* raw DS2760 data */ -+ int voltage_raw; /* units of 4.88 mV */ -+ int voltage_uV; /* units of uV */ -+ int current_raw; /* units of 0.625 mA */ -+ int current_uA; /* units of uA */ -+ int accum_current_raw; /* units of 0.25 mAh */ -+ int accum_current_uAh; /* units of uAh */ -+ int temp_raw; /* units of 0.125 C */ -+ int temp_C; /* units of 0.1 C */ -+ int rated_capacity; /* units of uAh */ -+ int rem_capacity; /* percentage */ -+ int full_active_uAh; /* units of uAh */ -+ int empty_uAh; /* units of uAh */ -+ int life_sec; /* units of seconds */ -+ int charge_status; /* POWER_SUPPLY_STATUS_* */ -+ -+ int full_counter; -+ struct power_supply bat; -+ struct device *w1_dev; -+ struct workqueue_struct *monitor_wqueue; -+ struct delayed_work monitor_work; -+}; -+ -+static unsigned int cache_time = 1000; -+module_param(cache_time, uint, 0644); -+MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); -+ -+/* Some batteries have their rated capacity stored a N * 10 mAh, while -+ * others use an index into this table. */ -+static int rated_capacities[] = { -+ 0, -+ 920, /* Samsung */ -+ 920, /* BYD */ -+ 920, /* Lishen */ -+ 920, /* NEC */ -+ 1440, /* Samsung */ -+ 1440, /* BYD */ -+ 1440, /* Lishen */ -+ 1440, /* NEC */ -+ 2880, /* Samsung */ -+ 2880, /* BYD */ -+ 2880, /* Lishen */ -+ 2880 /* NEC */ -+}; -+ -+/* array is level at temps 0C, 10C, 20C, 30C, 40C -+ * temp is in Celsius */ -+static int battery_interpolate(int array[], int temp) -+{ -+ int index, dt; -+ -+ if (temp <= 0) -+ return array[0]; -+ if (temp >= 40) -+ return array[4]; -+ -+ index = temp / 10; -+ dt = temp % 10; -+ -+ return array[index] + (((array[index + 1] - array[index]) * dt) / 10); -+} -+ -+static int ds2760_battery_read_status(struct ds2760_device_info *di) -+{ -+ int ret, i, start, count, scale[5]; -+ -+ if (di->update_time && time_before(jiffies, di->update_time + -+ msecs_to_jiffies(cache_time))) -+ return 0; -+ -+ /* The first time we read the entire contents of SRAM/EEPROM, -+ * but after that we just read the interesting bits that change. */ -+ if (di->update_time == 0) { -+ start = 0; -+ count = DS2760_DATA_SIZE; -+ } -+ else { -+ start = DS2760_VOLTAGE_MSB; -+ count = DS2760_TEMP_LSB - start + 1; -+ } -+ -+ ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count); -+ if (ret != count) { -+ dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n", -+ di->w1_dev); -+ return 1; -+ } -+ -+ di->update_time = jiffies; -+ -+ /* DS2760 reports voltage in units of 4.88mV, but the battery class -+ * reports in units of uV, so convert by multiplying by 4880. */ -+ di->voltage_raw = (di->raw[DS2760_VOLTAGE_MSB] << 3) | -+ (di->raw[DS2760_VOLTAGE_LSB] >> 5); -+ di->voltage_uV = di->voltage_raw * 4880; -+ -+ /* DS2760 reports current in signed units of 0.625mA, but the battery -+ * class reports in units of uA, so convert by multiplying by 625. */ -+ di->current_raw = -+ (((signed char)di->raw[DS2760_CURRENT_MSB]) << 5) | -+ (di->raw[DS2760_CURRENT_LSB] >> 3); -+ di->current_uA = di->current_raw * 625; -+ -+ /* DS2760 reports accumulated current in signed units of 0.25mAh. */ -+ di->accum_current_raw = -+ (((signed char)di->raw[DS2760_CURRENT_ACCUM_MSB]) << 8) | -+ di->raw[DS2760_CURRENT_ACCUM_LSB]; -+ di->accum_current_uAh = di->accum_current_raw * 250; -+ -+ /* DS2760 reports temperature in signed units of 0.125C, but the -+ * battery class reports in units of 1/10 C, so we convert by -+ * multiplying by .125 * 10 = 1.25. */ -+ di->temp_raw = (((signed char)di->raw[DS2760_TEMP_MSB]) << 3) | -+ (di->raw[DS2760_TEMP_LSB] >> 5); -+ di->temp_C = di->temp_raw + (di->temp_raw / 4); -+ -+ /* At least some battery monitors (e.g. HP iPAQ) store the battery's -+ * maximum rated capacity. */ -+ if (di->raw[DS2760_RATED_CAPACITY] < ARRAY_SIZE(rated_capacities)) -+ di->rated_capacity = rated_capacities[ -+ (unsigned int)di->raw[DS2760_RATED_CAPACITY]]; -+ else -+ di->rated_capacity = di->raw[DS2760_RATED_CAPACITY] * 10; -+ -+ di->rated_capacity *= 1000; /* convert to uAh */ -+ -+ /* Calculate the full level at the present temperature. */ -+ di->full_active_uAh = di->raw[DS2760_ACTIVE_FULL] << 8 | -+ di->raw[DS2760_ACTIVE_FULL + 1]; -+ -+ scale[0] = di->raw[DS2760_ACTIVE_FULL] << 8 | -+ di->raw[DS2760_ACTIVE_FULL + 1]; -+ for (i = 1; i < 5; i++) -+ scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i]; -+ -+ di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10); -+ di->full_active_uAh *= 1000; /* convert to uAh */ -+ -+ /* Calculate the empty level at the present temperature. */ -+ scale[4] = di->raw[DS2760_ACTIVE_EMPTY + 4]; -+ for (i = 3; i >= 0; i--) -+ scale[i] = scale[i + 1] + di->raw[DS2760_ACTIVE_EMPTY + i]; -+ -+ di->empty_uAh = battery_interpolate(scale, di->temp_C / 10); -+ di->empty_uAh *= 1000; /* convert to uAh */ -+ -+ /* From Maxim Application Note 131: remaining capacity = -+ * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */ -+ di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) / -+ (di->full_active_uAh - di->empty_uAh); -+ -+ if (di->rem_capacity < 0) -+ di->rem_capacity = 0; -+ if (di->rem_capacity > 100) -+ di->rem_capacity = 100; -+ -+ if (di->current_uA) -+ di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * -+ 3600L) / di->current_uA; -+ else -+ di->life_sec = 0; -+ -+ return 0; -+} -+ -+static void ds2760_battery_update_status(struct ds2760_device_info *di) -+{ -+ int old_charge_status = di->charge_status; -+ -+ ds2760_battery_read_status(di); -+ -+ if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN) -+ di->full_counter = 0; -+ -+ if (power_supply_am_i_supplied(&di->bat)) { -+ if (di->current_uA > 10000) { -+ di->charge_status = POWER_SUPPLY_STATUS_CHARGING; -+ di->full_counter = 0; -+ } -+ else if (di->current_uA < -5000) { -+ if (di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING) -+ dev_notice(di->dev, "not enough power to " -+ "charge\n"); -+ di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; -+ di->full_counter = 0; -+ } -+ else if (di->current_uA < 10000 && -+ di->charge_status != POWER_SUPPLY_STATUS_FULL) { -+ -+ /* Don't consider the battery to be full unless -+ * we've seen the current < 10 mA at least two -+ * consecutive times. */ -+ -+ di->full_counter++; -+ -+ if (di->full_counter < 2) -+ di->charge_status = POWER_SUPPLY_STATUS_CHARGING; -+ else { -+ unsigned char acr[2]; -+ int acr_val; -+ -+ /* acr is in units of 0.25 mAh */ -+ acr_val = di->full_active_uAh * 4L / 1000; -+ -+ acr[0] = acr_val >> 8; -+ acr[1] = acr_val & 0xff; -+ -+ if (w1_ds2760_write(di->w1_dev, acr, -+ DS2760_CURRENT_ACCUM_MSB, 2) < 2) -+ dev_warn(di->dev, -+ "ACR reset failed\n"); -+ -+ di->charge_status = POWER_SUPPLY_STATUS_FULL; -+ } -+ } -+ } -+ else { -+ di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; -+ di->full_counter = 0; -+ } -+ -+ if (di->charge_status != old_charge_status) -+ power_supply_changed(&di->bat); -+ -+ return; -+} -+ -+static void ds2760_battery_work(struct work_struct *work) -+{ -+ struct ds2760_device_info *di = container_of(work, -+ struct ds2760_device_info, monitor_work.work); -+ const int interval = HZ * 60; -+ -+ dev_dbg(di->dev, "%s\n", __FUNCTION__); -+ -+ ds2760_battery_update_status(di); -+ queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval); -+ -+ return; -+} -+ -+#define to_ds2760_device_info(x) container_of((x), struct ds2760_device_info, \ -+ bat); -+ -+static void ds2760_battery_external_power_changed(struct power_supply *psy) -+{ -+ struct ds2760_device_info *di = to_ds2760_device_info(psy); -+ -+ dev_dbg(di->dev, "%s\n", __FUNCTION__); -+ -+ cancel_delayed_work(&di->monitor_work); -+ queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ/10); -+ -+ return; -+} -+ -+static int ds2760_battery_get_property(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ struct ds2760_device_info *di = to_ds2760_device_info(psy); -+ -+ switch (psp) { -+ case POWER_SUPPLY_PROP_STATUS: -+ val->intval = di->charge_status; -+ return 0; -+ default: -+ break; -+ } -+ -+ ds2760_battery_read_status(di); -+ -+ switch (psp) { -+ case POWER_SUPPLY_PROP_VOLTAGE_NOW: -+ val->intval = di->voltage_uV; -+ break; -+ case POWER_SUPPLY_PROP_CURRENT_NOW: -+ val->intval = di->current_uA; -+ break; -+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: -+ val->intval = di->rated_capacity; -+ break; -+ case POWER_SUPPLY_PROP_CHARGE_FULL: -+ val->intval = di->full_active_uAh; -+ break; -+ case POWER_SUPPLY_PROP_CHARGE_EMPTY: -+ val->intval = di->empty_uAh; -+ break; -+ case POWER_SUPPLY_PROP_CHARGE_NOW: -+ val->intval = di->accum_current_uAh; -+ break; -+ case POWER_SUPPLY_PROP_TEMP: -+ val->intval = di->temp_C; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static enum power_supply_property ds2760_battery_props[] = { -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_CURRENT_NOW, -+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, -+ POWER_SUPPLY_PROP_CHARGE_FULL, -+ POWER_SUPPLY_PROP_CHARGE_EMPTY, -+ POWER_SUPPLY_PROP_CHARGE_NOW, -+ POWER_SUPPLY_PROP_TEMP, -+}; -+ -+static int ds2760_battery_probe(struct platform_device *pdev) -+{ -+ int retval = 0; -+ struct ds2760_device_info *di; -+ struct ds2760_platform_data *pdata; -+ -+ di = kzalloc(sizeof(*di), GFP_KERNEL); -+ if (!di) { -+ retval = -ENOMEM; -+ goto di_alloc_failed; -+ } -+ -+ platform_set_drvdata(pdev, di); -+ -+ pdata = pdev->dev.platform_data; -+ di->dev = &pdev->dev; -+ di->w1_dev = pdev->dev.parent; -+ di->bat.name = pdev->dev.bus_id; -+ di->bat.type = POWER_SUPPLY_TYPE_BATTERY; -+ di->bat.properties = ds2760_battery_props; -+ di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props); -+ di->bat.get_property = ds2760_battery_get_property; -+ di->bat.external_power_changed = -+ ds2760_battery_external_power_changed; -+ di->bat.use_for_apm = 1; -+ -+ di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; -+ -+ retval = power_supply_register(&pdev->dev, &di->bat); -+ if (retval) { -+ dev_err(di->dev, "failed to register battery"); -+ goto batt_failed; -+ } -+ -+ INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); -+ di->monitor_wqueue = create_singlethread_workqueue(pdev->dev.bus_id); -+ if (!di->monitor_wqueue) { -+ retval = -ESRCH; -+ goto workqueue_failed; -+ } -+ queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1); -+ -+ goto success; -+ -+workqueue_failed: -+ power_supply_unregister(&di->bat); -+batt_failed: -+ kfree(di); -+di_alloc_failed: -+success: -+ return retval; -+} -+ -+static int ds2760_battery_remove(struct platform_device *pdev) -+{ -+ struct ds2760_device_info *di = platform_get_drvdata(pdev); -+ -+ cancel_rearming_delayed_workqueue(di->monitor_wqueue, -+ &di->monitor_work); -+ destroy_workqueue(di->monitor_wqueue); -+ power_supply_unregister(&di->bat); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+ -+static int ds2760_battery_suspend(struct platf |
