omap: rx51_defconfig: Remove duplicate phonet
[safe/jmp/linux-2.6] / arch / arm / mach-pxa / sharpsl_pm.c
index 6c9e871..463d874 100644 (file)
 #undef DEBUG
 
 #include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/apm_bios.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/apm-emulation.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/suspend.h>
+#include <linux/gpio.h>
 
-#include <asm/hardware.h>
-#include <asm/hardware/scoop.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
-#include <asm/apm.h>
+#include <mach/pm.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/pxa2xx-gpio.h>
+#include <mach/regs-rtc.h>
+#include <mach/sharpsl.h>
+#include <mach/sharpsl_pm.h>
 
-#include <asm/arch/pm.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/arch/sharpsl.h>
 #include "sharpsl.h"
 
 /*
 #define SHARPSL_CHARGE_FINISH_TIME             (msecs_to_jiffies(10*60*1000)) /* 10 min */
 #define SHARPSL_BATCHK_TIME                    (msecs_to_jiffies(15*1000))    /* 15 sec */
 #define SHARPSL_BATCHK_TIME_SUSPEND            (60*10)                        /* 10 min */
+
 #define SHARPSL_WAIT_CO_TIME                   15  /* 15 sec */
 #define SHARPSL_WAIT_DISCHARGE_ON              100 /* 100 msec */
 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP   10  /* 10 msec */
 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT   10  /* 10 msec */
-#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD  10  /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN   10  /* 10 msec */
 #define SHARPSL_CHARGE_WAIT_TIME               15  /* 15 msec */
 #define SHARPSL_CHARGE_CO_CHECK_TIME           5   /* 5 msec */
 #define SHARPSL_CHARGE_RETRY_CNT               1   /* eqv. 10 min */
 
-#define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
-#define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
-#define SHARPSL_CHARGE_ON_JKVAD_HIGH   0x9b  /* 6V */
-#define SHARPSL_CHARGE_ON_JKVAD_LOW    0x34  /* 2V */
-#define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
-#define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
+/*
+ * Prototypes
+ */
+#ifdef CONFIG_PM
+static int sharpsl_off_charge_battery(void);
+static int sharpsl_check_battery_voltage(void);
+static int sharpsl_fatal_check(void);
+#endif
+static int sharpsl_check_battery_temp(void);
+static int sharpsl_ac_check(void);
+static int sharpsl_average_value(int ad);
+static void sharpsl_average_clear(void);
+static void sharpsl_charge_toggle(struct work_struct *private_);
+static void sharpsl_battery_thread(struct work_struct *private_);
+
 
