]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/macintosh/via-pmu.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[linux.git] / drivers / macintosh / via-pmu.c
index 25c1ce8110536725e61ec3afe1271057f5b7b388..d72c450aebe5c3aa79bf8322d93507aef8ad990c 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device driver for the via-pmu on Apple Powermacs.
+ * Device driver for the PMU in Apple PowerBooks and PowerMacs.
  *
  * The VIA (versatile interface adapter) interfaces to the PMU,
  * a 6805 microprocessor core whose primary function is to control
 #include <linux/compat.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <asm/prom.h>
+#include <linux/uaccess.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/sections.h>
 #include <asm/irq.h>
+#ifdef CONFIG_PPC_PMAC
 #include <asm/pmac_feature.h>
 #include <asm/pmac_pfunc.h>
 #include <asm/pmac_low_i2c.h>
-#include <linux/uaccess.h>
+#include <asm/prom.h>
 #include <asm/mmu_context.h>
 #include <asm/cputable.h>
 #include <asm/time.h>
 #include <asm/backlight.h>
+#else
+#include <asm/macintosh.h>
+#include <asm/macints.h>
+#include <asm/mac_via.h>
+#endif
 
 #include "via-pmu-event.h"
 
@@ -76,7 +82,6 @@
 #define BATTERY_POLLING_COUNT  2
 
 static DEFINE_MUTEX(pmu_info_proc_mutex);
-static volatile unsigned char __iomem *via;
 
 /* VIA registers - spaced 0x200 bytes apart */
 #define RS             0x200           /* skip between registers */
@@ -98,8 +103,13 @@ static volatile unsigned char __iomem *via;
 #define ANH            (15*RS)         /* A-side data, no handshake */
 
 /* Bits in B data register: both active low */
+#ifdef CONFIG_PPC_PMAC
 #define TACK           0x08            /* Transfer acknowledge (input) */
 #define TREQ           0x10            /* Transfer request (output) */
+#else
+#define TACK           0x02
+#define TREQ           0x04
+#endif
 
 /* Bits in ACR */
 #define SR_CTRL                0x1c            /* Shift register control bits */
