summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-07-03 15:28:34 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-03 15:28:34 -0700
commit912b2539e1e062cec73e2e61448e507f7719bd08 (patch)
tree233807569ee5e0ab3118dd54c0ae9164fec8343e /drivers
parent70b97a7f0b19cf1f2619deb5cc41e8b78c591aa7 (diff)
parent39ab9c212aac48f2744f2fd7722fa639ec048eb7 (diff)
downloadop-kernel-dev-912b2539e1e062cec73e2e61448e507f7719bd08.zip
op-kernel-dev-912b2539e1e062cec73e2e61448e507f7719bd08.tar.gz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: powerpc: add defconfig for Freescale MPC8349E-mITX board powerpc: Add base support for the Freescale MPC8349E-mITX eval board Documentation: correct values in MPC8548E SEC example node [POWERPC] Actually copy over i8259.c to arch/ppc/syslib this time [POWERPC] Add new interrupt mapping core and change platforms to use it [POWERPC] Copy i8259 code back to arch/ppc [POWERPC] New device-tree interrupt parsing code [POWERPC] Use the genirq framework [PATCH] genirq: Allow fasteoi handler to retrigger disabled interrupts [POWERPC] Update the SWIM3 (powermac) floppy driver [POWERPC] Fix error handling in detecting legacy serial ports [POWERPC] Fix booting on Momentum "Apache" board (a Maple derivative) [POWERPC] Fix various offb and BootX-related issues [POWERPC] Add a default config for 32-bit CHRP machines [POWERPC] fix implicit declaration on cell. [POWERPC] change get_property to return void *
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/swim3.c230
-rw-r--r--drivers/char/hvsi.c7
-rw-r--r--drivers/macintosh/macio-adb.c19
-rw-r--r--drivers/macintosh/macio_asic.c152
-rw-r--r--drivers/macintosh/smu.c6
-rw-r--r--drivers/macintosh/via-cuda.c24
-rw-r--r--drivers/macintosh/via-pmu.c33
-rw-r--r--drivers/net/mace.c4
-rw-r--r--drivers/serial/pmac_zilog.c6
-rw-r--r--drivers/video/offb.c284
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;
OpenPOWER on IntegriCloud