-struct battery_thresh spitz_battery_levels_acin[] = {
+/*
+ * Variables
+ */
+struct sharpsl_pm_status sharpsl_pm;
+static DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle);
+static DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread);
+DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
+
+
+
+struct battery_thresh sharpsl_battery_levels_acin[] = {
        { 213, 100},
        { 212,  98},
        { 211,  95},
@@ -100,7 +121,7 @@ struct battery_thresh spitz_battery_levels_acin[] = {
        {   0,   0},
 };
 
-struct battery_thresh  spitz_battery_levels_noac[] = {
+struct battery_thresh sharpsl_battery_levels_noac[] = {
        { 213, 100},
        { 212,  98},
        { 211,  95},
@@ -144,50 +165,45 @@ struct battery_thresh  spitz_battery_levels_noac[] = {
 };
 
 /* MAX1111 Commands */
-#define MAXCTRL_PD0      1u << 0
-#define MAXCTRL_PD1      1u << 1
-#define MAXCTRL_SGL      1u << 2
-#define MAXCTRL_UNI      1u << 3
+#define MAXCTRL_PD0      (1u << 0)
+#define MAXCTRL_PD1      (1u << 1)
+#define MAXCTRL_SGL      (1u << 2)
+#define MAXCTRL_UNI      (1u << 3)
 #define MAXCTRL_SEL_SH   4
-#define MAXCTRL_STR      1u << 7
-
-/* MAX1111 Channel Definitions */
-#define BATT_AD    4u
-#define BATT_THM   2u
-#define JK_VAD     6u
-
+#define MAXCTRL_STR      (1u << 7)
 
 /*
- * Prototypes
+ * Read MAX1111 ADC
  */
-static int sharpsl_read_MainBattery(void);
-static int sharpsl_off_charge_battery(void);
-static int sharpsl_check_battery(int mode);
-static int sharpsl_ac_check(void);
-static int sharpsl_fatal_check(void);
-static int sharpsl_average_value(int ad);
-static void sharpsl_average_clear(void);
-static void sharpsl_charge_toggle(void *private_);
-static void sharpsl_battery_thread(void *private_);
-
+int sharpsl_pm_pxa_read_max1111(int channel)
+{
+       /* Ugly, better move this function into another module */
+       if (machine_is_tosa())
+           return 0;
 
-/*
- * Variables
- */
-struct sharpsl_pm_status sharpsl_pm;
-DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
-DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
+#ifdef CONFIG_CORGI_SSP_DEPRECATED
+       return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
+                       | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
+#else
+       extern int max1111_read_channel(int);
 
+       /* max1111 accepts channels from 0-3, however,
+        * it is encoded from 0-7 here in the code.
+        */
+       return max1111_read_channel(channel >> 1);
+#endif
+}
 
 static int get_percentage(int voltage)
 {
        int i = sharpsl_pm.machinfo->bat_levels - 1;
+       int bl_status = sharpsl_pm.machinfo->backlight_get_status ? sharpsl_pm.machinfo->backlight_get_status() : 0;
        struct battery_thresh *thresh;
 
        if (sharpsl_pm.charge_mode == CHRG_ON)
-               thresh=sharpsl_pm.machinfo->bat_levels_acin;
+               thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_acin_bl : sharpsl_pm.machinfo->bat_levels_acin;
        else
-               thresh=sharpsl_pm.machinfo->bat_levels_noac;
+               thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_noac_bl : sharpsl_pm.machinfo->bat_levels_noac;
 
        while (i > 0 && (voltage > thresh[i].voltage))
                i--;
@@ -221,28 +237,28 @@ void sharpsl_battery_kick(void)
 EXPORT_SYMBOL(sharpsl_battery_kick);
 
 
-static void sharpsl_battery_thread(void *private_)
+static void sharpsl_battery_thread(struct work_struct *private_)
 {
-       int voltage, percent, apm_status, i = 0;
+       int voltage, percent, apm_status, i;
 
        if (!sharpsl_pm.machinfo)
                return;
 
-       sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE);
+       sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE);
 
        /* Corgi cannot confirm when battery fully charged so periodically kick! */
-       if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
+       if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON)
                        && time_after(jiffies, sharpsl_pm.charge_start_time +  SHARPSL_CHARGE_ON_TIME_INTERVAL))
-               schedule_work(&toggle_charger);
-
-       while(1) {
-               voltage = sharpsl_read_MainBattery();
-               if (voltage > 0) break;
-               if (i++ > 5) {
-                       voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
-                       dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
+               schedule_delayed_work(&toggle_charger, 0);
+
+       for (i = 0; i < 5; i++) {
+               voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
+               if (voltage > 0)
                        break;
-               }
+       }
+       if (voltage <= 0) {
+               voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
+               dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
        }
 
        voltage = sharpsl_average_value(voltage);
@@ -250,33 +266,37 @@ static void sharpsl_battery_thread(void *private_)
        percent = get_percentage(voltage);
 
        /* At low battery voltages, the voltage has a tendency to start
-           creeping back up so we try to avoid this here */
-       if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) ||  percent <= sharpsl_pm.battstat.mainbat_percent) {
+          creeping back up so we try to avoid this here */
+       if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE)
+           || (apm_status == APM_BATTERY_STATUS_HIGH)
+           || percent <= sharpsl_pm.battstat.mainbat_percent) {
                sharpsl_pm.battstat.mainbat_voltage = voltage;
                sharpsl_pm.battstat.mainbat_status = apm_status;
                sharpsl_pm.battstat.mainbat_percent = percent;
        }
 
