You can see the patch for arch specific code at: http://permalink.gmane.org/gmane.linux.ports.arm.kernel/88754 Yes , there are different methods to generate cfg0 and cfg1 in my controller. I had already tried that , but it is not helping. This modification is not in posted patch. So I am pesting the pcie_ops basic cfg rd/wr routine here: ---------------------------------------------------------------------------------------------------------------------- static int spear13xx_pcie_rd_conf(struct pcie_port *pp, struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base; u32 address = (u32)pp->va_cfg0_base | (PCI_FUNC(devfn) << 16) | (where & 0xFFFC); writel((bus->number << 24) | (PCI_SLOT(devfn) << 19), &app_reg->pom_cfg0_addr_start); writel(readl(&app_reg->slv_armisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_armisc); if (bus->parent->number == pp->root_bus_nr) writel(readl(&app_reg->slv_armisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE0, &app_reg->slv_armisc); else writel(readl(&app_reg->slv_armisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE1, &app_reg->slv_armisc); udelay(1); *val = readl(address); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2) *val = (*val >> (8 * (where & 3))) & 0xffff; writel(readl(&app_reg->slv_armisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_armisc); return PCIBIOS_SUCCESSFUL; } static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; if (pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { *val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; } spin_lock_irqsave(&pp->conf_lock, flags); if (bus->number != pp->root_bus_nr) ret = spear13xx_pcie_rd_conf(pp, bus, devfn, where, size, val); else { spear_dbi_read_reg(pp, where, size, val); ret = 0; } spin_unlock_irqrestore(&pp->conf_lock, flags); return ret; } static int spear13xx_pcie_wr_conf(struct pcie_port *pp, struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { int ret = PCIBIOS_SUCCESSFUL; struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base; u32 address = (u32)pp->va_cfg0_base | (PCI_FUNC(devfn) << 16) | (where & 0xFFFC); writel((bus->number << 24) | (PCI_SLOT(devfn) << 19), &app_reg->pom_cfg0_addr_start); writel(readl(&app_reg->slv_awmisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_awmisc); if (bus->parent->number == pp->root_bus_nr) writel(readl(&app_reg->slv_awmisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE0, &app_reg->slv_awmisc); else writel(readl(&app_reg->slv_awmisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE1, &app_reg->slv_awmisc); if (size == 4) writel(val, address); else if (size == 2) writew(val, address + (where & 2)); else if (size == 1) writeb(val, address + (where & 3)); else ret = PCIBIOS_BAD_REGISTER_NUMBER; writel(readl(&app_reg->slv_awmisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_awmisc); return ret; } static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; if (pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) return PCIBIOS_DEVICE_NOT_FOUND; spin_lock_irqsave(&pp->conf_lock, flags); if (bus->number != pp->root_bus_nr) ret = spear13xx_pcie_wr_conf(pp, bus, devfn, where, size, val); else { spear_dbi_write_reg(pp, where, size, val); ret = 0; } spin_unlock_irqrestore(&pp->conf_lock, flags); return ret; } static int spear13xx_pcie_rd_conf(struct pcie_port *pp, struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base; u32 address = (u32)pp->va_cfg0_base | (PCI_FUNC(devfn) << 16) | (where & 0xFFFC); writel((bus->number << 24) | (PCI_SLOT(devfn) << 19), &app_reg->pom_cfg0_addr_start); writel(readl(&app_reg->slv_armisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_armisc); if (bus->parent->number == pp->root_bus_nr) writel(readl(&app_reg->slv_armisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE0, &app_reg->slv_armisc); else writel(readl(&app_reg->slv_armisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE1, &app_reg->slv_armisc); udelay(1); *val = readl(address); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2) *val = (*val >> (8 * (where & 3))) & 0xffff; writel(readl(&app_reg->slv_armisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_armisc); return PCIBIOS_SUCCESSFUL; } static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; if (pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { *val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; } spin_lock_irqsave(&pp->conf_lock, flags); if (bus->number != pp->root_bus_nr) ret = spear13xx_pcie_rd_conf(pp, bus, devfn, where, size, val); else { spear_dbi_read_reg(pp, where, size, val); ret = 0; } spin_unlock_irqrestore(&pp->conf_lock, flags); return ret; } static int spear13xx_pcie_wr_conf(struct pcie_port *pp, struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { int ret = PCIBIOS_SUCCESSFUL; struct pcie_app_reg *app_reg = (struct pcie_app_reg *) pp->va_app_base; u32 address = (u32)pp->va_cfg0_base | (PCI_FUNC(devfn) << 16) | (where & 0xFFFC); writel((bus->number << 24) | (PCI_SLOT(devfn) << 19), &app_reg->pom_cfg0_addr_start); writel(readl(&app_reg->slv_awmisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_awmisc); if (bus->parent->number == pp->root_bus_nr) writel(readl(&app_reg->slv_awmisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE0, &app_reg->slv_awmisc); else writel(readl(&app_reg->slv_awmisc) | AXI_OP_TYPE_CONFIG_RDRW_TYPE1, &app_reg->slv_awmisc); if (size == 4) writel(val, address); else if (size == 2) writew(val, address + (where & 2)); else if (size == 1) writeb(val, address + (where & 3)); else ret = PCIBIOS_BAD_REGISTER_NUMBER; writel(readl(&app_reg->slv_awmisc) & ~(AXI_OP_TYPE_MASK), &app_reg->slv_awmisc); return ret; } static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; if (pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) return PCIBIOS_DEVICE_NOT_FOUND; spin_lock_irqsave(&pp->conf_lock, flags); if (bus->number != pp->root_bus_nr) ret = spear13xx_pcie_wr_conf(pp, bus, devfn, where, size, val); else { spear_dbi_write_reg(pp, where, size, val); ret = 0; } spin_unlock_irqrestore(&pp->conf_lock, flags); return ret; } On Thu, Oct 21, 2010 at 5:55 PM, Matthew Wilcox <matthew@xxxxxx> wrote: > On Thu, Oct 21, 2010 at 05:16:22PM +0530, Pratyush Anand wrote: >> Hi All, >> >> I have developed support for a PCIE host controller on linux platform >> for an SOC. >> >> It works well with PCIE devices (e.g.usb3.0 card, ethernet card, pcie >> to sata )from various vendors. >> >> However, I am having problem in using any card where device is >> connected below a bridge (class 0x0604). >> >> What ever bus number is programmed , cfg register value are from >> bridge only not of downstream device. > > It would be helpful if you could post your code. I suspect the problem is > that you're telling the host bridge to generate CfgRd0 instead of CfgRd1. > > -- > Matthew Wilcox Intel Open Source Technology Centre > "Bill, look, we understand that you're interested in selling us this > operating system, but compare it to ours. We can't possibly take such > a retrograde step." > -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html