i2c-core: i2c bus should support PM entries in struct dev_pm_ops
[safe/jmp/linux-2.6] / drivers / macintosh / via-pmu.c
index 7e77ac7..db379c3 100644 (file)
@@ -18,6 +18,7 @@
  *
  */
 #include <stdarg.h>
+#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -35,6 +36,7 @@
 #include <linux/spinlock.h>
 #include <linux/pm.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
@@ -185,17 +187,11 @@ static int init_pmu(void);
 static void pmu_start(void);
 static irqreturn_t via_pmu_interrupt(int irq, void *arg);
 static irqreturn_t gpio1_interrupt(int irq, void *arg);
-static int proc_get_info(char *page, char **start, off_t off,
-                         int count, int *eof, void *data);
-static int proc_get_irqstats(char *page, char **start, off_t off,
-                         int count, int *eof, void *data);
+static const struct file_operations pmu_info_proc_fops;
+static const struct file_operations pmu_irqstats_proc_fops;
 static void pmu_pass_intr(unsigned char *data, int len);
-static int proc_get_batt(char *page, char **start, off_t off,
-                       int count, int *eof, void *data);
-static int proc_read_options(char *page, char **start, off_t off,
-                       int count, int *eof, void *data);
-static int proc_write_options(struct file *file, const char __user *buffer,
-                       unsigned long count, void *data);
+static const struct file_operations pmu_battery_proc_fops;
+static const struct file_operations pmu_options_proc_fops;
 
 #ifdef CONFIG_ADB
 struct adb_driver via_pmu_driver = {
@@ -404,7 +400,11 @@ static int __init via_pmu_start(void)
                printk(KERN_ERR "via-pmu: can't map interrupt\n");
                return -ENODEV;
        }