-       dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage,
+       dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage,
                        sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
 
+#ifdef CONFIG_BACKLIGHT_CORGI
        /* If battery is low. limit backlight intensity to save power. */
        if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
-                       && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
-                       (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
+           && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW)
+           || (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
                if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
-                       corgibl_limit_intensity(1);
+                       sharpsl_pm.machinfo->backlight_limit(1);
                        sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
                }
        } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
-               corgibl_limit_intensity(0);
+               sharpsl_pm.machinfo->backlight_limit(0);
                sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
        }
+#endif
 
        /* Suspend if critical battery level */
        if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
-                       && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
-                       && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
+            && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
+            && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
                sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
                dev_err(sharpsl_pm.dev, "Fatal Off\n");
                apm_queue_event(APM_CRITICAL_SUSPEND);
@@ -285,6 +305,19 @@ static void sharpsl_battery_thread(void *private_)
        schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
 }
 
+void sharpsl_pm_led(int val)
+{
+       if (val == SHARPSL_LED_ERROR) {
+               dev_err(sharpsl_pm.dev, "Charging Error!\n");
+       } else if (val == SHARPSL_LED_ON) {
+               dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
+               led_trigger_event(sharpsl_charge_led_trigger, LED_FULL);
+       } else {
+               dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
+               led_trigger_event(sharpsl_charge_led_trigger, LED_OFF);
+       }
+}
+
 static void sharpsl_charge_on(void)
 {
        dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
@@ -299,45 +332,45 @@ static void sharpsl_charge_off(void)
 {
        dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
 
-       CHARGE_OFF();
-       CHARGE_LED_OFF();
+       sharpsl_pm.machinfo->charge(0);
+       sharpsl_pm_led(SHARPSL_LED_OFF);
        sharpsl_pm.charge_mode = CHRG_OFF;
 
-       schedule_work(&sharpsl_bat);
+       schedule_delayed_work(&sharpsl_bat, 0);
 }
 
 static void sharpsl_charge_error(void)
 {
-       CHARGE_LED_ERR();
-       CHARGE_OFF();
+       sharpsl_pm_led(SHARPSL_LED_ERROR);
+       sharpsl_pm.machinfo->charge(0);
        sharpsl_pm.charge_mode = CHRG_ERROR;
 }
 
-static void sharpsl_charge_toggle(void *private_)
+static void sharpsl_charge_toggle(struct work_struct *private_)
 {
-       dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
+       dev_dbg(sharpsl_pm.dev, "Toggling Charger at time: %lx\n", jiffies);
 
-       if (STATUS_AC_IN == 0) {
+       if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
                sharpsl_charge_off();
                return;
-       } else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) {
+       } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
                sharpsl_charge_error();
                return;
        }
 
-       CHARGE_LED_ON();
-       CHARGE_OFF();
+       sharpsl_pm_led(SHARPSL_LED_ON);
+       sharpsl_pm.machinfo->charge(0);
        mdelay(SHARPSL_CHARGE_WAIT_TIME);
-       CHARGE_ON();
+       sharpsl_pm.machinfo->charge(1);
 
        sharpsl_pm.charge_start_time = jiffies;
 }
 
 static void sharpsl_ac_timer(unsigned long data)
 {
-       int acin = STATUS_AC_IN;
+       int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 
-       dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
+       dev_dbg(sharpsl_pm.dev, "AC Status: %d\n", acin);
 
        sharpsl_average_clear();
        if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
@@ -345,11 +378,11 @@ static void sharpsl_ac_timer(unsigned long data)
        else if (sharpsl_pm.charge_mode == CHRG_ON)
                sharpsl_charge_off();
 
-       schedule_work(&sharpsl_bat);
+       schedule_delayed_work(&sharpsl_bat, 0);
 }
 
 
