UPSTREAM: PCI: rockchip: remove the pointer to L1 substate cap
[firefly-linux-kernel-4.4.55.git] / drivers / pci / xen-pcifront.c
index 966abc6054d7b625c18a5eeb854dc065b40d43c1..5f70fee59a947da1daddbeb2253043dc79c794fb 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/workqueue.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
+#include <linux/ktime.h>
+#include <xen/platform_pci.h>
 
 #include <asm/xen/swiotlb-xen.h>
 #define INVALID_GRANT_REF (0)
@@ -51,7 +53,7 @@ struct pcifront_device {
 };
 
 struct pcifront_sd {
-       int domain;
+       struct pci_sysdata sd;
        struct pcifront_device *pdev;
 };
 
@@ -65,7 +67,9 @@ static inline void pcifront_init_sd(struct pcifront_sd *sd,
                                    unsigned int domain, unsigned int bus,
                                    struct pcifront_device *pdev)
 {
-       sd->domain = domain;
+       /* Because we do not expose that information via XenBus. */
+       sd->sd.node = first_online_node;
+       sd->sd.domain = domain;
        sd->pdev = pdev;
 }
 
@@ -114,7 +118,6 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
        evtchn_port_t port = pdev->evtchn;
        unsigned irq = pdev->irq;
        s64 ns, ns_timeout;
-       struct timeval tv;
 
        spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
 
@@ -131,8 +134,7 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
         * (in the latter case we end up continually re-executing poll() with a
         * timeout in the past). 1s difference gives plenty of slack for error.
         */
-       do_gettimeofday(&tv);
-       ns_timeout = timeval_to_ns(&tv) + 2 * (s64)NSEC_PER_SEC;
+       ns_timeout = ktime_get_ns() + 2 * (s64)NSEC_PER_SEC;
 
        xen_clear_irq_pending(irq);
 
@@ -140,8 +142,7 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
                        (unsigned long *)&pdev->sh_info->flags)) {
                xen_poll_irq_timeout(irq, jiffies + 3*HZ);
                xen_clear_irq_pending(irq);
-               do_gettimeofday(&tv);
-               ns = timeval_to_ns(&tv);
+               ns = ktime_get_ns();
                if (ns > ns_timeout) {
                        dev_err(&pdev->xdev->dev,
                                "pciback not responding!!!\n");
@@ -266,7 +267,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
        }
 
        i = 0;
-       list_for_each_entry(entry, &dev->msi_list, list) {
+       for_each_pci_msi_entry(entry, dev) {
                op.msix_entries[i].entry = entry->msi_attrib.entry_nr;
                /* Vector is useless at this point. */
                op.msix_entries[i].vector = -1;
@@ -445,9 +446,15 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
                                 unsigned int domain, unsigned int bus)
 {
        struct pci_bus *b;
+       LIST_HEAD(resources);
        struct pcifront_sd *sd = NULL;
        struct pci_bus_entry *bus_entry = NULL;
        int err = 0;
+       static struct resource busn_res = {
+               .start = 0,
+               .end = 255,
+               .flags = IORESOURCE_BUS,
+       };
 
 #ifndef CONFIG_PCI_DOMAINS
        if (domain != 0) {
@@ -463,20 +470,27 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
        dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
                 domain, bus);
 
-       bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
-       sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+       bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
+       sd = kzalloc(sizeof(*sd), GFP_KERNEL);
        if (!bus_entry || !sd) {
                err = -ENOMEM;
                goto err_out;
        }
+       pci_add_resource(&resources, &ioport_resource);
+       pci_add_resource(&resources, &iomem_resource);
+       pci_add_resource(&resources, &busn_res);
        pcifront_init_sd(sd, domain, bus, pdev);
 
-       b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
-                                 &pcifront_bus_ops, sd);
+       pci_lock_rescan_remove();
+
+       b = pci_scan_root_bus(&pdev->xdev->dev, bus,
+                                 &pcifront_bus_ops, sd, &resources);
        if (!b) {
                dev_err(&pdev->xdev->dev,
                        "Error creating PCI Frontend Bus!\n");
                err = -ENOMEM;
+               pci_unlock_rescan_remove();
+               pci_free_resource_list(&resources);
                goto err_out;
        }
 
@@ -484,7 +498,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
 
        list_add(&bus_entry->list, &pdev->root_buses);
 
-       /* pci_scan_bus_parented skips devices which do not have a have
+       /* pci_scan_root_bus skips devices which do not have a
        * devfn==0. The pcifront_scan_bus enumerates all devfn. */
        err = pcifront_scan_bus(pdev, domain, bus, b);
 
@@ -494,6 +508,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
        /* Create SysFS and notify udev of the devices. Aka: "going live" */
        pci_bus_add_devices(b);
 
+       pci_unlock_rescan_remove();
        return err;
 
 err_out:
@@ -556,6 +571,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev)
 
        dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
 
+       pci_lock_rescan_remove();
        list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
                list_del(&bus_entry->list);
 
@@ -568,6 +584,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev)
 
                kfree(bus_entry);
        }