@@ -114,6 +124,7 @@ static volatile unsigned char __iomem *via;
 #define CB1_INT                0x10            /* transition on CB1 input */
 
 static volatile enum pmu_state {
+       uninitialized = 0,
        idle,
        sending,
        intack,
@@ -140,11 +151,15 @@ static int data_index;
 static int data_len;
 static volatile int adb_int_pending;
 static volatile int disable_poll;
-static struct device_node *vias;
 static int pmu_kind = PMU_UNKNOWN;
 static int pmu_fully_inited;
 static int pmu_has_adb;
+#ifdef CONFIG_PPC_PMAC
+static volatile unsigned char __iomem *via1;
+static volatile unsigned char __iomem *via2;
+static struct device_node *vias;
 static struct device_node *gpio_node;
+#endif
 static unsigned char __iomem *gpio_reg;
 static int gpio_irq = 0;
 static int gpio_irq_enabled = -1;
@@ -157,7 +172,9 @@ static int drop_interrupts;
 static int option_lid_wakeup = 1;
 #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
 static unsigned long async_req_locks;
-static unsigned int pmu_irq_stats[11];
+
+#define NUM_IRQ_STATS 13
+static unsigned int pmu_irq_stats[NUM_IRQ_STATS];
 
 static struct proc_dir_entry *proc_pmu_root;
 static struct proc_dir_entry *proc_pmu_info;
@@ -271,10 +288,11 @@ static char *pbook_type[] = {
 
 int __init find_via_pmu(void)
 {
+#ifdef CONFIG_PPC_PMAC
        u64 taddr;
        const u32 *reg;
 
-       if (via)
+       if (pmu_state != uninitialized)
                return 1;
        vias = of_find_node_by_name(NULL, "via-pmu");
        if (vias == NULL)
@@ -339,50 +357,70 @@ int __init find_via_pmu(void)
        } else
                pmu_kind = PMU_UNKNOWN;
 
-       via = ioremap(taddr, 0x2000);
-       if (via == NULL) {
+       via1 = via2 = ioremap(taddr, 0x2000);
+       if (via1 == NULL) {
                printk(KERN_ERR "via-pmu: Can't map address !\n");
                goto fail_via_remap;
        }
        
-       out_8(&via[IER], IER_CLR | 0x7f);       /* disable all intrs */
-       out_8(&via[IFR], 0x7f);                 /* clear IFR */
+       out_8(&via1[IER], IER_CLR | 0x7f);      /* disable all intrs */
+       out_8(&via1[IFR], 0x7f);                        /* clear IFR */
 
        pmu_state = idle;
 
        if (!init_pmu())
                goto fail_init;
 
-       printk(KERN_INFO "PMU driver v%d initialized for %s, firmware: %02x\n",
-              PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
-              
        sys_ctrler = SYS_CTRLER_PMU;
        
        return 1;
 
  fail_init:
-       iounmap(via);
-       via = NULL;
+       iounmap(via1);
+       via1 = via2 = NULL;
  fail_via_remap:
        iounmap(gpio_reg);
        gpio_reg = NULL;
  fail:
        of_node_put(vias);
        vias = NULL;
+       pmu_state = uninitialized;
        return 0;
+#else
+       if (macintosh_config->adb_type != MAC_ADB_PB2)
+               return 0;
+
+       pmu_kind = PMU_UNKNOWN;
+
+       spin_lock_init(&pmu_lock);
+
+       pmu_has_adb = 1;
+
+       pmu_intr_mask = PMU_INT_PCEJECT |
+                       PMU_INT_SNDBRT |
+                       PMU_INT_ADB |
+                       PMU_INT_TICK;
+
+       pmu_state = idle;
+
+       if (!init_pmu()) {
+               pmu_state = uninitialized;
+               return 0;
+       }
+
+       return 1;
+#endif /* !CONFIG_PPC_PMAC */
 }
 
 #ifdef CONFIG_ADB
 static int pmu_probe(void)
 {
-       return vias == NULL? -ENODEV: 0;
+       return pmu_state == uninitialized ? -ENODEV : 0;
 }
 
-static int __init pmu_init(void)
+static int pmu_init(void)
 {
-       if (vias == NULL)
-               return -ENODEV;
-       return 0;
+       return pmu_state == uninitialized ? -ENODEV : 0;
 }
 #endif /* CONFIG_ADB */
 
@@ -395,13 +433,14 @@ static int __init pmu_init(void)
  */
 static int __init via_pmu_start(void)
 {
-       unsigned int irq;
+       unsigned int __maybe_unused irq;
 
-       if (vias == NULL)
+       if (pmu_state == uninitialized)
                return -ENODEV;
 
        batt_req.complete = 1;
 
+#ifdef CONFIG_PPC_PMAC
        irq = irq_of_parse_and_map(vias, 0);
        if (!irq) {
                printk(KERN_ERR "via-pmu: can't map interrupt\n");
@@ -437,7 +476,20 @@ static int __init via_pmu_start(void)
        }
 
        /* Enable interrupts */
-       out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
+       out_8(&via1[IER], IER_SET | SR_INT | CB1_INT);
+#else
+       if (request_irq(IRQ_MAC_ADB_SR, via_pmu_interrupt, IRQF_NO_SUSPEND,
+                       "VIA-PMU-SR", NULL)) {
+               pr_err("%s: couldn't get SR irq\n", __func__);
+               return -ENODEV;
+       }
+       if (request_irq(IRQ_MAC_ADB_CL, via_pmu_interrupt, IRQF_NO_SUSPEND,
+                       "VIA-PMU-CL", NULL)) {
+               pr_err("%s: couldn't get CL irq\n", __func__);
+               free_irq(IRQ_MAC_ADB_SR, NULL);
+               return -ENODEV;
+       }
+#endif /* !CONFIG_PPC_PMAC */
 
        pmu_fully_inited = 1;
 
@@ -463,7 +515,7 @@ arch_initcall(via_pmu_start);
  */
 static int __init via_pmu_dev_init(void)
 {
-       if (vias == NULL)
+       if (pmu_state == uninitialized)
                return -ENODEV;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
@@ -534,8 +586,9 @@ init_pmu(void)
        int timeout;
        struct adb_request req;
 
-       out_8(&via[B], via[B] | TREQ);                  /* negate TREQ */
-       out_8(&via[DIRB], (via[DIRB] | TREQ) & ~TACK);  /* TACK in, TREQ out */
+       /* Negate TREQ. Set TACK to input and TREQ to output. */
+       out_8(&via2[B], in_8(&via2[B]) | TREQ);
+       out_8(&via2[DIRB], (in_8(&via2[DIRB]) | TREQ) & ~TACK);
 
        pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
        timeout =  100000;
@@ -587,6 +640,10 @@ init_pmu(void)
                               option_server_mode ? "enabled" : "disabled");
                }
        }
+
+       printk(KERN_INFO "PMU driver v%d initialized for %s, firmware: %02x\n",
+              PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
+
        return 1;
 }
 
@@ -625,6 +682,7 @@ static void pmu_set_server_mode(int server_mode)
 static void
 done_battery_state_ohare(struct adb_request* req)
 {
+#ifdef CONFIG_PPC_PMAC
        /* format:
         *  [0]    :  flags
         *    0x01 :  AC indicator
@@ -706,6 +764,7 @@ done_battery_state_ohare(struct adb_request* req)
        pmu_batteries[pmu_cur_battery].amperage = amperage;
        pmu_batteries[pmu_cur_battery].voltage = voltage;
        pmu_batteries[pmu_cur_battery].time_remaining = time;
+#endif /* CONFIG_PPC_PMAC */
 
        clear_bit(0, &async_req_locks);
 }
@@ -816,9 +875,9 @@ static int pmu_info_proc_show(struct seq_file *m, void *v)
 static int pmu_irqstats_proc_show(struct seq_file *m, void *v)
 {
        int i;
-       static const char *irq_names[] = {
-               "Total CB1 triggered events",
-               "Total GPIO1 triggered events",
+       static const char *irq_names[NUM_IRQ_STATS] = {
+               "Unknown interrupt (type 0)",
+               "Unknown interrupt (type 1)",
                "PC-Card eject button",
                "Sound/Brightness button",
                "ADB message",
@@ -827,10 +886,12 @@ static int pmu_irqstats_proc_show(struct seq_file *m, void *v)
                "Tick timer",
                "Ghost interrupt (zero len)",
                "Empty interrupt (empty mask)",
-               "Max irqs in a row"
+               "Max irqs in a row",
+               "Total CB1 triggered events",
+               "Total GPIO1 triggered events",
         };
 
-       for (i=0; i<11; i++) {
+       for (i = 0; i < NUM_IRQ_STATS; i++) {
                seq_printf(m, " %2u: %10u (%s)\n",
                             i, pmu_irq_stats[i], irq_names[i]);
        }
@@ -928,7 +989,7 @@ static int pmu_send_request(struct adb_request *req, int sync)
 {
        int i, ret;
 
-       if ((vias == NULL) || (!pmu_fully_inited)) {
+       if (pmu_state == uninitialized || !pmu_fully_inited) {
                req->complete = 1;
                return -ENXIO;
        }
@@ -1022,7 +1083,7 @@ static int __pmu_adb_autopoll(int devs)
 
 static int pmu_adb_autopoll(int devs)
 {
-       if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
+       if (pmu_state == uninitialized || !pmu_fully_inited || !pmu_has_adb)
                return -ENXIO;
 
        adb_dev_map = devs;
@@ -1035,7 +1096,7 @@ static int pmu_adb_reset_bus(void)
        struct adb_request req;
        int save_autopoll = adb_dev_map;
 
-       if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
+       if (pmu_state == uninitialized || !pmu_fully_inited || !pmu_has_adb)
                return -ENXIO;
 
        /* anyone got a better idea?? */
@@ -1071,7 +1132,7 @@ pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
        va_list list;
        int i;
 
-       if (vias == NULL)
+       if (pmu_state == uninitialized)
                return -ENXIO;
 
        if (nbytes < 0 || nbytes > 32) {
@@ -1096,7 +1157,7 @@ pmu_queue_request(struct adb_request *req)
        unsigned long flags;
        int nsend;
 
-       if (via == NULL) {
+       if (pmu_state == uninitialized) {
                req->complete = 1;
                return -ENXIO;
        }
@@ -1136,7 +1197,7 @@ wait_for_ack(void)
         * reported
         */
        int timeout = 4000;
-       while ((in_8(&via[B]) & TACK) == 0) {
+       while ((in_8(&via2[B]) & TACK) == 0) {
                if (--timeout < 0) {
                        printk(KERN_ERR "PMU not responding (!ack)\n");
                        return;
@@ -1150,23 +1211,19 @@ wait_for_ack(void)
 static inline void
 send_byte(int x)
 {
-       volatile unsigned char __iomem *v = via;
-
-       out_8(&v[ACR], in_8(&v[ACR]) | SR_OUT | SR_EXT);
-       out_8(&v[SR], x);
-       out_8(&v[B], in_8(&v[B]) & ~TREQ);              /* assert TREQ */
-       (void)in_8(&v[B]);
+       out_8(&via1[ACR], in_8(&via1[ACR]) | SR_OUT | SR_EXT);
+       out_8(&via1[SR], x);
+       out_8(&via2[B], in_8(&via2[B]) & ~TREQ);        /* assert TREQ */
+       (void)in_8(&via2[B]);
 }
 
 static inline void
 recv_byte(void)
 {
-       volatile unsigned char __iomem *v = via;
-
-       out_8(&v[ACR], (in_8(&v[ACR]) & ~SR_OUT) | SR_EXT);
-       in_8(&v[SR]);           /* resets SR */
-       out_8(&v[B], in_8(&v[B]) & ~TREQ);
-       (void)in_8(&v[B]);
+       out_8(&via1[ACR], (in_8(&via1[ACR]) & ~SR_OUT) | SR_EXT);
+       in_8(&via1[SR]);                /* resets SR */
+       out_8(&via2[B], in_8(&via2[B]) & ~TREQ);
+       (void)in_8(&via2[B]);
 }
 
 static inline void
@@ -1209,7 +1266,7 @@ pmu_start(void)
 void
 pmu_poll(void)
 {
-       if (!via)
+       if (pmu_state == uninitialized)
                return;
        if (disable_poll)
                return;
@@ -1219,7 +1276,7 @@ pmu_poll(void)
 void
 pmu_poll_adb(void)
 {
-       if (!via)
+       if (pmu_state == uninitialized)
                return;
        if (disable_poll)
                return;
@@ -1234,7 +1291,7 @@ pmu_poll_adb(void)
 void
 pmu_wait_complete(struct adb_request *req)
 {
-       if (!via)
+       if (pmu_state == uninitialized)
                return;
        while((pmu_state != idle && pmu_state != locked) || !req->complete)
                via_pmu_interrupt(0, NULL);
@@ -1250,7 +1307,7 @@ pmu_suspend(void)
 {
        unsigned long flags;
 
-       if (!via)
+       if (pmu_state == uninitialized)
                return;
        
        spin_lock_irqsave(&pmu_lock, flags);
@@ -1269,7 +1326,7 @@ pmu_suspend(void)
                if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) {
                        if (gpio_irq >= 0)
                                disable_irq_nosync(gpio_irq);
-                       out_8(&via[IER], CB1_INT | IER_CLR);
+                       out_8(&via1[IER], CB1_INT | IER_CLR);
                        spin_unlock_irqrestore(&pmu_lock, flags);
                        break;
                }
@@ -1281,7 +1338,7 @@ pmu_resume(void)
 {
        unsigned long flags;
 
-       if (!via || (pmu_suspended < 1))
+       if (pmu_state == uninitialized || pmu_suspended < 1)
                return;
 
        spin_lock_irqsave(&pmu_lock, flags);
@@ -1293,7 +1350,7 @@ pmu_resume(void)
        adb_int_pending = 1;
        if (gpio_irq >= 0)
                enable_irq(gpio_irq);
-       out_8(&via[IER], CB1_INT | IER_SET);
+       out_8(&via1[IER], CB1_INT | IER_SET);
        spin_unlock_irqrestore(&pmu_lock, flags);
        pmu_poll();
 }
@@ -1302,7 +1359,8 @@ pmu_resume(void)
 static void
 pmu_handle_data(unsigned char *data, int len)
 {
-       unsigned char ints, pirq;
+       unsigned char ints;
+       int idx;
        int i = 0;
 
        asleep = 0;
@@ -1324,25 +1382,24 @@ pmu_handle_data(unsigned char *data, int len)
                ints &= ~(PMU_INT_ADB_AUTO | PMU_INT_AUTO_SRQ_POLL);
 
 next:
-
        if (ints == 0) {
                if (i > pmu_irq_stats[10])
                        pmu_irq_stats[10] = i;
                return;
        }
-
-       for (pirq = 0; pirq < 8; pirq++)
-               if (ints & (1 << pirq))
-                       break;
-       pmu_irq_stats[pirq]++;
        i++;
-       ints &= ~(1 << pirq);
+
+       idx = ffs(ints) - 1;
+       ints &= ~BIT(idx);
+
+       pmu_irq_stats[idx]++;
 
        /* Note: for some reason, we get an interrupt with len=1,
         * data[0]==0 after each normal ADB interrupt, at least
         * on the Pismo. Still investigating...  --BenH
         */
-       if ((1 << pirq) & PMU_INT_ADB) {
+       switch (BIT(idx)) {
+       case PMU_INT_ADB:
                if ((data[0] & PMU_INT_ADB_AUTO) == 0) {
                        struct adb_request *req = req_awaiting_reply;
                        if (!req) {
@@ -1358,6 +1415,7 @@ pmu_handle_data(unsigned char *data, int len)
                        }
                        pmu_done(req);
                } else {
+#ifdef CONFIG_XMON
                        if (len == 4 && data[1] == 0x2c) {
                                extern int xmon_wants_key, xmon_adb_keycode;
                                if (xmon_wants_key) {
@@ -1365,6 +1423,7 @@ pmu_handle_data(unsigned char *data, int len)
                                        return;
                                }
                        }
+#endif /* CONFIG_XMON */
 #ifdef CONFIG_ADB
                        /*
                         * XXX On the [23]400 the PMU gives us an up
@@ -1378,25 +1437,28 @@ pmu_handle_data(unsigned char *data, int len)
                                adb_input(data+1, len-1, 1);
 #endif /* CONFIG_ADB */                
                }
-       }
+               break;
+
        /* Sound/brightness button pressed */
-       else if ((1 << pirq) & PMU_INT_SNDBRT) {
+       case PMU_INT_SNDBRT:
 #ifdef CONFIG_PMAC_BACKLIGHT
                if (len == 3)
                        pmac_backlight_set_legacy_brightness_pmu(data[1] >> 4);
 #endif
-       }
+               break;
+
        /* Tick interrupt */
-       else if ((1 << pirq) & PMU_INT_TICK) {
-               /* Environement or tick interrupt, query batteries */
+       case PMU_INT_TICK:
+               /* Environment or tick interrupt, query batteries */
                if (pmu_battery_count) {
                        if ((--query_batt_timer) == 0) {
                                query_battery_state();
                                query_batt_timer = BATTERY_POLLING_COUNT;
                        }
                }
-        }
-       else if ((1 << pirq) & PMU_INT_ENVIRONMENT) {
+               break;
+
+       case PMU_INT_ENVIRONMENT:
                if (pmu_battery_count)
                        query_battery_state();
                pmu_pass_intr(data, len);
@@ -1406,7 +1468,9 @@ pmu_handle_data(unsigned char *data, int len)
                        via_pmu_event(PMU_EVT_POWER, !!(data[1]&8));
                        via_pmu_event(PMU_EVT_LID, data[1]&1);
                }
-       } else {
+               break;
+
+       default:
               pmu_pass_intr(data, len);
        }
        goto next;
@@ -1418,21 +1482,20 @@ pmu_sr_intr(void)
        struct adb_request *req;
        int bite = 0;
 
-       if (via[B] & TREQ) {
-               printk(KERN_ERR "PMU: spurious SR intr (%x)\n", via[B]);
-               out_8(&via[IFR], SR_INT);
+       if (in_8(&via2[B]) & TREQ) {
+               printk(KERN_ERR "PMU: spurious SR intr (%x)\n", in_8(&via2[B]));
                return NULL;
        }
        /* The ack may not yet be low when we get the interrupt */
-       while ((in_8(&via[B]) & TACK) != 0)
+       while ((in_8(&via2[B]) & TACK) != 0)
                        ;
 
        /* if reading grab the byte, and reset the interrupt */
        if (pmu_state == reading || pmu_state == reading_intr)
-               bite = in_8(&via[SR]);
+               bite = in_8(&via1[SR]);
 
        /* reset TREQ and wait for TACK to go high */
-       out_8(&via[B], in_8(&via[B]) | TREQ);
+       out_8(&via2[B], in_8(&via2[B]) | TREQ);
        wait_for_ack();
 
        switch (pmu_state) {
@@ -1533,26 +1596,46 @@ via_pmu_interrupt(int irq, void *arg)
        ++disable_poll;
        
        for (;;) {
-               intr = in_8(&via[IFR]) & (SR_INT | CB1_INT);
+               /* On 68k Macs, VIA interrupts are dispatched individually.
+                * Unless we are polling, the relevant IRQ flag has already
+                * been cleared.
+                */
+               intr = 0;
+               if (IS_ENABLED(CONFIG_PPC_PMAC) || !irq) {
+                       intr = in_8(&via1[IFR]) & (SR_INT | CB1_INT);
+                       out_8(&via1[IFR], intr);
+               }
+#ifndef CONFIG_PPC_PMAC
+               switch (irq) {
+               case IRQ_MAC_ADB_CL:
+                       intr = CB1_INT;
+                       break;
+               case IRQ_MAC_ADB_SR:
+                       intr = SR_INT;
+                       break;
+               }
+#endif
                if (intr == 0)
                        break;
                handled = 1;
                if (++nloop > 1000) {
                        printk(KERN_DEBUG "PMU: stuck in intr loop, "
                               "intr=%x, ier=%x pmu_state=%d\n",
-                              intr, in_8(&via[IER]), pmu_state);
+                              intr, in_8(&via1[IER]), pmu_state);
                        break;
                }
-               out_8(&via[IFR], intr);
                if (intr & CB1_INT) {
                        adb_int_pending = 1;
-                       pmu_irq_stats[0]++;
+                       pmu_irq_stats[11]++;
                }
                if (intr & SR_INT) {
                        req = pmu_sr_intr();
                        if (req)
                                break;
                }
+#ifndef CONFIG_PPC_PMAC
+               break;
+#endif
        }
 
 recheck:
@@ -1619,7 +1702,7 @@ pmu_unlock(void)
 }
 
 
-static irqreturn_t
+static __maybe_unused irqreturn_t
 gpio1_interrupt(int irq, void *arg)
 {
        unsigned long flags;
@@ -1630,7 +1713,7 @@ gpio1_interrupt(int irq, void *arg)
                        disable_irq_nosync(gpio_irq);
                        gpio_irq_enabled = 0;
                }
-               pmu_irq_stats[1]++;
+               pmu_irq_stats[12]++;
                adb_int_pending = 1;
                spin_unlock_irqrestore(&pmu_lock, flags);
                via_pmu_interrupt(0, NULL);
@@ -1644,7 +1727,7 @@ pmu_enable_irled(int on)
 {
        struct adb_request req;
 
-       if (vias == NULL)
+       if (pmu_state == uninitialized)
                return ;
        if (pmu_kind == PMU_KEYLARGO_BASED)
                return ;
@@ -1659,7 +1742,7 @@ pmu_restart(void)
 {
        struct adb_request req;
 
-       if (via == NULL)
+       if (pmu_state == uninitialized)
                return;
 
        local_irq_disable();
@@ -1684,7 +1767,7 @@ pmu_shutdown(void)
 {
        struct adb_request req;
 
-       if (via == NULL)
+       if (pmu_state == uninitialized)
                return;
 
        local_irq_disable();
@@ -1712,7 +1795,7 @@ pmu_shutdown(void)
 int
 pmu_present(void)
 {
-       return via != NULL;
+       return pmu_state != uninitialized;
 }
 
 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
@@ -1725,29 +1808,29 @@ static u32 save_via[8];
 static void
 save_via_state(void)
 {
-       save_via[0] = in_8(&via[ANH]);
-       save_via[1] = in_8(&via[DIRA]);
-       save_via[2] = in_8(&via[B]);
-       save_via[3] = in_8(&via[DIRB]);
-       save_via[4] = in_8(&via[PCR]);
-       save_via[5] = in_8(&via[ACR]);
-       save_via[6] = in_8(&via[T1CL]);
-       save_via[7] = in_8(&via[T1CH]);
+       save_via[0] = in_8(&via1[ANH]);
+       save_via[1] = in_8(&via1[DIRA]);
+       save_via[2] = in_8(&via1[B]);
+       save_via[3] = in_8(&via1[DIRB]);
+       save_via[4] = in_8(&via1[PCR]);
+       save_via[5] = in_8(&via1[ACR]);
+       save_via[6] = in_8(&via1[T1CL]);
+       save_via[7] = in_8(&via1[T1CH]);
 }
 static void
 restore_via_state(void)
 {
-       out_8(&via[ANH], save_via[0]);
-       out_8(&via[DIRA], save_via[1]);
-       out_8(&via[B], save_via[2]);
-       out_8(&via[DIRB], save_via[3]);
-       out_8(&via[PCR], save_via[4]);
-       out_8(&via[ACR], save_via[5]);
-       out_8(&via[T1CL], save_via[6]);
-       out_8(&via[T1CH], save_via[7]);
-       out_8(&via[IER], IER_CLR | 0x7f);       /* disable all intrs */
-       out_8(&via[IFR], 0x7f);                         /* clear IFR */
-       out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
+       out_8(&via1[ANH],  save_via[0]);
+       out_8(&via1[DIRA], save_via[1]);
+       out_8(&via1[B],    save_via[2]);
+       out_8(&via1[DIRB], save_via[3]);
+       out_8(&via1[PCR],  save_via[4]);
+       out_8(&via1[ACR],  save_via[5]);
+       out_8(&via1[T1CL], save_via[6]);
+       out_8(&via1[T1CH], save_via[7]);
+       out_8(&via1[IER], IER_CLR | 0x7f);      /* disable all intrs */
+       out_8(&via1[IFR], 0x7f);                        /* clear IFR */
+       out_8(&via1[IER], IER_SET | SR_INT | CB1_INT);
 }
 
 #define        GRACKLE_PM      (1<<7)
@@ -2253,6 +2336,7 @@ static int pmu_ioctl(struct file *filp,
        int error = -EINVAL;
 
        switch (cmd) {
+#ifdef CONFIG_PPC_PMAC
        case PMU_IOC_SLEEP:
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
@@ -2262,6 +2346,7 @@ static int pmu_ioctl(struct file *filp,
                        return put_user(0, argp);
                else
                        return put_user(1, argp);
+#endif
 
 #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY
        /* Compatibility ioctl's for backlight */
@@ -2378,7 +2463,7 @@ static struct miscdevice pmu_device = {
 
 static int pmu_device_init(void)
 {
-       if (!via)
+       if (pmu_state == uninitialized)
                return 0;
        if (misc_register(&pmu_device) < 0)
                printk(KERN_ERR "via-pmu: cannot register misc device.\n");
@@ -2389,33 +2474,33 @@ device_initcall(pmu_device_init);
 
 #ifdef DEBUG_SLEEP
 static inline void 
-polled_handshake(volatile unsigned char __iomem *via)
+polled_handshake(void)
 {
-       via[B] &= ~TREQ; eieio();
-       while ((via[B] & TACK) != 0)
+       via2[B] &= ~TREQ; eieio();
+       while ((via2[B] & TACK) != 0)
                ;
-       via[B] |= TREQ; eieio();
-       while ((via[B] & TACK) == 0)
+       via2[B] |= TREQ; eieio();
+       while ((via2[B] & TACK) == 0)
                ;
 }
 
 static inline void 
-polled_send_byte(volatile unsigned char __iomem *via, int x)
+polled_send_byte(int x)
 {
-       via[ACR] |= SR_OUT | SR_EXT; eieio();
-       via[SR] = x; eieio();
-       polled_handshake(via);
+       via1[ACR] |= SR_OUT | SR_EXT; eieio();
+       via1[SR] = x; eieio();
+       polled_handshake();
 }
 
 static inline int
-polled_recv_byte(volatile unsigned char __iomem *via)
+polled_recv_byte(void)
 {
        int x;
 
-       via[ACR] = (via[ACR] & ~SR_OUT) | SR_EXT; eieio();
-       x = via[SR]; eieio();
-       polled_handshake(via);
-       x = via[SR]; eieio();
+       via1[ACR] = (via1[ACR] & ~SR_OUT) | SR_EXT; eieio();
+       x = via1[SR]; eieio();
+       polled_handshake();
+       x = via1[SR]; eieio();
        return x;
 }
 
@@ -2424,7 +2509,6 @@ pmu_polled_request(struct adb_request *req)
 {
        unsigned long flags;
        int i, l, c;
-       volatile unsigned char __iomem *v = via;
 
        req->complete = 1;
        c = req->data[0];
@@ -2436,21 +2520,21 @@ pmu_polled_request(struct adb_request *req)
        while (pmu_state != idle)
                pmu_poll();
 
-       while ((via[B] & TACK) == 0)
+       while ((via2[B] & TACK) == 0)
                ;
-       polled_send_byte(v, c);
+       polled_send_byte(c);
        if (l < 0) {
                l = req->nbytes - 1;
-               polled_send_byte(v, l);
+               polled_send_byte(l);
        }
        for (i = 1; i <= l; ++i)
-               polled_send_byte(v, req->data[i]);
+               polled_send_byte(req->data[i]);
 
        l = pmu_data_len[c][1];
        if (l < 0)
-               l = polled_recv_byte(v);
+               l = polled_recv_byte();
        for (i = 0; i < l; ++i)
-               req->reply[i + req->reply_len] = polled_recv_byte(v);
+               req->reply[i + req->reply_len] = polled_recv_byte();
 
        if (req->done)
                (*req->done)(req);