-static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id)
 {
        /* Delay the event slightly to debounce */
        /* Must be a smaller delay than the chrg_full_isr below */
@@ -364,16 +397,16 @@ static void sharpsl_chrg_full_timer(unsigned long data)
 
        sharpsl_pm.full_count++;
 
-       if (STATUS_AC_IN == 0) {
+       if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
                dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
                if (sharpsl_pm.charge_mode == CHRG_ON)
                        sharpsl_charge_off();
        } else if (sharpsl_pm.full_count < 2) {
                dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
-               schedule_work(&toggle_charger);
+               schedule_delayed_work(&toggle_charger, 0);
        } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
                dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
-               schedule_work(&toggle_charger);
+               schedule_delayed_work(&toggle_charger, 0);
        } else {
                sharpsl_charge_off();
                sharpsl_pm.charge_mode = CHRG_DONE;
@@ -382,9 +415,9 @@ static void sharpsl_chrg_full_timer(unsigned long data)
 }
 
 /* Charging Finished Interrupt (Not present on Corgi) */
-/* Can trigger at the same time as an AC staus change so
+/* Can trigger at the same time as an AC status change so
    delay until after that has been processed */
-static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id)
 {
        if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
                return IRQ_HANDLED;
@@ -395,16 +428,16 @@ static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id)
 {
        int is_fatal = 0;
 
-       if (STATUS_BATT_LOCKED == 0) {
+       if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) {
                dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
                is_fatal = 1;
        }
 
-       if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) {
+       if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) {
                dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
                is_fatal = 1;
        }
@@ -441,48 +474,14 @@ static int sharpsl_average_value(int ad)
        sharpsl_ad[sharpsl_ad_index] = ad;
        sharpsl_ad_index++;
        if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
-               for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
+               for (i = 0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
                        sharpsl_ad[i] = sharpsl_ad[i+1];
                sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
        }
-       for (i=0; i < sharpsl_ad_index; i++)
+       for (i = 0; i < sharpsl_ad_index; i++)
                ad_val += sharpsl_ad[i];
 
-       return (ad_val / sharpsl_ad_index);
-}
-
-
-/*
- * Read MAX1111 ADC
- */
-static int read_max1111(int channel)
-{
-       return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
-                       | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
-}
-
-static int sharpsl_read_MainBattery(void)
-{
-       return read_max1111(BATT_AD);
-}
-
-static int sharpsl_read_Temp(void)
-{
-       int temp;
-
-       sharpsl_pm.machinfo->measure_temp(1);
-
-       mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
-       temp = read_max1111(BATT_THM);
-
-       sharpsl_pm.machinfo->measure_temp(0);
-
-       return temp;
-}
-
-static int sharpsl_read_jkvad(void)
-{
-       return read_max1111(JK_VAD);
+       return ad_val / sharpsl_ad_index;
 }
 
 /*
@@ -495,8 +494,8 @@ static int get_select_val(int *val)
 
        /* Find MAX val */
        temp = val[0];