-       if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) {
+       /* We set IRQF_TIMER because we don't want the interrupt to be disabled
+        * between the 2 passes of driver suspend, we control our own disabling
+        * for that one
+        */
+       if (request_irq(irq, via_pmu_interrupt, IRQF_TIMER, "VIA-PMU", (void *)0)) {
                printk(KERN_ERR "via-pmu: can't request irq %d\n", irq);
                return -ENODEV;
        }
@@ -418,7 +418,7 @@ static int __init via_pmu_start(void)
                        gpio_irq = irq_of_parse_and_map(gpio_node, 0);
 
                if (gpio_irq != NO_IRQ) {
-                       if (request_irq(gpio_irq, gpio1_interrupt, 0,
+                       if (request_irq(gpio_irq, gpio1_interrupt, IRQF_TIMER,
                                        "GPIO1 ADB", (void *)0))
                                printk(KERN_ERR "pmu: can't get irq %d"
                                       " (GPIO1)\n", gpio_irq);
@@ -502,19 +502,15 @@ static int __init via_pmu_dev_init(void)
                for (i=0; i<pmu_battery_count; i++) {
                        char title[16];
                        sprintf(title, "battery_%ld", i);
-                       proc_pmu_batt[i] = create_proc_read_entry(title, 0, proc_pmu_root,
-                                               proc_get_batt, (void *)i);
+                       proc_pmu_batt[i] = proc_create_data(title, 0, proc_pmu_root,
+                                       &pmu_battery_proc_fops, (void *)i);
                }
 
-               proc_pmu_info = create_proc_read_entry("info", 0, proc_pmu_root,
-                                       proc_get_info, NULL);
-               proc_pmu_irqstats = create_proc_read_entry("interrupts", 0, proc_pmu_root,
-                                       proc_get_irqstats, NULL);
-               proc_pmu_options = create_proc_entry("options", 0600, proc_pmu_root);
-               if (proc_pmu_options) {
-                       proc_pmu_options->read_proc = proc_read_options;
-                       proc_pmu_options->write_proc = proc_write_options;
-               }
+               proc_pmu_info = proc_create("info", 0, proc_pmu_root, &pmu_info_proc_fops);
+               proc_pmu_irqstats = proc_create("interrupts", 0, proc_pmu_root,
+                                               &pmu_irqstats_proc_fops);
+               proc_pmu_options = proc_create("options", 0600, proc_pmu_root,
+                                               &pmu_options_proc_fops);
        }
        return 0;
 }
@@ -794,27 +790,33 @@ query_battery_state(void)
                        2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
 }
 
-static int
-proc_get_info(char *page, char **start, off_t off,
-               int count, int *eof, void *data)
+static int pmu_info_proc_show(struct seq_file *m, void *v)
 {
-       char* p = page;
-
-       p += sprintf(p, "PMU driver version     : %d\n", PMU_DRIVER_VERSION);
-       p += sprintf(p, "PMU firmware version   : %02x\n", pmu_version);
-       p += sprintf(p, "AC Power               : %d\n",
+       seq_printf(m, "PMU driver version     : %d\n", PMU_DRIVER_VERSION);
+       seq_printf(m, "PMU firmware version   : %02x\n", pmu_version);
+       seq_printf(m, "AC Power               : %d\n",
                ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0) || pmu_battery_count == 0);
-       p += sprintf(p, "Battery count          : %d\n", pmu_battery_count);
+       seq_printf(m, "Battery count          : %d\n", pmu_battery_count);
 
-       return p - page;
+       return 0;
 }
 
-static int
-proc_get_irqstats(char *page, char **start, off_t off,
-                 int count, int *eof, void *data)
+static int pmu_info_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, pmu_info_proc_show, NULL);
+}
+
+static const struct file_operations pmu_info_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pmu_info_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int pmu_irqstats_proc_show(struct seq_file *m, void *v)
 {
        int i;
-       char* p = page;
        static const char *irq_names[] = {
                "Total CB1 triggered events",
                "Total GPIO1 triggered events",
@@ -830,60 +832,76 @@ proc_get_irqstats(char *page, char **start, off_t off,
         };
 
        for (i=0; i<11; i++) {
-               p += sprintf(p, " %2u: %10u (%s)\n",
+               seq_printf(m, " %2u: %10u (%s)\n",
                             i, pmu_irq_stats[i], irq_names[i]);
        }
-       return p - page;
+       return 0;
 }
 
-static int
-proc_get_batt(char *page, char **start, off_t off,
-               int count, int *eof, void *data)
+static int pmu_irqstats_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, pmu_irqstats_proc_show, NULL);
+}
+
+static const struct file_operations pmu_irqstats_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pmu_irqstats_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int pmu_battery_proc_show(struct seq_file *m, void *v)
 {
-       long batnum = (long)data;
-       char *p = page;
+       long batnum = (long)m->private;
        
-       p += sprintf(p, "\n");
-       p += sprintf(p, "flags      : %08x\n",
-               pmu_batteries[batnum].flags);
-       p += sprintf(p, "charge     : %d\n",
-               pmu_batteries[batnum].charge);
-       p += sprintf(p, "max_charge : %d\n",
-               pmu_batteries[batnum].max_charge);
-       p += sprintf(p, "current    : %d\n",
-               pmu_batteries[batnum].amperage);
-       p += sprintf(p, "voltage    : %d\n",
-               pmu_batteries[batnum].voltage);
-       p += sprintf(p, "time rem.  : %d\n",
-               pmu_batteries[batnum].time_remaining);
-
-       return p - page;
+       seq_putc(m, '\n');
+       seq_printf(m, "flags      : %08x\n", pmu_batteries[batnum].flags);
+       seq_printf(m, "charge     : %d\n", pmu_batteries[batnum].charge);
+       seq_printf(m, "max_charge : %d\n", pmu_batteries[batnum].max_charge);
+       seq_printf(m, "current    : %d\n", pmu_batteries[batnum].amperage);
+       seq_printf(m, "voltage    : %d\n", pmu_batteries[batnum].voltage);
+       seq_printf(m, "time rem.  : %d\n", pmu_batteries[batnum].time_remaining);
+       return 0;
 }
 
