[POWERPC] Clean out a bunch of duplicate includes
[safe/jmp/linux-2.6] / arch / powerpc / platforms / powermac / low_i2c.c
index df2343e..da2007e 100644 (file)
@@ -30,7 +30,6 @@
 #undef DEBUG
 #undef DEBUG_LOW
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/init.h>
@@ -41,8 +40,8 @@
 #include <linux/completion.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
-#include <linux/completion.h>
 #include <linux/timer.h>
+#include <linux/mutex.h>
 #include <asm/keylargo.h>
 #include <asm/uninorth.h>
 #include <asm/io.h>
@@ -85,7 +84,7 @@ struct pmac_i2c_bus
        void                    *hostdata;
        int                     channel;        /* some hosts have multiple */
        int                     mode;           /* current mode */
-       struct semaphore        sem;
+       struct mutex            mutex;
        int                     opened;
        int                     polled;         /* open mode */
        struct platform_device  *platform_dev;
@@ -105,7 +104,7 @@ static LIST_HEAD(pmac_i2c_busses);
 
 struct pmac_i2c_host_kw
 {
-       struct semaphore        mutex;          /* Access mutex for use by
+       struct mutex            mutex;          /* Access mutex for use by
                                                 * i2c-keywest */
        void __iomem            *base;          /* register base address */
        int                     bsteps;         /* register stepping */
@@ -343,7 +342,7 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
 }
 
 /* Interrupt handler */