-       j=0;
-       for (i=1; i<5; i++) {
+       j = 0;
+       for (i = 1; i < 5; i++) {
                if (temp < val[i]) {
                        temp = val[i];
                        j = i;
@@ -505,85 +504,95 @@ static int get_select_val(int *val)
 
        /* Find MIN val */
        temp = val[4];
-       k=4;
-       for (i=3; i>=0; i--) {
+       k = 4;
+       for (i = 3; i >= 0; i--) {
                if (temp > val[i]) {
                        temp = val[i];
                        k = i;
                }
        }
 
-       for (i=0; i<5; i++)
-               if (i != j && i != k )
+       for (i = 0; i < 5; i++)
+               if (i != j && i != k)
                        sum += val[i];
 
        dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
 
-       return (sum/3);
+       return sum/3;
 }
 
-/*  mode 0 - Check temperature and voltage
- *       1 - Check temperature only */
-static int sharpsl_check_battery(int mode)
+static int sharpsl_check_battery_temp(void)
 {
        int val, i, buff[5];
 
        /* Check battery temperature */
-       for (i=0; i<5; i++) {
+       for (i = 0; i < 5; i++) {
+               mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+               sharpsl_pm.machinfo->measure_temp(1);
                mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
-               buff[i] = sharpsl_read_Temp();
+               buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP);
+               sharpsl_pm.machinfo->measure_temp(0);
        }
 
        val = get_select_val(buff);
 
        dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
-       if (val > SHARPSL_CHARGE_ON_TEMP)
+       if (val > sharpsl_pm.machinfo->charge_on_temp) {
+               printk(KERN_WARNING "Not charging: temperature out of limits.\n");
                return -1;
-       if (mode == 1)
-               return 0;
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int sharpsl_check_battery_voltage(void)
+{
+       int val, i, buff[5];
 
        /* disable charge, enable discharge */
-       CHARGE_OFF();
-       DISCHARGE_ON();
+       sharpsl_pm.machinfo->charge(0);
+       sharpsl_pm.machinfo->discharge(1);
        mdelay(SHARPSL_WAIT_DISCHARGE_ON);
 
        if (sharpsl_pm.machinfo->discharge1)
                sharpsl_pm.machinfo->discharge1(1);
 
        /* Check battery voltage */
-       for (i=0; i<5; i++) {
-               buff[i] = sharpsl_read_MainBattery();
+       for (i = 0; i < 5; i++) {
+               buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
                mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
        }
 
        if (sharpsl_pm.machinfo->discharge1)
                sharpsl_pm.machinfo->discharge1(0);
 
-       DISCHARGE_OFF();
+       sharpsl_pm.machinfo->discharge(0);
 
        val = get_select_val(buff);
        dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
 
-       if (val < SHARPSL_CHARGE_ON_VOLT)
+       if (val < sharpsl_pm.machinfo->charge_on_volt)
                return -1;
 
        return 0;
 }
+#endif
 
 static int sharpsl_ac_check(void)
 {
        int temp, i, buff[5];
 
-       for (i=0; i<5; i++) {
-               buff[i] = sharpsl_read_jkvad();
-               mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD);
+       for (i = 0; i < 5; i++) {
+               buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
+               mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
        }
 
        temp = get_select_val(buff);
-       dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
+       dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n", temp);
 
-       if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) {
-               dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
+       if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) {
+               dev_err(sharpsl_pm.dev, "Error: AC check failed: voltage %d.\n", temp);
                return -1;
        }
 
@@ -591,7 +600,7 @@ static int sharpsl_ac_check(void)
 }
 
 #ifdef CONFIG_PM
-static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
+static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
 {
        sharpsl_pm.flags |= SHARPSL_SUSPENDED;
        flush_scheduled_work();
@@ -604,7 +613,7 @@ static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
        return 0;
 }
 
-static int sharpsl_pm_resume(struct device *dev)
+static int sharpsl_pm_resume(struct platform_device *pdev)
 {
        /* Clear the reset source indicators as they break the bootloader upon reboot */
        RCSR = 0x0f;
@@ -617,12 +626,12 @@ static int sharpsl_pm_resume(struct device *dev)
 
 static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
 {
-       dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
+       dev_dbg(sharpsl_pm.dev, "Time is: %08x\n", RCNR);
 
-       dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
+       dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n", sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
        /* not charging and AC-IN! */
 
-       if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) {
+       if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) {
                dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
                sharpsl_pm.charge_mode = CHRG_OFF;
                sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
@@ -637,12 +646,12 @@ static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable
        if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
                RTSR &= RTSR_ALE;
                RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
-               dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
+               dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n", RTAR);
                sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
        } else if (alarm_enable) {
                RTSR &= RTSR_ALE;
                RTAR = alarm_time;
-               dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
+               dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n", RTAR);
        } else {
                dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
        }
@@ -651,19 +660,18 @@ static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable
 
        sharpsl_pm.machinfo->postsuspend();
 
-       dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
+       dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n", PEDR);
 }
 
 static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
 {
-       if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
-       {
+       if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable)) {
                if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
                        dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
                        corgi_goto_sleep(alarm_time, alarm_enable, state);
                        return 1;
                }
-               if(sharpsl_off_charge_battery()) {
+               if (sharpsl_off_charge_battery()) {
                        dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
                        corgi_goto_sleep(alarm_time, alarm_enable, state);
                        return 1;
@@ -671,8 +679,8 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab
                dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
        }
 
-       if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) )
-       {
+       if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) ||
+           (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) {
                dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
                corgi_goto_sleep(alarm_time, alarm_enable, state);
                return 1;
@@ -690,15 +698,16 @@ static int corgi_pxa_pm_enter(suspend_state_t state)
 
        corgi_goto_sleep(alarm_time, alarm_status, state);
 
-       while (corgi_enter_suspend(alarm_time,alarm_status,state))
+       while (corgi_enter_suspend(alarm_time, alarm_status, state))
                {}
 
+       if (sharpsl_pm.machinfo->earlyresume)
+               sharpsl_pm.machinfo->earlyresume();
+
        dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
 
        return 0;
 }
-#endif
-
 
 /*
  * Check for fatal battery errors
@@ -711,12 +720,12 @@ static int sharpsl_fatal_check(void)
        dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
 
        /* Check AC-Adapter */
-       acin = STATUS_AC_IN;
+       acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 
        if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
-               CHARGE_OFF();
+               sharpsl_pm.machinfo->charge(0);
                udelay(100);
-               DISCHARGE_ON(); /* enable discharge */
+               sharpsl_pm.machinfo->discharge(1);      /* enable discharge */
                mdelay(SHARPSL_WAIT_DISCHARGE_ON);
        }
 
@@ -724,8 +733,8 @@ static int sharpsl_fatal_check(void)
                sharpsl_pm.machinfo->discharge1(1);
 
        /* Check battery : check inserting battery ? */
-       for (i=0; i<5; i++) {
-               buff[i] = sharpsl_read_MainBattery();
+       for (i = 0; i < 5; i++) {
+               buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
                mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
        }
 
@@ -734,24 +743,24 @@ static int sharpsl_fatal_check(void)
 
        if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
                udelay(100);
-               CHARGE_ON();
-               DISCHARGE_OFF();
+               sharpsl_pm.machinfo->charge(1);
+               sharpsl_pm.machinfo->discharge(0);
        }
 
        temp = get_select_val(buff);
-       dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery());
+       dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %ld\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));
 
