OSDN Git Service

Merge branch 'pci/msi' into next
[uclinux-h8/linux.git] / drivers / pci / host / pcie-designware.c
index 76d3d8e..f727445 100644 (file)
@@ -73,6 +73,8 @@ static unsigned long global_io_offset;
 
 static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
 {
+       BUG_ON(!sys->private_data);
+
        return sys->private_data;
 }
 
@@ -261,11 +263,6 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
        int irq, pos0, pos1, i;
        struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
 
-       if (!pp) {
-               BUG();
-               return -EINVAL;
-       }
-
        pos0 = find_first_zero_bit(pp->msi_irq_in_use,
                        MAX_MSI_IRQS);
        if (pos0 % no_irqs) {
@@ -326,10 +323,6 @@ static void clear_irq(unsigned int irq)
        /* get the port structure */
        msi = irq_data_get_msi(data);
        pp = sys_to_pcie(msi->dev->bus->sysdata);
-       if (!pp) {
-               BUG();
-               return;
-       }
 
        /* undo what was done in assign_irq */
        pos = data->hwirq;
@@ -350,14 +343,8 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
        struct msi_msg msg;
        struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
 
-       if (!pp) {
-               BUG();
-               return -EINVAL;
-       }
-
-       pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
-                               &msg_ctr);
-       msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
+       pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &msg_ctr);
+       msgvec = (msg_ctr & PCI_MSI_FLAGS_QSIZE) >> 4;
        if (msgvec == 0)
                msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
        if (msgvec > 5)
@@ -373,12 +360,17 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
         */
        desc->msi_attrib.multiple = msgvec;
 
-       if (pp->ops->get_msi_data)
-               msg.address_lo = pp->ops->get_msi_data(pp);
+       if (pp->ops->get_msi_addr)
+               msg.address_lo = pp->ops->get_msi_addr(pp);
        else
                msg.address_lo = virt_to_phys((void *)pp->msi_data);
        msg.address_hi = 0x0;
-       msg.data = pos;
+
+       if (pp->ops->get_msi_data)
+               msg.data = pp->ops->get_msi_data(pp, pos);
+       else
+               msg.data = pos;
+
        write_msi_msg(irq, &msg);
 
        return 0;
@@ -435,16 +427,16 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
 
        cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
        if (cfg_res) {
-               pp->config.cfg0_size = resource_size(cfg_res)/2;
-               pp->config.cfg1_size = resource_size(cfg_res)/2;
+               pp->cfg0_size = resource_size(cfg_res)/2;
+               pp->cfg1_size = resource_size(cfg_res)/2;
                pp->cfg0_base = cfg_res->start;
-               pp->cfg1_base = cfg_res->start + pp->config.cfg0_size;
+               pp->cfg1_base = cfg_res->start + pp->cfg0_size;
 
                /* Find the untranslated configuration space address */
                index = of_property_match_string(np, "reg-names", "config");
-               addrp = of_get_address(np, index, false, false);
+               addrp = of_get_address(np, index, NULL, NULL);
                pp->cfg0_mod_base = of_read_number(addrp, ns);
-               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->config.cfg0_size;
+               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
        } else {
                dev_err(pp->dev, "missing *config* reg space\n");
        }
@@ -466,9 +458,9 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
                        pp->io.end = min_t(resource_size_t,
                                           IO_SPACE_LIMIT,
                                           range.pci_addr + range.size
-                                          + global_io_offset);
-                       pp->config.io_size = resource_size(&pp->io);
-                       pp->config.io_bus_addr = range.pci_addr;
+                                          + global_io_offset - 1);
+                       pp->io_size = resource_size(&pp->io);
+                       pp->io_bus_addr = range.pci_addr;
                        pp->io_base = range.cpu_addr;
 
                        /* Find the untranslated IO space address */