-static int
-proc_read_options(char *page, char **start, off_t off,
-                       int count, int *eof, void *data)
+static int pmu_battery_proc_open(struct inode *inode, struct file *file)
 {
-       char *p = page;
+       return single_open(file, pmu_battery_proc_show, PDE(inode)->data);
+}
 
+static const struct file_operations pmu_battery_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pmu_battery_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int pmu_options_proc_show(struct seq_file *m, void *v)
+{
 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
        if (pmu_kind == PMU_KEYLARGO_BASED &&
            pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
-               p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup);
+               seq_printf(m, "lid_wakeup=%d\n", option_lid_wakeup);
 #endif
        if (pmu_kind == PMU_KEYLARGO_BASED)
-               p += sprintf(p, "server_mode=%d\n", option_server_mode);
+               seq_printf(m, "server_mode=%d\n", option_server_mode);
 
-       return p - page;
+       return 0;
 }
-                       
-static int
-proc_write_options(struct file *file, const char __user *buffer,
-                       unsigned long count, void *data)
+
+static int pmu_options_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, pmu_options_proc_show, NULL);
+}
+
+static ssize_t pmu_options_proc_write(struct file *file,
+               const char __user *buffer, size_t count, loff_t *pos)
 {
        char tmp[33];
        char *label, *val;
-       unsigned long fcount = count;
+       size_t fcount = count;
        
        if (!count)
                return -EINVAL;
@@ -922,10 +940,18 @@ proc_write_options(struct file *file, const char __user *buffer,
        return fcount;
 }
 
+static const struct file_operations pmu_options_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pmu_options_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = pmu_options_proc_write,
+};
+
 #ifdef CONFIG_ADB
 /* Send an ADB command */
-static int
-pmu_send_request(struct adb_request *req, int sync)
+static int pmu_send_request(struct adb_request *req, int sync)
 {
        int i, ret;
 
@@ -1004,16 +1030,11 @@ pmu_send_request(struct adb_request *req, int sync)
 }
 
 /* Enable/disable autopolling */
-static int
-pmu_adb_autopoll(int devs)
+static int __pmu_adb_autopoll(int devs)
 {
        struct adb_request req;
 
-       if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
-               return -ENXIO;
-
        if (devs) {
-               adb_dev_map = devs;
                pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86,
                            adb_dev_map >> 8, adb_dev_map);
                pmu_adb_flags = 2;
@@ -1026,9 +1047,17 @@ pmu_adb_autopoll(int devs)
        return 0;
 }
 
+static int pmu_adb_autopoll(int devs)
+{
+       if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
+               return -ENXIO;
+
+       adb_dev_map = devs;
+       return __pmu_adb_autopoll(devs);
+}
+
 /* Reset the ADB bus */
-static int
-pmu_adb_reset_bus(void)
+static int pmu_adb_reset_bus(void)
 {
        struct adb_request req;
        int save_autopoll = adb_dev_map;
@@ -1037,13 +1066,13 @@ pmu_adb_reset_bus(void)
                return -ENXIO;
 
        /* anyone got a better idea?? */
-       pmu_adb_autopoll(0);
+       __pmu_adb_autopoll(0);
 
-       req.nbytes = 5;
+       req.nbytes = 4;
        req.done = NULL;
        req.data[0] = PMU_ADB_CMD;
-       req.data[1] = 0;
-       req.data[2] = ADB_BUSRESET;
+       req.data[1] = ADB_BUSRESET;
+       req.data[2] = 0;
        req.data[3] = 0;
        req.data[4] = 0;
        req.reply_len = 0;
@@ -1055,7 +1084,7 @@ pmu_adb_reset_bus(void)
        pmu_wait_complete(&req);
 
        if (save_autopoll != 0)
-               pmu_adb_autopoll(save_autopoll);
+               __pmu_adb_autopoll(save_autopoll);
 
        return 0;
 }
@@ -1748,8 +1777,6 @@ restore_via_state(void)
        out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
 }
 
-extern void pmu_backlight_set_sleep(int sleep);
-
 #define        GRACKLE_PM      (1<<7)
 #define GRACKLE_DOZE   (1<<5)
 #define        GRACKLE_NAP     (1<<4)