-       if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
-                       (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
+       if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) ||
+                       (!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt)))
                return -1;
        return 0;
 }
 
 static int sharpsl_off_charge_error(void)
 {
-       dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");
-       CHARGE_OFF();
-       CHARGE_LED_ERR();
+       dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n");
+       sharpsl_pm.machinfo->charge(0);
+       sharpsl_pm_led(SHARPSL_LED_ERROR);
        sharpsl_pm.charge_mode = CHRG_ERROR;
        return 1;
 }
@@ -771,14 +780,14 @@ static int sharpsl_off_charge_battery(void)
                dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
 
                /* AC Check */
-               if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0))
+               if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
                        return sharpsl_off_charge_error();
 
                /* Start Charging */
-               CHARGE_LED_ON();
-               CHARGE_OFF();
+               sharpsl_pm_led(SHARPSL_LED_ON);
+               sharpsl_pm.machinfo->charge(0);
                mdelay(SHARPSL_CHARGE_WAIT_TIME);
-               CHARGE_ON();
+               sharpsl_pm.machinfo->charge(1);
 
                sharpsl_pm.charge_mode = CHRG_ON;
                sharpsl_pm.full_count = 0;
@@ -793,30 +802,30 @@ static int sharpsl_off_charge_battery(void)
 
                dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
 