@@ -478,8 +470,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
                if (restype == IORESOURCE_MEM) {
                        of_pci_range_to_resource(&range, np, &pp->mem);
                        pp->mem.name = "MEM";
-                       pp->config.mem_size = resource_size(&pp->mem);
-                       pp->config.mem_bus_addr = range.pci_addr;
+                       pp->mem_size = resource_size(&pp->mem);
+                       pp->mem_bus_addr = range.pci_addr;
 
                        /* Find the untranslated MEM space address */
                        pp->mem_mod_base = of_read_number(parser.range -
@@ -487,19 +479,29 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
                }
                if (restype == 0) {
                        of_pci_range_to_resource(&range, np, &pp->cfg);
-                       pp->config.cfg0_size = resource_size(&pp->cfg)/2;
-                       pp->config.cfg1_size = resource_size(&pp->cfg)/2;
+                       pp->cfg0_size = resource_size(&pp->cfg)/2;
+                       pp->cfg1_size = resource_size(&pp->cfg)/2;
                        pp->cfg0_base = pp->cfg.start;
-                       pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size;
+                       pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
 
                        /* Find the untranslated configuration space address */
                        pp->cfg0_mod_base = of_read_number(parser.range -
                                                           parser.np + na, ns);
                        pp->cfg1_mod_base = pp->cfg0_mod_base +
-                                           pp->config.cfg0_size;
+                                           pp->cfg0_size;
                }
        }
 
+       ret = of_pci_parse_bus_range(np, &pp->busn);
+       if (ret < 0) {
+               pp->busn.name = np->name;
+               pp->busn.start = 0;
+               pp->busn.end = 0xff;
+               pp->busn.flags = IORESOURCE_BUS;
+               dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
+                       ret, &pp->busn);
+       }
+
        if (!pp->dbi_base) {
                pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
                                        resource_size(&pp->cfg));
@@ -512,9 +514,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
        pp->mem_base = pp->mem.start;
 
        if (!pp->va_cfg0_base) {
-               pp->cfg0_base = pp->cfg.start;
                pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
-                                               pp->config.cfg0_size);
+                                               pp->cfg0_size);
                if (!pp->va_cfg0_base) {
                        dev_err(pp->dev, "error with ioremap in function\n");
                        return -ENOMEM;
@@ -522,9 +523,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
        }
 
        if (!pp->va_cfg1_base) {
-               pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size;
                pp->va_cfg1_base = devm_ioremap(pp->dev, pp->cfg1_base,
-                                               pp->config.cfg1_size);
+                                               pp->cfg1_size);
                if (!pp->va_cfg1_base) {
                        dev_err(pp->dev, "error with ioremap\n");
                        return -ENOMEM;
@@ -571,7 +571,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
        dw_pci.private_data = (void **)&pp;
 
        pci_common_init_dev(pp->dev, &dw_pci);
-       pci_assign_unassigned_resources();
 #ifdef CONFIG_PCI_DOMAINS
        dw_pci.domain++;
 #endif
@@ -586,7 +585,7 @@ static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev)
                          PCIE_ATU_VIEWPORT);
        dw_pcie_writel_rc(pp, pp->cfg0_mod_base, PCIE_ATU_LOWER_BASE);
        dw_pcie_writel_rc(pp, (pp->cfg0_mod_base >> 32), PCIE_ATU_UPPER_BASE);
