parisc: Hide Diva-built-in serial aux and graphics card
[pandora-kernel.git] / drivers / parisc / lba_pci.c
index 59fbbf1..37d8fdc 100644 (file)
@@ -980,28 +980,38 @@ static void
 lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
 {
        unsigned long bytecnt;
-       pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;     /* PA_VIEW */
-       pdc_pat_cell_mod_maddr_block_t io_pdc_cell;     /* IO_VIEW */
        long io_count;
        long status;    /* PDC return status */
        long pa_count;
+       pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell;    /* PA_VIEW */
+       pdc_pat_cell_mod_maddr_block_t *io_pdc_cell;    /* IO_VIEW */
        int i;
 
+       pa_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL);
+       if (!pa_pdc_cell)
+               return;
+
+       io_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL);
+       if (!io_pdc_cell) {
+               kfree(pa_pdc_cell);
+               return;
+       }
+
        /* return cell module (IO view) */
        status = pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
-                               PA_VIEW, pa_pdc_cell);
-       pa_count = pa_pdc_cell.mod[1];
+                               PA_VIEW, pa_pdc_cell);
+       pa_count = pa_pdc_cell->mod[1];
 
        status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
-                               IO_VIEW, &io_pdc_cell);
-       io_count = io_pdc_cell.mod[1];
+                               IO_VIEW, io_pdc_cell);
+       io_count = io_pdc_cell->mod[1];
 
        /* We've already done this once for device discovery...*/
        if (status != PDC_OK) {
                panic("pdc_pat_cell_module() call failed for LBA!\n");
        }
 
-       if (PAT_GET_ENTITY(pa_pdc_cell.mod_info) != PAT_ENTITY_LBA) {
+       if (PAT_GET_ENTITY(pa_pdc_cell->mod_info) != PAT_ENTITY_LBA) {
                panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n");
        }
 
@@ -1016,8 +1026,8 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                } *p, *io;
                struct resource *r;
 
-               p = (void *) &(pa_pdc_cell.mod[2+i*3]);
-               io = (void *) &(io_pdc_cell.mod[2+i*3]);
+               p = (void *) &(pa_pdc_cell->mod[2+i*3]);
+               io = (void *) &(io_pdc_cell->mod[2+i*3]);
 
                /* Convert the PAT range data to PCI "struct resource" */
                switch(p->type & 0xff) {
@@ -1096,6 +1106,9 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                        break;
                }
        }
+
+       kfree(pa_pdc_cell);
+       kfree(io_pdc_cell);
 }
 #else
 /* keep compiler from complaining about missing declarations */
@@ -1509,10 +1522,6 @@ lba_driver_probe(struct parisc_device *dev)
        lba_bus = lba_dev->hba.hba_bus =
                pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
                                cfg_ops, NULL);
-       if (lba_bus) {
-               lba_next_bus = lba_bus->subordinate + 1;
-               pci_bus_add_devices(lba_bus);
-       }
 
        /* This is in lieu of calling pci_assign_unassigned_resources() */
        if (is_pdc_pat()) {
@@ -1533,7 +1542,6 @@ lba_driver_probe(struct parisc_device *dev)
        }
        pci_enable_bridges(lba_bus);
 
-
        /*
        ** Once PCI register ops has walked the bus, access to config
        ** space is restricted. Avoids master aborts on config cycles.
@@ -1543,6 +1551,11 @@ lba_driver_probe(struct parisc_device *dev)
                lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
        }
 
+       if (lba_bus) {
+               lba_next_bus = lba_bus->subordinate + 1;
+               pci_bus_add_devices(lba_bus);
+       }
+
        /* Whew! Finally done! Tell services we got this one covered. */
        return 0;
 }
@@ -1590,3 +1603,36 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
        iounmap(base_addr);
 }
 
+
+/*
+ * The design of the Diva management card in rp34x0 machines (rp3410, rp3440)
+ * seems rushed, so that many built-in components simply don't work.
+ * The following quirks disable the serial AUX port and the built-in ATI RV100
+ * Radeon 7000 graphics card which both don't have any external connectors and
+ * thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as
+ * such makes those machines the only PARISC machines on which we can't use
+ * ttyS0 as boot console.
+ */
+static void quirk_diva_ati_card(struct pci_dev *dev)
+{
+       if (dev->subsystem_vendor != PCI_VENDOR_ID_HP ||
+           dev->subsystem_device != 0x1292)
+               return;
+
+       dev_info(&dev->dev, "Hiding Diva built-in ATI card");
+       dev->device = 0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY,
+       quirk_diva_ati_card);
+
+static void quirk_diva_aux_disable(struct pci_dev *dev)
+{
+       if (dev->subsystem_vendor != PCI_VENDOR_ID_HP ||
+           dev->subsystem_device != 0x1291)
+               return;
+
+       dev_info(&dev->dev, "Hiding Diva built-in AUX serial device");
+       dev->device = 0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX,
+       quirk_diva_aux_disable);