-               if (sharpsl_check_battery(0) < 0)
+               if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
                        return sharpsl_off_charge_error();
 
-               CHARGE_OFF();
+               sharpsl_pm.machinfo->charge(0);
                mdelay(SHARPSL_CHARGE_WAIT_TIME);
-               CHARGE_ON();
+               sharpsl_pm.machinfo->charge(1);
                sharpsl_pm.charge_mode = CHRG_ON;
 
                mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
 
                time = RCNR;
-               while(1) {
-                       /* Check if any wakeup event had occured */
+               while (1) {
+                       /* Check if any wakeup event had occurred */
                        if (sharpsl_pm.machinfo->charger_wakeup() != 0)
                                return 0;
                        /* Check for timeout */
                        if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
                                return 1;
-                       if (STATUS_CHRG_FULL) {
-                               dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
-                               sharpsl_pm.full_count++;
-                               CHARGE_OFF();
+                       if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
+                               dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n");
+                               sharpsl_pm.full_count++;
+                               sharpsl_pm.machinfo->charge(0);
                                mdelay(SHARPSL_CHARGE_WAIT_TIME);
-                               CHARGE_ON();
+                               sharpsl_pm.machinfo->charge(1);
                                return 1;
                        }
                }
@@ -827,9 +836,9 @@ static int sharpsl_off_charge_battery(void)
        mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
 
        time = RCNR;
-       while(1) {
-               /* Check if any wakeup event had occured */
-               if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+       while (1) {
+               /* Check if any wakeup event had occurred */
+               if (sharpsl_pm.machinfo->charger_wakeup())
                        return 0;
                /* Check for timeout */
                if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
@@ -840,25 +849,28 @@ static int sharpsl_off_charge_battery(void)
                        sharpsl_pm.full_count++;
                        return 1;
                }
-               if (STATUS_CHRG_FULL) {
+               if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
                        dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
-                       CHARGE_LED_OFF();
-                       CHARGE_OFF();
+                       sharpsl_pm_led(SHARPSL_LED_OFF);
+                       sharpsl_pm.machinfo->charge(0);
                        sharpsl_pm.charge_mode = CHRG_DONE;
                        return 1;
                }
        }
 }
-
+#else
+#define sharpsl_pm_suspend     NULL
+#define sharpsl_pm_resume      NULL
+#endif
 
 static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
+       return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_percent);
 }
 
 static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
+       return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_voltage);
 }
 
 static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
@@ -879,80 +891,90 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
        info->battery_life = sharpsl_pm.battstat.mainbat_percent;
 }
 
-static struct pm_ops sharpsl_pm_ops = {
-       .pm_disk_mode   = PM_DISK_FIRMWARE,
+#ifdef CONFIG_PM
+static struct platform_suspend_ops sharpsl_pm_ops = {
        .prepare        = pxa_pm_prepare,
-       .enter          = corgi_pxa_pm_enter,
        .finish         = pxa_pm_finish,
+       .enter          = corgi_pxa_pm_enter,
+       .valid          = suspend_valid_only_mem,
 };
+#endif
 
-static int __init sharpsl_pm_probe(struct device *dev)
+static int __devinit sharpsl_pm_probe(struct platform_device *pdev)
 {
-       if (!dev->platform_data)
+       int ret;
+
+       if (!pdev->dev.platform_data)
                return -EINVAL;
 
-       sharpsl_pm.dev = dev;
-       sharpsl_pm.machinfo = dev->platform_data;
+       sharpsl_pm.dev = &pdev->dev;
+       sharpsl_pm.machinfo = pdev->dev.platform_data;
        sharpsl_pm.charge_mode = CHRG_OFF;
        sharpsl_pm.flags = 0;
 
-       sharpsl_pm.machinfo->init();
-
        init_timer(&sharpsl_pm.ac_timer);
        sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
 
        init_timer(&sharpsl_pm.chrg_full_timer);
        sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
 
-       pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
-       pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
-       pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
+       led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
+
+       sharpsl_pm.machinfo->init();
+
+       gpio_request(sharpsl_pm.machinfo->gpio_acin, "AC IN");
+       gpio_direction_input(sharpsl_pm.machinfo->gpio_acin);
+       gpio_request(sharpsl_pm.machinfo->gpio_batfull, "Battery Full");
+       gpio_direction_input(sharpsl_pm.machinfo->gpio_batfull);
+       gpio_request(sharpsl_pm.machinfo->gpio_batlock, "Battery Lock");
+       gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock);
 
        /* Register interrupt handlers */
-       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) {
+       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) {
                dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
        }