-       dw_pcie_writel_rc(pp, pp->cfg0_mod_base + pp->config.cfg0_size - 1,
+       dw_pcie_writel_rc(pp, pp->cfg0_mod_base + pp->cfg0_size - 1,
                          PCIE_ATU_LIMIT);
        dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
        dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
@@ -602,7 +601,7 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
        dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
        dw_pcie_writel_rc(pp, pp->cfg1_mod_base, PCIE_ATU_LOWER_BASE);
        dw_pcie_writel_rc(pp, (pp->cfg1_mod_base >> 32), PCIE_ATU_UPPER_BASE);
-       dw_pcie_writel_rc(pp, pp->cfg1_mod_base + pp->config.cfg1_size - 1,
+       dw_pcie_writel_rc(pp, pp->cfg1_mod_base + pp->cfg1_size - 1,
                          PCIE_ATU_LIMIT);
        dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
        dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
@@ -617,10 +616,10 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
        dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
        dw_pcie_writel_rc(pp, pp->mem_mod_base, PCIE_ATU_LOWER_BASE);
        dw_pcie_writel_rc(pp, (pp->mem_mod_base >> 32), PCIE_ATU_UPPER_BASE);
-       dw_pcie_writel_rc(pp, pp->mem_mod_base + pp->config.mem_size - 1,
+       dw_pcie_writel_rc(pp, pp->mem_mod_base + pp->mem_size - 1,
                          PCIE_ATU_LIMIT);
-       dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
-       dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
+       dw_pcie_writel_rc(pp, pp->mem_bus_addr, PCIE_ATU_LOWER_TARGET);
+       dw_pcie_writel_rc(pp, upper_32_bits(pp->mem_bus_addr),
                          PCIE_ATU_UPPER_TARGET);
        dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 }
@@ -633,10 +632,10 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
        dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
        dw_pcie_writel_rc(pp, pp->io_mod_base, PCIE_ATU_LOWER_BASE);
        dw_pcie_writel_rc(pp, (pp->io_mod_base >> 32), PCIE_ATU_UPPER_BASE);
-       dw_pcie_writel_rc(pp, pp->io_mod_base + pp->config.io_size - 1,
+       dw_pcie_writel_rc(pp, pp->io_mod_base + pp->io_size - 1,
                          PCIE_ATU_LIMIT);
-       dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
-       dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
+       dw_pcie_writel_rc(pp, pp->io_bus_addr, PCIE_ATU_LOWER_TARGET);
+       dw_pcie_writel_rc(pp, upper_32_bits(pp->io_bus_addr),
                          PCIE_ATU_UPPER_TARGET);
        dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 }
@@ -720,11 +719,6 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
        struct pcie_port *pp = sys_to_pcie(bus->sysdata);
        int ret;
 
-       if (!pp) {
-               BUG();
-               return -EINVAL;
-       }
-
        if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
                *val = 0xffffffff;
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -749,11 +743,6 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
        struct pcie_port *pp = sys_to_pcie(bus->sysdata);
        int ret;
 
-       if (!pp) {
-               BUG();
-               return -EINVAL;
-       }
-
        if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -781,19 +770,17 @@ static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
 
        pp = sys_to_pcie(sys);
 
-       if (!pp)
-               return 0;
-
-       if (global_io_offset < SZ_1M && pp->config.io_size > 0) {
-               sys->io_offset = global_io_offset - pp->config.io_bus_addr;
+       if (global_io_offset < SZ_1M && pp->io_size > 0) {
+               sys->io_offset = global_io_offset - pp->io_bus_addr;
                pci_ioremap_io(global_io_offset, pp->io_base);
                global_io_offset += SZ_64K;
                pci_add_resource_offset(&sys->resources, &pp->io,
                                        sys->io_offset);
        }
 
-       sys->mem_offset = pp->mem.start - pp->config.mem_bus_addr;
+       sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
        pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
+       pci_add_resource(&sys->resources, &pp->busn);
 
        return 1;
 }
@@ -803,14 +790,13 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
        struct pci_bus *bus;
        struct pcie_port *pp = sys_to_pcie(sys);
 
-       if (pp) {
-               pp->root_bus_nr = sys->busnr;
-               bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
-                                       sys, &sys->resources);
-       } else {
-               bus = NULL;
-               BUG();
-       }
+       pp->root_bus_nr = sys->busnr;
+       bus = pci_create_root_bus(pp->dev, sys->busnr,
+                                 &dw_pcie_ops, sys, &sys->resources);
+       if (!bus)
+               return NULL;
+
+       pci_scan_child_bus(bus);
 
        if (bus && pp->ops->scan_bus)
                pp->ops->scan_bus(pp);
@@ -849,7 +835,6 @@ static struct hw_pci dw_pci = {
 
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
-       struct pcie_port_info *config = &pp->config;
        u32 val;
        u32 membase;
        u32 memlimit;
@@ -904,7 +889,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
 
        /* setup memory base, memory limit */
        membase = ((u32)pp->mem_base & 0xfff00000) >> 16;
-       memlimit = (config->mem_size + (u32)pp->mem_base) & 0xfff00000;
+       memlimit = (pp->mem_size + (u32)pp->mem_base) & 0xfff00000;
        val = memlimit | membase;
        dw_pcie_writel_rc(pp, val, PCI_MEMORY_BASE);