@@ -1815,7 +1842,7 @@ static int powerbook_sleep_grackle(void)
                _set_L2CR(save_l2cr);
        
        /* Restore userland MMU context */
-       set_context(current->active_mm->context.id, current->active_mm->pgd);
+       switch_mmu_context(NULL, current->active_mm);
 
        /* Power things up */
        pmu_unlock();
@@ -1904,7 +1931,7 @@ powerbook_sleep_Core99(void)
                _set_L3CR(save_l3cr);
        
        /* Restore userland MMU context */
-       set_context(current->active_mm->context.id, current->active_mm->pgd);
+       switch_mmu_context(NULL, current->active_mm);
 
        /* Tell PMU we are ready */
        pmu_unlock();
@@ -2049,6 +2076,7 @@ pmu_open(struct inode *inode, struct file *file)
        pp->rb_get = pp->rb_put = 0;
        spin_lock_init(&pp->lock);
        init_waitqueue_head(&pp->wait);
+       lock_kernel();
        spin_lock_irqsave(&all_pvt_lock, flags);
 #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
        pp->backlight_locker = 0;
@@ -2056,6 +2084,7 @@ pmu_open(struct inode *inode, struct file *file)
        list_add(&pp->list, &all_pmu_pvt);
        spin_unlock_irqrestore(&all_pvt_lock, flags);
        file->private_data = pp;
+       unlock_kernel();
        return 0;
 }
 
@@ -2160,11 +2189,6 @@ pmu_release(struct inode *inode, struct file *file)
 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
 static void pmac_suspend_disable_irqs(void)
 {
-#ifdef CONFIG_PMAC_BACKLIGHT
-       /* Tell backlight code not to muck around with the chip anymore */
-       pmu_backlight_set_sleep(1);
-#endif
-
        /* Call platform functions marked "on sleep" */
        pmac_pfunc_i2c_suspend();
        pmac_pfunc_base_suspend();
@@ -2208,11 +2232,6 @@ static int powerbook_sleep(suspend_state_t state)
 
        mdelay(100);
 
-#ifdef CONFIG_PMAC_BACKLIGHT
-       /* Tell backlight code it can use the chip again */
-       pmu_backlight_set_sleep(0);
-#endif
-
        return 0;
 }
 
@@ -2457,10 +2476,15 @@ static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
        if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended)
                return 0;
 
-       /* Suspend PMU event interrupts */
+       /* Suspend PMU event interrupts */\
        pmu_suspend();
-
        pmu_sys_suspended = 1;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+       /* Tell backlight code not to muck around with the chip anymore */
+       pmu_backlight_set_sleep(1);
+#endif
+
        return 0;
 }
 
@@ -2475,9 +2499,12 @@ static int pmu_sys_resume(struct sys_device *sysdev)
        pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
        pmu_wait_complete(&req);
 
+#ifdef CONFIG_PMAC_BACKLIGHT
+       /* Tell backlight code it can use the chip again */
+       pmu_backlight_set_sleep(0);
+#endif
        /* Resume PMU event interrupts */
        pmu_resume();
-
        pmu_sys_suspended = 0;
 
        return 0;
@@ -2486,7 +2513,7 @@ static int pmu_sys_resume(struct sys_device *sysdev)
 #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
 
 static struct sysdev_class pmu_sysclass = {
-       set_kset_name("pmu"),
+       .name = "pmu",
 };
 
 static struct sys_device device_pmu = {
@@ -2532,7 +2559,7 @@ EXPORT_SYMBOL(pmu_wait_complete);
 EXPORT_SYMBOL(pmu_suspend);
 EXPORT_SYMBOL(pmu_resume);
 EXPORT_SYMBOL(pmu_unlock);
-#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+#if defined(CONFIG_PPC32)
 EXPORT_SYMBOL(pmu_enable_irled);
 EXPORT_SYMBOL(pmu_battery_count);
 EXPORT_SYMBOL(pmu_batteries);