+       pci_unlock_rescan_remove();
 }
 
 static pci_ers_result_t pcifront_common_process(int cmd,
@@ -589,8 +606,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
        pcidev = pci_get_bus_and_slot(bus, devfn);
        if (!pcidev || !pcidev->driver) {
                dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
-               if (pcidev)
-                       pci_dev_put(pcidev);
+               pci_dev_put(pcidev);
                return result;
        }
        pdrv = pcidev->driver;
@@ -655,9 +671,9 @@ static void pcifront_do_aer(struct work_struct *data)
        notify_remote_via_evtchn(pdev->evtchn);
 
        /*in case of we lost an aer request in four lines time_window*/
-       smp_mb__before_clear_bit();
+       smp_mb__before_atomic();
        clear_bit(_PDEVB_op_active, &pdev->flags);
-       smp_mb__after_clear_bit();
+       smp_mb__after_atomic();
 
        schedule_pcifront_aer_op(pdev);
 
@@ -678,10 +694,9 @@ static int pcifront_connect_and_init_dma(struct pcifront_device *pdev)
        if (!pcifront_dev) {
                dev_info(&pdev->xdev->dev, "Installing PCI frontend\n");
                pcifront_dev = pdev;
-       } else {
-               dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
+       } else
                err = -EEXIST;
-       }
+
        spin_unlock(&pcifront_dev_lock);
 
        if (!err && !swiotlb_nr_tbl()) {
@@ -772,12 +787,13 @@ static int pcifront_publish_info(struct pcifront_device *pdev)
 {
        int err = 0;
        struct xenbus_transaction trans;
+       grant_ref_t gref;
 
-       err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info));
+       err = xenbus_grant_ring(pdev->xdev, pdev->sh_info, 1, &gref);
        if (err < 0)
                goto out;
 
-       pdev->gnt_ref = err;
+       pdev->gnt_ref = gref;
 
        err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn);
        if (err)
@@ -848,7 +864,7 @@ static int pcifront_try_connect(struct pcifront_device *pdev)
                goto out;
 
        err = pcifront_connect_and_init_dma(pdev);
-       if (err) {
+       if (err && err != -EEXIST) {
                xenbus_dev_fatal(pdev->xdev, err,
                                 "Error setting up PCI Frontend");
                goto out;
@@ -860,6 +876,11 @@ static int pcifront_try_connect(struct pcifront_device *pdev)
                xenbus_dev_error(pdev->xdev, err,
                                 "No PCI Roots found, trying 0000:00");
                err = pcifront_scan_root(pdev, 0, 0);
+               if (err) {
+                       xenbus_dev_fatal(pdev->xdev, err,
+                                        "Error scanning PCI root 0000:00");
+                       goto out;
+               }
                num_roots = 0;
        } else if (err != 1) {
                if (err == 0)
@@ -941,6 +962,11 @@ static int pcifront_attach_devices(struct pcifront_device *pdev)
                xenbus_dev_error(pdev->xdev, err,
                                 "No PCI Roots found, trying 0000:00");
                err = pcifront_rescan_root(pdev, 0, 0);
+               if (err) {
+                       xenbus_dev_fatal(pdev->xdev, err,
+                                        "Error scanning PCI root 0000:00");
+                       goto out;
+               }
                num_roots = 0;
        } else if (err != 1) {
                if (err == 0)
@@ -1044,8 +1070,10 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
                                domain, bus, slot, func);
                        continue;
                }
+               pci_lock_rescan_remove();
                pci_stop_and_remove_bus_device(pci_dev);
                pci_dev_put(pci_dev);
+               pci_unlock_rescan_remove();
 
                dev_dbg(&pdev->xdev->dev,
                        "PCI device %04x:%02x:%02x.%d removed.\n",
@@ -1128,17 +1156,22 @@ static const struct xenbus_device_id xenpci_ids[] = {
        {""},
 };
 
-static DEFINE_XENBUS_DRIVER(xenpci, "pcifront",
+static struct xenbus_driver xenpci_driver = {
+       .name                   = "pcifront",
+       .ids                    = xenpci_ids,
        .probe                  = pcifront_xenbus_probe,
        .remove                 = pcifront_xenbus_remove,
        .otherend_changed       = pcifront_backend_changed,
-);
+};
 
 static int __init pcifront_init(void)
 {
        if (!xen_pv_domain() || xen_initial_domain())
                return -ENODEV;
 
+       if (!xen_has_pv_devices())
+               return -ENODEV;
+
        pci_frontend_registrar(1 /* enable */);
 
        return xenbus_register_frontend(&xenpci_driver);