-       else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
 
-       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) {
+       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) {
                dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
        }
-       else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
 
        if (sharpsl_pm.machinfo->gpio_fatal) {
-               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) {
+               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) {
                        dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
                }
-               else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
        }
 
-       if (!machine_is_corgi())
-       {
+       if (sharpsl_pm.machinfo->batfull_irq) {
                /* Register interrupt handler. */
-               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
+               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) {
                        dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
                }
-               else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
        }
 
-       device_create_file(dev, &dev_attr_battery_percentage);
-       device_create_file(dev, &dev_attr_battery_voltage);
+       ret = device_create_file(&pdev->dev, &dev_attr_battery_percentage);
+       ret |= device_create_file(&pdev->dev, &dev_attr_battery_voltage);
+       if (ret != 0)
+               dev_warn(&pdev->dev, "Failed to register attributes (%d)\n", ret);
 
        apm_get_power_status = sharpsl_apm_get_power_status;
 
-       pm_set_ops(&sharpsl_pm_ops);
+#ifdef CONFIG_PM
+       suspend_set_ops(&sharpsl_pm_ops);
+#endif
 
        mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
 
        return 0;
 }
 
-static int sharpsl_pm_remove(struct device *dev)
+static int sharpsl_pm_remove(struct platform_device *pdev)
 {
-       pm_set_ops(NULL);
+       suspend_set_ops(NULL);
 
-       device_remove_file(dev, &dev_attr_battery_percentage);
-       device_remove_file(dev, &dev_attr_battery_voltage);
+       device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
+       device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
+
+       led_trigger_unregister_simple(sharpsl_charge_led_trigger);
 
        free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
        free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
@@ -960,32 +982,40 @@ static int sharpsl_pm_remove(struct device *dev)
        if (sharpsl_pm.machinfo->gpio_fatal)
                free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
 
-       if (!machine_is_corgi())
+       if (sharpsl_pm.machinfo->batfull_irq)
                free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
 
+       gpio_free(sharpsl_pm.machinfo->gpio_batlock);
+       gpio_free(sharpsl_pm.machinfo->gpio_batfull);
+       gpio_free(sharpsl_pm.machinfo->gpio_acin);
+
+       if (sharpsl_pm.machinfo->exit)
+               sharpsl_pm.machinfo->exit();
+
        del_timer_sync(&sharpsl_pm.chrg_full_timer);
        del_timer_sync(&sharpsl_pm.ac_timer);
 
        return 0;
 }
 
-static struct device_driver sharpsl_pm_driver = {
-       .name           = "sharpsl-pm",
-       .bus            = &platform_bus_type,
+static struct platform_driver sharpsl_pm_driver = {
        .probe          = sharpsl_pm_probe,
        .remove         = sharpsl_pm_remove,
        .suspend        = sharpsl_pm_suspend,
        .resume         = sharpsl_pm_resume,
+       .driver         = {
+               .name           = "sharpsl-pm",
+       },
 };
 
 static int __devinit sharpsl_pm_init(void)
 {
-       return driver_register(&sharpsl_pm_driver);
+       return platform_driver_register(&sharpsl_pm_driver);
 }
 
 static void sharpsl_pm_exit(void)
 {
-       driver_unregister(&sharpsl_pm_driver);
+       platform_driver_unregister(&sharpsl_pm_driver);
 }
 
 late_initcall(sharpsl_pm_init);