diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/swim3.c | 230 | ||||
-rw-r--r-- | drivers/char/hvsi.c | 7 | ||||
-rw-r--r-- | drivers/macintosh/macio-adb.c | 19 | ||||
-rw-r--r-- | drivers/macintosh/macio_asic.c | 152 | ||||
-rw-r--r-- | drivers/macintosh/smu.c | 6 | ||||
-rw-r--r-- | drivers/macintosh/via-cuda.c | 24 | ||||
-rw-r--r-- | drivers/macintosh/via-pmu.c | 33 | ||||
-rw-r--r-- | drivers/net/mace.c | 4 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.c | 6 | ||||
-rw-r--r-- | drivers/video/offb.c | 284 |
10 files changed, 394 insertions, 371 deletions
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 3721e12..cc42e76 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -250,8 +250,6 @@ static int floppy_open(struct inode *inode, struct file *filp); static int floppy_release(struct inode *inode, struct file *filp); static int floppy_check_change(struct gendisk *disk); static int floppy_revalidate(struct gendisk *disk); -static int swim3_add_device(struct device_node *swims); -int swim3_init(void); #ifndef CONFIG_PMAC_MEDIABAY #define check_media_bay(which, what) 1 @@ -1011,114 +1009,63 @@ static struct block_device_operations floppy_fops = { .revalidate_disk= floppy_revalidate, }; -int swim3_init(void) -{ - struct device_node *swim; - int err = -ENOMEM; - int i; - - swim = find_devices("floppy"); - while (swim && (floppy_count < MAX_FLOPPIES)) - { - swim3_add_device(swim); - swim = swim->next; - } - - swim = find_devices("swim3"); - while (swim && (floppy_count < MAX_FLOPPIES)) - { - swim3_add_device(swim); - swim = swim->next; - } - - if (!floppy_count) - return -ENODEV; - - for (i = 0; i < floppy_count; i++) { - disks[i] = alloc_disk(1); - if (!disks[i]) - goto out; - } - - if (register_blkdev(FLOPPY_MAJOR, "fd")) { - err = -EBUSY; - goto out; - } - - swim3_queue = blk_init_queue(do_fd_request, &swim3_lock); - if (!swim3_queue) { - err = -ENOMEM; - goto out_queue; - } - - for (i = 0; i < floppy_count; i++) { - struct gendisk *disk = disks[i]; - disk->major = FLOPPY_MAJOR; - disk->first_minor = i; - disk->fops = &floppy_fops; - disk->private_data = &floppy_states[i]; - disk->queue = swim3_queue; - disk->flags |= GENHD_FL_REMOVABLE; - sprintf(disk->disk_name, "fd%d", i); - set_capacity(disk, 2880); - add_disk(disk); - } - return 0; - -out_queue: - unregister_blkdev(FLOPPY_MAJOR, "fd"); -out: - while (i--) - put_disk(disks[i]); - /* shouldn't we do something with results of swim_add_device()? */ - return err; -} - -static int swim3_add_device(struct device_node *swim) +static int swim3_add_device(struct macio_dev *mdev, int index) { + struct device_node *swim = mdev->ofdev.node; struct device_node *mediabay; - struct floppy_state *fs = &floppy_states[floppy_count]; - struct resource res_reg, res_dma; + struct floppy_state *fs = &floppy_states[index]; + int rc = -EBUSY; - if (of_address_to_resource(swim, 0, &res_reg) || - of_address_to_resource(swim, 1, &res_dma)) { - printk(KERN_ERR "swim3: Can't get addresses\n"); - return -EINVAL; + /* Check & Request resources */ + if (macio_resource_count(mdev) < 2) { + printk(KERN_WARNING "ifd%d: no address for %s\n", + index, swim->full_name); + return -ENXIO; } - if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, - " (reg)") == NULL) { - printk(KERN_ERR "swim3: Can't request register space\n"); - return -EINVAL; + if (macio_irq_count(mdev) < 2) { + printk(KERN_WARNING "fd%d: no intrs for device %s\n", + index, swim->full_name); } - if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, - " (dma)") == NULL) { - release_mem_region(res_reg.start, - res_reg.end - res_reg.start + 1); - printk(KERN_ERR "swim3: Can't request DMA space\n"); - return -EINVAL; + if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { + printk(KERN_ERR "fd%d: can't request mmio resource for %s\n", + index, swim->full_name); + return -EBUSY; } - - if (swim->n_intrs < 2) { - printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", - swim->n_intrs); - release_mem_region(res_reg.start, - res_reg.end - res_reg.start + 1); - release_mem_region(res_dma.start, - res_dma.end - res_dma.start + 1); - return -EINVAL; + if (macio_request_resource(mdev, 1, "swim3 (dma)")) { + printk(KERN_ERR "fd%d: can't request dma resource for %s\n", + index, swim->full_name); + macio_release_resource(mdev, 0); + return -EBUSY; } + dev_set_drvdata(&mdev->ofdev.dev, fs); - mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? swim->parent : NULL; + mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? + swim->parent : NULL; if (mediabay == NULL) pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); memset(fs, 0, sizeof(*fs)); spin_lock_init(&fs->lock); fs->state = idle; - fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); - fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); - fs->swim3_intr = swim->intrs[0].line; - fs->dma_intr = swim->intrs[1].line; + fs->swim3 = (struct swim3 __iomem *) + ioremap(macio_resource_start(mdev, 0), 0x200); + if (fs->swim3 == NULL) { + printk("fd%d: couldn't map registers for %s\n", + index, swim->full_name); + rc = -ENOMEM; + goto out_release; + } + fs->dma = (struct dbdma_regs __iomem *) + ioremap(macio_resource_start(mdev, 1), 0x200); + if (fs->dma == NULL) { + printk("fd%d: couldn't map DMA for %s\n", + index, swim->full_name); + iounmap(fs->swim3); + rc = -ENOMEM; + goto out_release; + } + fs->swim3_intr = macio_irq(mdev, 0); + fs->dma_intr = macio_irq(mdev, 1);; fs->cur_cyl = -1; fs->cur_sector = -1; fs->secpercyl = 36; @@ -1132,15 +1079,16 @@ static int swim3_add_device(struct device_node *swim) st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { - printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr); + printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n", + index, fs->swim3_intr, swim->full_name); pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); + goto out_unmap; return -EBUSY; } /* if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", fs->dma_intr); - pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); return -EBUSY; } */ @@ -1150,8 +1098,90 @@ static int swim3_add_device(struct device_node *swim) printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, mediabay ? "in media bay" : ""); - floppy_count++; - + return 0; + + out_unmap: + iounmap(fs->dma); + iounmap(fs->swim3); + + out_release: + macio_release_resource(mdev, 0); + macio_release_resource(mdev, 1); + + return rc; +} + +static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match) +{ + int i, rc; + struct gendisk *disk; + + /* Add the drive */ + rc = swim3_add_device(mdev, floppy_count); + if (rc) + return rc; + + /* Now create the queue if not there yet */ + if (swim3_queue == NULL) { + /* If we failed, there isn't much we can do as the driver is still + * too dumb to remove the device, just bail out + */ + if (register_blkdev(FLOPPY_MAJOR, "fd")) + return 0; + swim3_queue = blk_init_queue(do_fd_request, &swim3_lock); + if (swim3_queue == NULL) { + unregister_blkdev(FLOPPY_MAJOR, "fd"); + return 0; + } + } + + /* Now register that disk. Same comment about failure handling */ + i = floppy_count++; + disk = disks[i] = alloc_disk(1); + if (disk == NULL) + return 0; + + disk->major = FLOPPY_MAJOR; + disk->first_minor = i; + disk->fops = &floppy_fops; + disk->private_data = &floppy_states[i]; + disk->queue = swim3_queue; + disk->flags |= GENHD_FL_REMOVABLE; + sprintf(disk->disk_name, "fd%d", i); + set_capacity(disk, 2880); + add_disk(disk); + + return 0; +} + +static struct of_device_id swim3_match[] = +{ + { + .name = "swim3", + }, + { + .compatible = "ohare-swim3" + }, + { + .compatible = "swim3" + }, +}; + +static struct macio_driver swim3_driver = +{ + .name = "swim3", + .match_table = swim3_match, + .probe = swim3_attach, +#if 0 + .suspend = swim3_suspend, + .resume = swim3_resume, +#endif +}; + + +int swim3_init(void) +{ + macio_register_driver(&swim3_driver); return 0; } diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 8dc205b..56612a2 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c @@ -1299,13 +1299,12 @@ static int __init hvsi_console_init(void) hp->inbuf_end = hp->inbuf; hp->state = HVSI_CLOSED; hp->vtermno = *vtermno; - hp->virq = virt_irq_create_mapping(irq[0]); + hp->virq = irq_create_mapping(NULL, irq[0], 0); if (hp->virq == NO_IRQ) { printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", - __FUNCTION__, hp->virq); + __FUNCTION__, irq[0]); continue; - } else - hp->virq = irq_offset_up(hp->virq); + } hvsi_count++; } diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c index 314fc08..4b08852 100644 --- a/drivers/macintosh/macio-adb.c +++ b/drivers/macintosh/macio-adb.c @@ -90,22 +90,12 @@ int macio_init(void) { struct device_node *adbs; struct resource r; + unsigned int irq; adbs = find_compatible_devices("adb", "chrp,adb0"); if (adbs == 0) return -ENXIO; -#if 0 - { int i = 0; - - printk("macio_adb_init: node = %p, addrs =", adbs->node); - while(!of_address_to_resource(adbs, i, &r)) - printk(" %x(%x)", r.start, r.end - r.start); - printk(", intrs ="); - for (i = 0; i < adbs->n_intrs; ++i) - printk(" %x", adbs->intrs[i].line); - printk("\n"); } -#endif if (of_address_to_resource(adbs, 0, &r)) return -ENXIO; adb = ioremap(r.start, sizeof(struct adb_regs)); @@ -117,10 +107,9 @@ int macio_init(void) out_8(&adb->active_lo.r, 0xff); out_8(&adb->autopoll.r, APE); - if (request_irq(adbs->intrs[0].line, macio_adb_interrupt, - 0, "ADB", (void *)0)) { - printk(KERN_ERR "ADB: can't get irq %d\n", - adbs->intrs[0].line); + irq = irq_of_parse_and_map(adbs, 0); + if (request_irq(irq, macio_adb_interrupt, 0, "ADB", (void *)0)) { + printk(KERN_ERR "ADB: can't get irq %d\n", irq); return -EAGAIN; } out_8(&adb->intr_enb.r, DFB | TAG); diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 40ae7b6..80c0c66 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -280,75 +280,128 @@ static void macio_release_dev(struct device *dev) static int macio_resource_quirks(struct device_node *np, struct resource *res, int index) { - if (res->flags & IORESOURCE_MEM) { - /* Grand Central has too large resource 0 on some machines */ - if (index == 0 && !strcmp(np->name, "gc")) - res->end = res->start + 0x1ffff; + /* Only quirks for memory resources for now */ + if ((res->flags & IORESOURCE_MEM) == 0) + return 0; + + /* Grand Central has too large resource 0 on some machines */ + if (index == 0 && !strcmp(np->name, "gc")) + res->end = res->start + 0x1ffff; - /* Airport has bogus resource 2 */ - if (index >= 2 && !strcmp(np->name, "radio")) - return 1; + /* Airport has bogus resource 2 */ + if (index >= 2 && !strcmp(np->name, "radio")) + return 1; #ifndef CONFIG_PPC64 - /* DBDMAs may have bogus sizes */ - if ((res->start & 0x0001f000) == 0x00008000) - res->end = res->start + 0xff; + /* DBDMAs may have bogus sizes */ + if ((res->start & 0x0001f000) == 0x00008000) + res->end = res->start + 0xff; #endif /* CONFIG_PPC64 */ - /* ESCC parent eats child resources. We could have added a - * level of hierarchy, but I don't really feel the need - * for it - */ - if (!strcmp(np->name, "escc")) - return 1; - - /* ESCC has bogus resources >= 3 */ - if (index >= 3 && !(strcmp(np->name, "ch-a") && - strcmp(np->name, "ch-b"))) - return 1; - - /* Media bay has too many resources, keep only first one */ - if (index > 0 && !strcmp(np->name, "media-bay")) - return 1; - - /* Some older IDE resources have bogus sizes */ - if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && - strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { - if (index == 0 && (res->end - res->start) > 0xfff) - res->end = res->start + 0xfff; - if (index == 1 && (res->end - res->start) > 0xff) - res->end = res->start + 0xff; - } + /* ESCC parent eats child resources. We could have added a + * level of hierarchy, but I don't really feel the need + * for it + */ + if (!strcmp(np->name, "escc")) + return 1; + + /* ESCC has bogus resources >= 3 */ + if (index >= 3 && !(strcmp(np->name, "ch-a") && + strcmp(np->name, "ch-b"))) + return 1; + + /* Media bay has too many resources, keep only first one */ + if (index > 0 && !strcmp(np->name, "media-bay")) + return 1; + + /* Some older IDE resources have bogus sizes */ + if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && + strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { + if (index == 0 && (res->end - res->start) > 0xfff) + res->end = res->start + 0xfff; + if (index == 1 && (res->end - res->start) > 0xff) + res->end = res->start + 0xff; } return 0; } +static void macio_create_fixup_irq(struct macio_dev *dev, int index, + unsigned int line) +{ + unsigned int irq; -static void macio_setup_interrupts(struct macio_dev *dev) + irq = irq_create_mapping(NULL, line, 0); + if (irq != NO_IRQ) { + dev->interrupt[index].start = irq; + dev->interrupt[index].flags = IORESOURCE_IRQ; + dev->interrupt[index].name = dev->ofdev.dev.bus_id; + } + if (dev->n_interrupts <= index) + dev->n_interrupts = index + 1; +} + +static void macio_add_missing_resources(struct macio_dev *dev) { struct device_node *np = dev->ofdev.node; - int i,j; + unsigned int irq_base; + + /* Gatwick has some missing interrupts on child nodes */ + if (dev->bus->chip->type != macio_gatwick) + return; - /* For now, we use pre-parsed entries in the device-tree for - * interrupt routing and addresses, but we should change that - * to dynamically parsed entries and so get rid of most of the - * clutter in struct device_node + /* irq_base is always 64 on gatwick. I have no cleaner way to get + * that value from here at this point */ - for (i = j = 0; i < np->n_intrs; i++) { + irq_base = 64; + + /* Fix SCC */ + if (strcmp(np->name, "ch-a") == 0) { + macio_create_fixup_irq(dev, 0, 15 + irq_base); + macio_create_fixup_irq(dev, 1, 4 + irq_base); + macio_create_fixup_irq(dev, 2, 5 + irq_base); + printk(KERN_INFO "macio: fixed SCC irqs on gatwick\n"); + } + + /* Fix media-bay */ + if (strcmp(np->name, "media-bay") == 0) { + macio_create_fixup_irq(dev, 0, 29 + irq_base); + printk(KERN_INFO "macio: fixed media-bay irq on gatwick\n"); + } + + /* Fix left media bay childs */ + if (dev->media_bay != NULL && strcmp(np->name, "floppy") == 0) { + macio_create_fixup_irq(dev, 0, 19 + irq_base); + macio_create_fixup_irq(dev, 1, 1 + irq_base); + printk(KERN_INFO "macio: fixed left floppy irqs\n"); + } + if (dev->media_bay != NULL && strcasecmp(np->name, "ata4") == 0) { + macio_create_fixup_irq(dev, 0, 14 + irq_base); + macio_create_fixup_irq(dev, 0, 3 + irq_base); + printk(KERN_INFO "macio: fixed left ide irqs\n"); + } +} + +static void macio_setup_interrupts(struct macio_dev *dev) +{ + struct device_node *np = dev->ofdev.node; + unsigned int irq; + int i = 0, j = 0; + + for (;;) { struct resource *res = &dev->interrupt[j]; if (j >= MACIO_DEV_COUNT_IRQS) break; - res->start = np->intrs[i].line; - res->flags = IORESOURCE_IO; - if (np->intrs[j].sense) - res->flags |= IORESOURCE_IRQ_LOWLEVEL; - else - res->flags |= IORESOURCE_IRQ_HIGHEDGE; + irq = irq_of_parse_and_map(np, i++); + if (irq == NO_IRQ) + break; + res->start = irq; + res->flags = IORESOURCE_IRQ; res->name = dev->ofdev.dev.bus_id; - if (macio_resource_quirks(np, res, i)) + if (macio_resource_quirks(np, res, i - 1)) { memset(res, 0, sizeof(struct resource)); - else + continue; + } else j++; } dev->n_interrupts = j; @@ -445,6 +498,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, /* Setup interrupts & resources */ macio_setup_interrupts(dev); macio_setup_resources(dev, parent_res); + macio_add_missing_resources(dev); /* Register with core */ if (of_device_register(&dev->ofdev) != 0) { diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index ff6d9bf..f139a74 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -497,8 +497,7 @@ int __init smu_init (void) smu->doorbell = *data; if (smu->doorbell < 0x50) smu->doorbell += 0x50; - if (np->n_intrs > 0) - smu->db_irq = np->intrs[0].line; + smu->db_irq = irq_of_parse_and_map(np, 0); of_node_put(np); @@ -515,8 +514,7 @@ int __init smu_init (void) smu->msg = *data; if (smu->msg < 0x50) smu->msg += 0x50; - if (np->n_intrs > 0) - smu->msg_irq = np->intrs[0].line; + smu->msg_irq = irq_of_parse_and_map(np, 0); of_node_put(np); } while(0); diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index 6501db5..69d5452 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -34,13 +34,6 @@ static volatile unsigned char __iomem *via; static DEFINE_SPINLOCK(cuda_lock); -#ifdef CONFIG_MAC -#define CUDA_IRQ IRQ_MAC_ADB -#define eieio() -#else -#define CUDA_IRQ vias->intrs[0].line -#endif - /* VIA registers - spaced 0x200 bytes apart */ #define RS 0x200 /* skip between registers */ #define B 0 /* B-side data */ @@ -189,11 +182,24 @@ int __init find_via_cuda(void) static int __init via_cuda_start(void) { + unsigned int irq; + if (via == NULL) return -ENODEV; - if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { - printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); +#ifdef CONFIG_MAC + irq = IRQ_MAC_ADB; +#else /* CONFIG_MAC */ + irq = irq_of_parse_and_map(vias, 0); + if (irq == NO_IRQ) { + printk(KERN_ERR "via-cuda: can't map interrupts for %s\n", + vias->full_name); + return -ENODEV; + } +#endif /* CONFIG_MAP */ + + if (request_irq(irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) { + printk(KERN_ERR "via-cuda: can't request irq %d\n", irq); return -EAGAIN; } diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index c1193d3..06ca80b 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -64,10 +64,6 @@ #include <asm/backlight.h> #endif -#ifdef CONFIG_PPC32 -#include <asm/open_pic.h> -#endif - #include "via-pmu-event.h" /* Some compile options */ @@ -151,7 +147,7 @@ static int pmu_fully_inited = 0; static int pmu_has_adb; static struct device_node *gpio_node; static unsigned char __iomem *gpio_reg = NULL; -static int gpio_irq = -1; +static int gpio_irq = NO_IRQ; static int gpio_irq_enabled = -1; static volatile int pmu_suspended = 0; static spinlock_t pmu_lock; @@ -403,22 +399,21 @@ static int __init pmu_init(void) */ static int __init via_pmu_start(void) { + unsigned int irq; + if (vias == NULL) return -ENODEV; batt_req.complete = 1; -#ifndef CONFIG_PPC_MERGE - if (pmu_kind == PMU_KEYLARGO_BASED) - openpic_set_irq_priority(vias->intrs[0].line, - OPENPIC_PRIORITY_DEFAULT + 1); -#endif - - if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU", - (void *)0)) { - printk(KERN_ERR "VIA-PMU: can't get irq %d\n", - vias->intrs[0].line); - return -EAGAIN; + irq = irq_of_parse_and_map(vias, 0); + if (irq == NO_IRQ) { + printk(KERN_ERR "via-pmu: can't map interruptn"); + return -ENODEV; + } + if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) { + printk(KERN_ERR "via-pmu: can't request irq %d\n", irq); + return -ENODEV; } if (pmu_kind == PMU_KEYLARGO_BASED) { @@ -426,10 +421,10 @@ static int __init via_pmu_start(void) if (gpio_node == NULL) gpio_node = of_find_node_by_name(NULL, "pmu-interrupt"); - if (gpio_node && gpio_node->n_intrs > 0) - gpio_irq = gpio_node->intrs[0].line; + if (gpio_node) + gpio_irq = irq_of_parse_and_map(gpio_node, 0); - if (gpio_irq != -1) { + if (gpio_irq != NO_IRQ) { if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1 ADB", (void *)0)) printk(KERN_ERR "pmu: can't get irq %d" diff --git a/drivers/net/mace.c b/drivers/net/mace.c index f2c0bf8..29e4b5a 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -242,12 +242,12 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i } rc = request_irq(mp->tx_dma_intr, mace_txdma_intr, 0, "MACE-txdma", dev); if (rc) { - printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[1].line); + printk(KERN_ERR "MACE: can't get irq %d\n", mp->tx_dma_intr); goto err_free_irq; } rc = request_irq(mp->rx_dma_intr, mace_rxdma_intr, 0, "MACE-rxdma", dev); if (rc) { - printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[2].line); + printk(KERN_ERR "MACE: can't get irq %d\n", mp->rx_dma_intr); goto err_free_tx_irq; } diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 459c023..bfd2a22 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1443,8 +1443,8 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } - uap->tx_dma_irq = np->intrs[1].line; - uap->rx_dma_irq = np->intrs[2].line; + uap->tx_dma_irq = irq_of_parse_and_map(np, 1); + uap->rx_dma_irq = irq_of_parse_and_map(np, 2); } no_dma: @@ -1491,7 +1491,7 @@ no_dma: * Init remaining bits of "port" structure */ uap->port.iotype = UPIO_MEM; - uap->port.irq = np->intrs[0].line; + uap->port.irq = irq_of_parse_and_map(np, 0); uap->port.uartclk = ZS_CLOCK; uap->port.fifosize = 1; uap->port.ops = &pmz_pops; diff --git a/drivers/video/offb.c b/drivers/video/offb.c index bfeb11b..71ce1fa 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -97,14 +97,43 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { struct offb_par *par = (struct offb_par *) info->par; + int i, depth; + u32 *pal = info->pseudo_palette; - if (!par->cmap_adr || regno > 255) + depth = info->var.bits_per_pixel; + if (depth == 16) + depth = (info->var.green.length == 5) ? 15 : 16; + + if (regno > 255 || + (depth == 16 && regno > 63) || + (depth == 15 && regno > 31)) return 1; + if (regno < 16) { + switch (depth) { + case 15: + pal[regno] = (regno << 10) | (regno << 5) | regno; + break; + case 16: + pal[regno] = (regno << 11) | (regno << 5) | regno; + break; + case 24: + pal[regno] = (regno << 16) | (regno << 8) | regno; + break; + case 32: + i = (regno << 8) | regno; + pal[regno] = (i << 16) | i; + break; + } + } + red >>= 8; green >>= 8; blue >>= 8; + if (!par->cmap_adr) + return 0; + switch (par->cmap_type) { case cmap_m64: writeb(regno, par->cmap_adr); @@ -141,20 +170,6 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, break; } - if (regno < 16) - switch (info->var.bits_per_pixel) { - case 16: - ((u16 *) (info->pseudo_palette))[regno] = - (regno << 10) | (regno << 5) | regno; - break; - case 32: - { - int i = (regno << 8) | regno; - ((u32 *) (info->pseudo_palette))[regno] = - (i << 16) | i; - break; - } - } return 0; } @@ -223,81 +238,9 @@ int __init offb_init(void) { struct device_node *dp = NULL, *boot_disp = NULL; -#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) - struct device_node *macos_display = NULL; -#endif if (fb_get_options("offb", NULL)) return -ENODEV; -#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) - /* If we're booted from BootX... */ - if (boot_infos != 0) { - unsigned long addr = - (unsigned long) boot_infos->dispDeviceBase; - u32 *addrp; - u64 daddr, dsize; - unsigned int flags; - - /* find the device node corresponding to the macos display */ - while ((dp = of_find_node_by_type(dp, "display"))) { - int i; - - /* - * Look for an AAPL,address property first. - */ - unsigned int na; - unsigned int *ap = - (unsigned int *)get_property(dp, "AAPL,address", - &na); - if (ap != 0) { - for (na /= sizeof(unsigned int); na > 0; - --na, ++ap) - if (*ap <= addr && - addr < *ap + 0x1000000) { - macos_display = dp; - goto foundit; - } - } - - /* - * See if the display address is in one of the address - * ranges for this display. - */ - i = 0; - for (;;) { - addrp = of_get_address(dp, i++, &dsize, &flags); - if (addrp == NULL) - break; - if (!(flags & IORESOURCE_MEM)) - continue; - daddr = of_translate_address(dp, addrp); - if (daddr == OF_BAD_ADDR) - continue; - if (daddr <= addr && addr < (daddr + dsize)) { - macos_display = dp; - goto foundit; - } - } - foundit: - if (macos_display) { - printk(KERN_INFO "MacOS display is %s\n", - dp->full_name); - break; - } - } - - /* initialize it */ - offb_init_fb(macos_display ? macos_display-> - name : "MacOS display", - macos_display ? macos_display-> - full_name : "MacOS display", - boot_infos->dispDeviceRect[2], - boot_infos->dispDeviceRect[3], - boot_infos->dispDeviceDepth, - boot_infos->dispDeviceRowBytes, addr, NULL); - } -#endif /* defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) */ - for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { if (get_property(dp, "linux,opened", NULL) && get_property(dp, "linux,boot-display", NULL)) { @@ -317,94 +260,93 @@ int __init offb_init(void) static void __init offb_init_nodriver(struct device_node *dp) { - int *pp, i; unsigned int len; - int width = 640, height = 480, depth = 8, pitch; - unsigned int flags, rsize, *up; - u64 address = OF_BAD_ADDR; - u32 *addrp; + int i, width = 640, height = 480, depth = 8, pitch = 640; + unsigned int flags, rsize, addr_prop = 0; + unsigned long max_size = 0; + u64 rstart, address = OF_BAD_ADDR; + u32 *pp, *addrp, *up; u64 asize; - if ((pp = (int *) get_property(dp, "depth", &len)) != NULL - && len == sizeof(int)) + pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "depth", &len); + if (pp && len == sizeof(u32)) depth = *pp; - if ((pp = (int *) get_property(dp, "width", &len)) != NULL - && len == sizeof(int)) + + pp = (u32 *)get_property(dp, "linux,bootx-width", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "width", &len); + if (pp && len == sizeof(u32)) width = *pp; - if ((pp = (int *) get_property(dp, "height", &len)) != NULL - && len == sizeof(int)) + + pp = (u32 *)get_property(dp, "linux,bootx-height", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "height", &len); + if (pp && len == sizeof(u32)) height = *pp; - if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL - && len == sizeof(int)) { + + pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "linebytes", &len); + if (pp && len == sizeof(u32)) pitch = *pp; - if (pitch == 1) - pitch = 0x1000; - } else - pitch = width; - - rsize = (unsigned long)pitch * (unsigned long)height * - (unsigned long)(depth / 8); - - /* Try to match device to a PCI device in order to get a properly - * translated address rather then trying to decode the open firmware - * stuff in various incorrect ways - */ -#ifdef CONFIG_PCI - /* First try to locate the PCI device if any */ - { - struct pci_dev *pdev = NULL; - - for_each_pci_dev(pdev) { - if (dp == pci_device_to_OF_node(pdev)) - break; - } - if (pdev) { - for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) { - if ((pci_resource_flags(pdev, i) & - IORESOURCE_MEM) && - (pci_resource_len(pdev, i) >= rsize)) - address = pci_resource_start(pdev, i); - } - pci_dev_put(pdev); - } - } -#endif /* CONFIG_PCI */ - - /* This one is dodgy, we may drop it ... */ - if (address == OF_BAD_ADDR && - (up = (unsigned *) get_property(dp, "address", &len)) != NULL && - len == sizeof(unsigned int)) - address = (u64) * up; - - if (address == OF_BAD_ADDR) { - for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) - != NULL; i++) { - if (!(flags & IORESOURCE_MEM)) - continue; - if (asize >= pitch * height * depth / 8) - break; - } - if (addrp == NULL) { - printk(KERN_ERR - "no framebuffer address found for %s\n", - dp->full_name); - return; - } - address = of_translate_address(dp, addrp); - if (address == OF_BAD_ADDR) { - printk(KERN_ERR - "can't translate framebuffer address for %s\n", - dp->full_name); - return; + else + pitch = width * ((depth + 7) / 8); + + rsize = (unsigned long)pitch * (unsigned long)height; + + /* Ok, now we try to figure out the address of the framebuffer. + * + * Unfortunately, Open Firmware doesn't provide a standard way to do + * so. All we can do is a dodgy heuristic that happens to work in + * practice. On most machines, the "address" property contains what + * we need, though not on Matrox cards found in IBM machines. What I've + * found that appears to give good results is to go through the PCI + * ranges and pick one that is both big enough and if possible encloses + * the "address" property. If none match, we pick the biggest + */ + up = (u32 *)get_property(dp, "linux,bootx-addr", &len); + if (up == NULL) + up = (u32 *)get_property(dp, "address", &len); + if (up && len == sizeof(u32)) + addr_prop = *up; + + for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) + != NULL; i++) { + int match_addrp = 0; + + if (!(flags & IORESOURCE_MEM)) + continue; + if (asize < rsize) + continue; + rstart = of_translate_address(dp, addrp); + if (rstart == OF_BAD_ADDR) + continue; + if (addr_prop && (rstart <= addr_prop) && + ((rstart + asize) >= (addr_prop + rsize))) + match_addrp = 1; + if (match_addrp) { + address = addr_prop; + break; } + if (rsize > max_size) { + max_size = rsize; + address = OF_BAD_ADDR; + } + if (address == OF_BAD_ADDR) + address = rstart; + } + if (address == OF_BAD_ADDR && addr_prop) + address = (u64)addr_prop; + if (address != OF_BAD_ADDR) { /* kludge for valkyrie */ if (strcmp(dp->name, "valkyrie") == 0) address += 0x1000; + offb_init_fb(dp->name, dp->full_name, width, height, depth, + pitch, address, dp); } - offb_init_fb(dp->name, dp->full_name, width, height, depth, - pitch, address, dp); - } static void __init offb_init_fb(const char *name, const char *full_name, @@ -412,7 +354,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, int pitch, unsigned long address, struct device_node *dp) { - unsigned long res_size = pitch * height * depth / 8; + unsigned long res_size = pitch * height * (depth + 7) / 8; struct offb_par *par = &default_par; unsigned long res_start = address; struct fb_fix_screeninfo *fix; @@ -426,7 +368,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, printk(KERN_INFO "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", width, height, name, address, depth, pitch); - if (depth != 8 && depth != 16 && depth != 32) { + if (depth != 8 && depth != 15 && depth != 16 && depth != 32) { printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth); release_mem_region(res_start, res_size); @@ -502,7 +444,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, : */ FB_VISUAL_TRUECOLOR; var->xoffset = var->yoffset = 0; - var->bits_per_pixel = depth; switch (depth) { case 8: var->bits_per_pixel = 8; @@ -515,7 +456,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, var->transp.offset = 0; var->transp.length = 0; break; - case 16: /* RGB 555 */ + case 15: /* RGB 555 */ var->bits_per_pixel = 16; var->red.offset = 10; var->red.length = 5; @@ -526,6 +467,17 @@ static void __init offb_init_fb(const char *name, const char *full_name, var->transp.offset = 0; var->transp.length = 0; break; + case 16: /* RGB 565 */ + var->bits_per_pixel = 16; + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.offset = 0; + var->transp.length = 0; + break; case 32: /* RGB 888 */ var->bits_per_pixel = 32; var->red.offset = 16; |