|
@@ -84,3 +84,65 @@ struct
|
|
*
|
|
*
|
|
* The register selects a DWORD (32 bit) register offset. Hence it
|
|
* The register selects a DWORD (32 bit) register offset. Hence it
|
|
* doesn't get shifted by 2 bits as we want to "drop" the bottom two
|
|
* doesn't get shifted by 2 bits as we want to "drop" the bottom two
|
|
|
|
+ * bits.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
|
|
|
|
+ unsigned long *pci_addr, unsigned char *type1)
|
|
|
|
+{
|
|
|
|
+ struct pci_controller *hose = pbus->sysdata;
|
|
|
|
+ unsigned long addr;
|
|
|
|
+ u8 bus = pbus->number;
|
|
|
|
+
|
|
|
|
+ DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
|
|
|
|
+ "pci_addr=0x%p, type1=0x%p)\n",
|
|
|
|
+ bus, device_fn, where, pci_addr, type1));
|
|
|
|
+
|
|
|
|
+ if (!pbus->parent) /* No parent means peer PCI bus. */
|
|
|
|
+ bus = 0;
|
|
|
|
+ *type1 = (bus != 0);
|
|
|
|
+
|
|
|
|
+ addr = (bus << 16) | (device_fn << 8) | where;
|
|
|
|
+ addr |= hose->config_space_base;
|
|
|
|
+
|
|
|
|
+ *pci_addr = addr;
|
|
|
|
+ DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+tsunami_read_config(struct pci_bus *bus, unsigned int devfn, int where,
|
|
|
|
+ int size, u32 *value)
|
|
|
|
+{
|
|
|
|
+ unsigned long addr;
|
|
|
|
+ unsigned char type1;
|
|
|
|
+
|
|
|
|
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
|
|
|
|
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
|
|
|
+
|
|
|
|
+ switch (size) {
|
|
|
|
+ case 1:
|
|
|
|
+ *value = __kernel_ldbu(*(vucp)addr);
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ *value = __kernel_ldwu(*(vusp)addr);
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ *value = *(vuip)addr;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return PCIBIOS_SUCCESSFUL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+tsunami_write_config(struct pci_bus *bus, unsigned int devfn, int where,
|
|
|
|
+ int size, u32 value)
|
|
|
|
+{
|
|
|
|
+ unsigned long addr;
|
|
|
|
+ unsigned char type1;
|
|
|
|
+
|
|
|
|
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
|
|
|
|
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
|
|
|
+
|