ACPI: fix OSC regression that caused aer and pciehp not to load
[safe/jmp/linux-2.6] / drivers / acpi / sbs.c
index 73c1ba3..52b9db8 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
 #include <linux/jiffies.h>
 #include <linux/delay.h>
 
+#ifdef CONFIG_ACPI_SYSFS_POWER
 #include <linux/power_supply.h>
+#endif
 
 #include "sbshc.h"
 
+#define PREFIX "ACPI: "
+
 #define ACPI_SBS_CLASS                 "sbs"
 #define ACPI_AC_CLASS                  "ac_adapter"
 #define ACPI_BATTERY_CLASS             "battery"
 #define ACPI_BATTERY_DIR_NAME          "BAT%i"
 #define ACPI_AC_DIR_NAME               "AC0"
 
-enum acpi_sbs_device_addr {
-       ACPI_SBS_CHARGER = 0x9,
-       ACPI_SBS_MANAGER = 0xa,
-       ACPI_SBS_BATTERY = 0xb,
-};
-
 #define ACPI_SBS_NOTIFY_STATUS         0x80
 #define ACPI_SBS_NOTIFY_INFO           0x81
 
@@ -86,9 +84,11 @@ static const struct acpi_device_id sbs_device_ids[] = {
 MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
 
 struct acpi_battery {
+#ifdef CONFIG_ACPI_SYSFS_POWER
        struct power_supply bat;
+#endif
        struct acpi_sbs *sbs;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        struct proc_dir_entry *proc_entry;
 #endif
        unsigned long update_time;
@@ -104,8 +104,8 @@ struct acpi_battery {
        u16 cycle_count;
        u16 temp_now;
        u16 voltage_now;
-       s16 current_now;
-       s16 current_avg;
+       s16 rate_now;
+       s16 rate_avg;
        u16 capacity_now;
        u16 state_of_charge;
        u16 state;
@@ -119,11 +119,13 @@ struct acpi_battery {
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
 
 struct acpi_sbs {
+#ifdef CONFIG_ACPI_SYSFS_POWER
        struct power_supply charger;
+#endif
        struct acpi_device *device;
        struct acpi_smb_hc *hc;
        struct mutex lock;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        struct proc_dir_entry *charger_entry;
 #endif
        struct acpi_battery battery[MAX_SBS_BAT];
@@ -163,6 +165,7 @@ static inline int acpi_battery_scale(struct acpi_battery *battery)
            acpi_battery_ipscale(battery);
 }
 
+#ifdef CONFIG_ACPI_SYSFS_POWER
 static int sbs_get_ac_property(struct power_supply *psy,
                               enum power_supply_property psp,
                               union power_supply_propval *val)
@@ -201,9 +204,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
                return -ENODEV;
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
-               if (battery->current_now < 0)
+               if (battery->rate_now < 0)
                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
-               else if (battery->current_now > 0)
+               else if (battery->rate_now > 0)
                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
                else
                        val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -223,11 +226,13 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
                                acpi_battery_vscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
-               val->intval = abs(battery->current_now) *
+       case POWER_SUPPLY_PROP_POWER_NOW:
+               val->intval = abs(battery->rate_now) *
                                acpi_battery_ipscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_AVG:
-               val->intval = abs(battery->current_avg) *
+       case POWER_SUPPLY_PROP_POWER_AVG:
+               val->intval = abs(battery->rate_avg) *
                                acpi_battery_ipscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CAPACITY:
@@ -292,6 +297,8 @@ static enum power_supply_property sbs_energy_battery_props[] = {
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
        POWER_SUPPLY_PROP_CURRENT_NOW,
        POWER_SUPPLY_PROP_CURRENT_AVG,
+       POWER_SUPPLY_PROP_POWER_NOW,
+       POWER_SUPPLY_PROP_POWER_AVG,
        POWER_SUPPLY_PROP_CAPACITY,
        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
        POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -301,6 +308,8 @@ static enum power_supply_property sbs_energy_battery_props[] = {
        POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
+#endif
+
 /* --------------------------------------------------------------------------
                             Smart Battery System Management
    -------------------------------------------------------------------------- */
@@ -328,8 +337,8 @@ static struct acpi_battery_reader info_readers[] = {
 static struct acpi_battery_reader state_readers[] = {
        {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
        {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
-       {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
-       {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+       {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
+       {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
        {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
        {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
        {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@ -435,6 +444,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
        return result;
 }
 
+#ifdef CONFIG_ACPI_SYSFS_POWER
 static ssize_t acpi_battery_alarm_show(struct device *dev,
                                        struct device_attribute *attr,
                                        char *buf)
@@ -460,64 +470,47 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
 }
 
 static struct device_attribute alarm_attr = {
-       .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+       .attr = {.name = "alarm", .mode = 0644},
        .show = acpi_battery_alarm_show,
        .store = acpi_battery_alarm_store,
 };
+#endif
 
 /* --------------------------------------------------------------------------
                               FS Interface (/proc/acpi)
    -------------------------------------------------------------------------- */
 
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
 /* Generic Routines */
 static int
 acpi_sbs_add_fs(struct proc_dir_entry **dir,
                struct proc_dir_entry *parent_dir,
                char *dir_name,
-               struct file_operations *info_fops,
-               struct file_operations *state_fops,
-               struct file_operations *alarm_fops, void *data)
+               const struct file_operations *info_fops,
+               const struct file_operations *state_fops,
+               const struct file_operations *alarm_fops, void *data)
 {
-       struct proc_dir_entry *entry = NULL;
-
        if (!*dir) {
                *dir = proc_mkdir(dir_name, parent_dir);
                if (!*dir) {
                        return -ENODEV;
                }
-               (*dir)->owner = THIS_MODULE;
        }
 
        /* 'info' [R] */
-       if (info_fops) {
-               entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
-               if (entry) {
-                       entry->proc_fops = info_fops;
-                       entry->data = data;
-                       entry->owner = THIS_MODULE;
-               }
-       }
+       if (info_fops)
+               proc_create_data(ACPI_SBS_FILE_INFO, S_IRUGO, *dir,
+                                info_fops, data);
 
        /* 'state' [R] */
-       if (state_fops) {
-               entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
-               if (entry) {
-                       entry->proc_fops = state_fops;
-                       entry->data = data;
-                       entry->owner = THIS_MODULE;
-               }
-       }
+       if (state_fops)
+               proc_create_data(ACPI_SBS_FILE_STATE, S_IRUGO, *dir,
+                                state_fops, data);
 
        /* 'alarm' [R/W] */
-       if (alarm_fops) {
-               entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
-               if (entry) {
-                       entry->proc_fops = alarm_fops;
-                       entry->data = data;
-                       entry->owner = THIS_MODULE;
-               }
-       }
+       if (alarm_fops)
+               proc_create_data(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir,
+                                alarm_fops, data);
        return 0;
 }
 
@@ -539,7 +532,7 @@ static struct proc_dir_entry *acpi_battery_dir = NULL;
 
 static inline char *acpi_battery_units(struct acpi_battery *battery)
 {
-       return acpi_battery_mode(battery) ? " mWh" : " mAh";
+       return acpi_battery_mode(battery) ? " mW" : " mA";
 }
 
 
@@ -556,10 +549,10 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
        if (!battery->present)
                goto end;
 
-       seq_printf(seq, "design capacity:         %i%s\n",
+       seq_printf(seq, "design capacity:         %i%sh\n",
                   battery->design_capacity * acpi_battery_scale(battery),
                   acpi_battery_units(battery));
-       seq_printf(seq, "last full capacity:      %i%s\n",
+       seq_printf(seq, "last full capacity:      %i%sh\n",
                   battery->full_charge_capacity * acpi_battery_scale(battery),
                   acpi_battery_units(battery));
        seq_printf(seq, "battery technology:      rechargeable\n");
@@ -590,7 +583,7 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 {
        struct acpi_battery *battery = seq->private;
        struct acpi_sbs *sbs = battery->sbs;
-       int result = 0;
+       int rate;
 
        mutex_lock(&sbs->lock);
        seq_printf(seq, "present:                 %s\n",
@@ -602,11 +595,14 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
        seq_printf(seq, "capacity state:          %s\n",
                   (battery->state & 0x0010) ? "critical" : "ok");
        seq_printf(seq, "charging state:          %s\n",
-                  (battery->current_now < 0) ? "discharging" :
-                  ((battery->current_now > 0) ? "charging" : "charged"));
-       seq_printf(seq, "present rate:            %d mA\n",
-                  abs(battery->current_now) * acpi_battery_ipscale(battery));
-       seq_printf(seq, "remaining capacity:      %i%s\n",
+                  (battery->rate_now < 0) ? "discharging" :
+                  ((battery->rate_now > 0) ? "charging" : "charged"));
+       rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
+       rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
+                       acpi_battery_vscale(battery)/1000):1;
+       seq_printf(seq, "present rate:            %d%s\n", rate,
+                  acpi_battery_units(battery));
+       seq_printf(seq, "remaining capacity:      %i%sh\n",
                   battery->capacity_now * acpi_battery_scale(battery),
                   acpi_battery_units(battery));
        seq_printf(seq, "present voltage:         %i mV\n",
@@ -614,7 +610,7 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 
       end:
        mutex_unlock(&sbs->lock);
-       return result;
+       return 0;
 }
 
 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
@@ -638,7 +634,7 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
        acpi_battery_get_alarm(battery);
        seq_printf(seq, "alarm:                   ");
        if (battery->alarm_capacity)
-               seq_printf(seq, "%i%s\n",
+               seq_printf(seq, "%i%sh\n",
                           battery->alarm_capacity *
                           acpi_battery_scale(battery),
                           acpi_battery_units(battery));
@@ -687,7 +683,7 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
        return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
 }
 
-static struct file_operations acpi_battery_info_fops = {
+static const struct file_operations acpi_battery_info_fops = {
        .open = acpi_battery_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -695,7 +691,7 @@ static struct file_operations acpi_battery_info_fops = {
        .owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_state_fops = {
+static const struct file_operations acpi_battery_state_fops = {
        .open = acpi_battery_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -703,7 +699,7 @@ static struct file_operations acpi_battery_state_fops = {
        .owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_alarm_fops = {
+static const struct file_operations acpi_battery_alarm_fops = {
        .open = acpi_battery_alarm_open_fs,
        .read = seq_read,
        .write = acpi_battery_write_alarm,
@@ -735,7 +731,7 @@ static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
        return single_open(file, acpi_ac_read_state, PDE(inode)->data);
 }
 
-static struct file_operations acpi_ac_state_fops = {
+static const struct file_operations acpi_ac_state_fops = {
        .open = acpi_ac_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -790,12 +786,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
                return result;
 
        sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
                        battery->name, &acpi_battery_info_fops,
                        &acpi_battery_state_fops, &acpi_battery_alarm_fops,
                        battery);
 #endif
+#ifdef CONFIG_ACPI_SYSFS_POWER
        battery->bat.name = battery->name;
        battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
        if (!acpi_battery_mode(battery)) {
@@ -816,22 +813,24 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
                goto end;
        battery->have_sysfs_alarm = 1;
       end:
+#endif
        printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
               ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
-              battery->name, sbs->battery->present ? "present" : "absent");
+              battery->name, battery->present ? "present" : "absent");
        return result;
 }
 
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
        struct acpi_battery *battery = &sbs->battery[id];
-
+#ifdef CONFIG_ACPI_SYSFS_POWER
        if (battery->bat.dev) {
                if (battery->have_sysfs_alarm)
                        device_remove_file(battery->bat.dev, &alarm_attr);
                power_supply_unregister(&battery->bat);
        }
-#ifdef CONFIG_ACPI_PROCFS
+#endif
+#ifdef CONFIG_ACPI_PROCFS_POWER
        if (battery->proc_entry)
                acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir);
 #endif
@@ -844,19 +843,21 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
        result = acpi_ac_get_present(sbs);
        if (result)
                goto end;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
                                 ACPI_AC_DIR_NAME, NULL,
                                 &acpi_ac_state_fops, NULL, sbs);
        if (result)
                goto end;
 #endif
+#ifdef CONFIG_ACPI_SYSFS_POWER
        sbs->charger.name = "sbs-charger";
        sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
        sbs->charger.properties = sbs_ac_props;
        sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
        sbs->charger.get_property = sbs_get_ac_property;
        power_supply_register(&sbs->device->dev, &sbs->charger);
+#endif
        printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
               ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
               ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
@@ -866,15 +867,17 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
 
 static void acpi_charger_remove(struct acpi_sbs *sbs)
 {
+#ifdef CONFIG_ACPI_SYSFS_POWER
        if (sbs->charger.dev)
                power_supply_unregister(&sbs->charger);
-#ifdef CONFIG_ACPI_PROCFS
+#endif
+#ifdef CONFIG_ACPI_PROCFS_POWER
        if (sbs->charger_entry)
                acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
 #endif
 }
 
-void acpi_sbs_callback(void *context)
+static void acpi_sbs_callback(void *context)
 {
        int id;
        struct acpi_sbs *sbs = context;
@@ -888,7 +891,9 @@ void acpi_sbs_callback(void *context)
                                              ACPI_SBS_NOTIFY_STATUS,
                                              sbs->charger_present);
 #endif
+#ifdef CONFIG_ACPI_SYSFS_POWER
                kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
+#endif
        }
        if (sbs->manager_present) {
                for (id = 0; id < MAX_SBS_BAT; ++id) {
@@ -905,7 +910,9 @@ void acpi_sbs_callback(void *context)
                                                      ACPI_SBS_NOTIFY_STATUS,
                                                      bat->present);
 #endif
+#ifdef CONFIG_ACPI_SYSFS_POWER
                        kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
+#endif
                }
        }
 }
@@ -930,7 +937,7 @@ static int acpi_sbs_add(struct acpi_device *device)
        sbs->device = device;
        strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
-       acpi_driver_data(device) = sbs;
+       device->driver_data = sbs;
 
        result = acpi_charger_add(sbs);
        if (result)
@@ -974,7 +981,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
 
 static void acpi_sbs_rmdirs(void)
 {
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        if (acpi_ac_dir) {
                acpi_unlock_ac_dir(acpi_ac_dir);
                acpi_ac_dir = NULL;
@@ -1013,7 +1020,7 @@ static int __init acpi_sbs_init(void)
 
        if (acpi_disabled)
                return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+#ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_ac_dir = acpi_lock_ac_dir();
        if (!acpi_ac_dir)
                return -ENODEV;