-static irqreturn_t kw_i2c_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t kw_i2c_irq(int irq, void *dev_id)
 {
        struct pmac_i2c_host_kw *host = dev_id;
        unsigned long flags;
@@ -376,14 +375,14 @@ static void kw_i2c_timeout(unsigned long data)
 static int kw_i2c_open(struct pmac_i2c_bus *bus)
 {
        struct pmac_i2c_host_kw *host = bus->hostdata;
-       down(&host->mutex);
+       mutex_lock(&host->mutex);
        return 0;
 }
 
 static void kw_i2c_close(struct pmac_i2c_bus *bus)
 {
        struct pmac_i2c_host_kw *host = bus->hostdata;
-       up(&host->mutex);
+       mutex_unlock(&host->mutex);
 }
 
 static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
@@ -478,7 +477,8 @@ static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
 static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
 {
        struct pmac_i2c_host_kw *host;
-       u32                     *psteps, *prate, *addrp, steps;
+       const u32               *psteps, *prate, *addrp;
+       u32                     steps;
 
        host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL);
        if (host == NULL) {
@@ -491,27 +491,27 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
         * on all i2c keywest nodes so far ... we would have to fallback
         * to macio parsing if that wasn't the case
         */
-       addrp = (u32 *)get_property(np, "AAPL,address", NULL);
+       addrp = of_get_property(np, "AAPL,address", NULL);
        if (addrp == NULL) {
                printk(KERN_ERR "low_i2c: Can't find address for %s\n",
                       np->full_name);
                kfree(host);
                return NULL;
        }
-       init_MUTEX(&host->mutex);
+       mutex_init(&host->mutex);
        init_completion(&host->complete);
        spin_lock_init(&host->lock);
        init_timer(&host->timeout_timer);
        host->timeout_timer.function = kw_i2c_timeout;
        host->timeout_timer.data = (unsigned long)host;
 
-       psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
+       psteps = of_get_property(np, "AAPL,address-step", NULL);
        steps = psteps ? (*psteps) : 0x10;
        for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
                steps >>= 1;
        /* Select interface rate */
        host->speed = KW_I2C_MODE_25KHZ;
-       prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
+       prate = of_get_property(np, "AAPL,i2c-rate", NULL);
        if (prate) switch(*prate) {
        case 100:
                host->speed = KW_I2C_MODE_100KHZ;
@@ -523,10 +523,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
                host->speed = KW_I2C_MODE_25KHZ;
                break;
        }       
-       if (np->n_intrs > 0)
-               host->irq = np->intrs[0].line;
-       else
-               host->irq = NO_IRQ;
+       host->irq = irq_of_parse_and_map(np, 0);
+       if (host->irq == NO_IRQ)
+               printk(KERN_WARNING
+                      "low_i2c: Failed to map interrupt for %s\n",
+                      np->full_name);
 
        host->base = ioremap((*addrp), 0x1000);
        if (host->base == NULL) {
@@ -570,7 +571,7 @@ static void __init kw_i2c_add(struct pmac_i2c_host_kw *host,
        bus->open = kw_i2c_open;
        bus->close = kw_i2c_close;
        bus->xfer = kw_i2c_xfer;
-       init_MUTEX(&bus->sem);
+       mutex_init(&bus->mutex);
        if (controller == busnode)
                bus->flags = pmac_i2c_multibus;
        list_add(&bus->link, &pmac_i2c_busses);
@@ -618,8 +619,8 @@ static void __init kw_i2c_probe(void)
                } else {
                        for (child = NULL;
                             (child = of_get_next_child(np, child)) != NULL;) {
-                               u32 *reg =
-                                       (u32 *)get_property(child, "reg", NULL);
+                               const u32 *reg = of_get_property(child,
+                                               "reg", NULL);
                                if (reg == NULL)
                                        continue;
                                kw_i2c_add(host, np, child, *reg);
@@ -797,7 +798,7 @@ static void __init pmu_i2c_probe(void)
                bus->mode = pmac_i2c_mode_std;
                bus->hostdata = bus + 1;
                bus->xfer = pmu_i2c_xfer;
-               init_MUTEX(&bus->sem);
+               mutex_init(&bus->mutex);
                bus->flags = pmac_i2c_multibus;
                list_add(&bus->link, &pmac_i2c_busses);
 
@@ -881,7 +882,7 @@ static void __init smu_i2c_probe(void)
 {
        struct device_node *controller, *busnode;
        struct pmac_i2c_bus *bus;
-       u32 *reg;
+       const u32 *reg;
        int sz;
 
        if (!smu_present())
@@ -904,7 +905,7 @@ static void __init smu_i2c_probe(void)
                if (strcmp(busnode->type, "i2c") &&
                    strcmp(busnode->type, "i2c-bus"))
                        continue;
-               reg = (u32 *)get_property(busnode, "reg", NULL);
+               reg = of_get_property(busnode, "reg", NULL);
                if (reg == NULL)
                        continue;
 
@@ -920,7 +921,7 @@ static void __init smu_i2c_probe(void)
                bus->mode = pmac_i2c_mode_std;
                bus->hostdata = bus + 1;
                bus->xfer = smu_i2c_xfer;
-               init_MUTEX(&bus->sem);
+               mutex_init(&bus->mutex);
                bus->flags = 0;
                list_add(&bus->link, &pmac_i2c_busses);
 
@@ -948,9 +949,9 @@ struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node)
                list_for_each_entry(bus, &pmac_i2c_busses, link) {
                        if (p == bus->busnode) {
                                if (prev && bus->flags & pmac_i2c_multibus) {
-                                       u32 *reg;
-                                       reg = (u32 *)get_property(prev, "reg",
-                                                                 NULL);
+                                       const u32 *reg;
+                                       reg = of_get_property(prev, "reg",
+                                                               NULL);
                                        if (!reg)
                                                continue;
                                        if (((*reg) >> 8) != bus->channel)
@@ -971,7 +972,7 @@ EXPORT_SYMBOL_GPL(pmac_i2c_find_bus);
 
 u8 pmac_i2c_get_dev_addr(struct device_node *device)
 {
-       u32 *reg = (u32 *)get_property(device, "reg", NULL);
+       const u32 *reg = of_get_property(device, "reg", NULL);
 
        if (reg == NULL)
                return 0;
@@ -1092,13 +1093,13 @@ int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled)
 {
        int rc;
 
-       down(&bus->sem);
+       mutex_lock(&bus->mutex);
        bus->polled = polled || pmac_i2c_force_poll;
        bus->opened = 1;
        bus->mode = pmac_i2c_mode_std;
        if (bus->open && (rc = bus->open(bus)) != 0) {
                bus->opened = 0;
-               up(&bus->sem);
+               mutex_unlock(&bus->mutex);
                return rc;
        }
        return 0;
@@ -1111,7 +1112,7 @@ void pmac_i2c_close(struct pmac_i2c_bus *bus)
        if (bus->close)
                bus->close(bus);
        bus->opened = 0;
-       up(&bus->sem);
+       mutex_unlock(&bus->mutex);
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_close);
 
@@ -1157,6 +1158,7 @@ EXPORT_SYMBOL_GPL(pmac_i2c_xfer);
 /* some quirks for platform function decoding */
 enum {
        pmac_i2c_quirk_invmask = 0x00000001u,
+       pmac_i2c_quirk_skip = 0x00000002u,
 };
 
 static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
@@ -1172,6 +1174,15 @@ static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
                /* XXX Study device-tree's & apple drivers are get the quirks
                 * right !
                 */
+               /* Workaround: It seems that running the clockspreading
+                * properties on the eMac will cause lockups during boot.
+                * The machine seems to work fine without that. So for now,
+                * let's make sure i2c-hwclock doesn't match about "imic"
+                * clocks and we'll figure out if we really need to do
+                * something special about those later.
+                */
+               { "i2c-hwclock", "imic5002", pmac_i2c_quirk_skip },
+               { "i2c-hwclock", "imic5003", pmac_i2c_quirk_skip },
                { "i2c-hwclock", NULL, pmac_i2c_quirk_invmask },
                { "i2c-cpu-voltage", NULL, 0},
                {  "temp-monitor", NULL, 0 },
@@ -1196,8 +1207,10 @@ static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
                                if (strcmp(np->name, p->name))
                                        continue;
                                if (p->compatible &&
-                                   !device_is_compatible(np, p->compatible))
+                                   !of_device_is_compatible(np, p->compatible))
                                        continue;
+                               if (p->quirks & pmac_i2c_quirk_skip)
+                                       break;
                                callback(np, p->quirks);
                                break;
                        }