Merge tag 'mfd-for-linus-3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / drm_pci.c
index 9c696a5ad74de262244be248549f99173f4c3806..fd29f03645b8e465b42add64384b339c13229dc2 100644 (file)
@@ -1,17 +1,3 @@
-/* drm_pci.h -- PCI DMA memory management wrappers for DRM -*- linux-c -*- */
-/**
- * \file drm_pci.c
- * \brief Functions and ioctls to manage PCI memory
- *
- * \warning These interfaces aren't stable yet.
- *
- * \todo Implement the remaining ioctl's for the PCI pools.
- * \todo The wrappers here are so thin that they would be better off inlined..
- *
- * \author José Fonseca <jrfonseca@tungstengraphics.com>
- * \author Leif Delgass <ldelgass@retinalburn.net>
- */
-
 /*
  * Copyright 2003 José Fonseca.
  * Copyright 2003 Leif Delgass.
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <drm/drmP.h>
-
-/**********************************************************************/
-/** \name PCI memory */
-/*@{*/
+#include "drm_legacy.h"
 
 /**
- * \brief Allocate a PCI consistent memory block, for DMA.
+ * drm_pci_alloc - Allocate a PCI consistent memory block, for DMA.
+ * @dev: DRM device
+ * @size: size of block to allocate
+ * @align: alignment of block
+ *
+ * Return: A handle to the allocated memory block on success or NULL on
+ * failure.
  */
 drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align)
 {
@@ -88,12 +77,12 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali
 
 EXPORT_SYMBOL(drm_pci_alloc);
 
-/**
- * \brief Free a PCI consistent memory block without freeing its descriptor.
+/*
+ * Free a PCI consistent memory block without freeing its descriptor.
  *
  * This function is for internal use in the Linux-specific DRM core code.
  */
-void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
+void __drm_legacy_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
 {
        unsigned long addr;
        size_t sz;
@@ -111,11 +100,13 @@ void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
 }
 
 /**
- * \brief Free a PCI consistent memory block
+ * drm_pci_free - Free a PCI consistent memory block
+ * @dev: DRM device
+ * @dmah: handle to memory block
  */
 void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
 {
-       __drm_pci_free(dev, dmah);
+       __drm_legacy_pci_free(dev, dmah);
        kfree(dmah);
 }
 
@@ -137,69 +128,29 @@ static int drm_get_pci_domain(struct drm_device *dev)
        return pci_domain_nr(dev->pdev->bus);
 }
 
-static int drm_pci_get_irq(struct drm_device *dev)
-{
-       return dev->pdev->irq;
-}
-
-static const char *drm_pci_get_name(struct drm_device *dev)
-{
-       struct pci_driver *pdriver = dev->driver->kdriver.pci;
-       return pdriver->name;
-}
-
-static int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
+int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
 {
-       int len, ret;
-       struct pci_driver *pdriver = dev->driver->kdriver.pci;
-       master->unique_len = 40;
-       master->unique_size = master->unique_len;
-       master->unique = kmalloc(master->unique_size, GFP_KERNEL);
-       if (master->unique == NULL)
+       master->unique = kasprintf(GFP_KERNEL, "pci:%04x:%02x:%02x.%d",
+                                       drm_get_pci_domain(dev),
+                                       dev->pdev->bus->number,
+                                       PCI_SLOT(dev->pdev->devfn),
+                                       PCI_FUNC(dev->pdev->devfn));
+       if (!master->unique)
                return -ENOMEM;
 
-
-       len = snprintf(master->unique, master->unique_len,
-                      "pci:%04x:%02x:%02x.%d",
-                      drm_get_pci_domain(dev),
-                      dev->pdev->bus->number,
-                      PCI_SLOT(dev->pdev->devfn),
-                      PCI_FUNC(dev->pdev->devfn));
-
-       if (len >= master->unique_len) {
-               DRM_ERROR("buffer overflow");
-               ret = -EINVAL;
-               goto err;
-       } else
-               master->unique_len = len;
-
-       dev->devname =
-               kmalloc(strlen(pdriver->name) +
-                       master->unique_len + 2, GFP_KERNEL);
-
-       if (dev->devname == NULL) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       sprintf(dev->devname, "%s@%s", pdriver->name,
-               master->unique);
-
+       master->unique_len = strlen(master->unique);
        return 0;
-err:
-       return ret;
 }
+EXPORT_SYMBOL(drm_pci_set_busid);
 
-static int drm_pci_set_unique(struct drm_device *dev,
-                             struct drm_master *master,
-                             struct drm_unique *u)
+int drm_pci_set_unique(struct drm_device *dev,
+                      struct drm_master *master,
+                      struct drm_unique *u)
 {
        int domain, bus, slot, func, ret;
-       const char *bus_name;
 
        master->unique_len = u->unique_len;
-       master->unique_size = u->unique_len + 1;
-       master->unique = kmalloc(master->unique_size, GFP_KERNEL);
+       master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
        if (!master->unique) {
                ret = -ENOMEM;
                goto err;
@@ -212,17 +163,6 @@ static int drm_pci_set_unique(struct drm_device *dev,
 
        master->unique[master->unique_len] = '\0';
 
-       bus_name = dev->driver->bus->get_name(dev);
-       dev->devname = kmalloc(strlen(bus_name) +
-                              strlen(master->unique) + 2, GFP_KERNEL);
-       if (!dev->devname) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       sprintf(dev->devname, "%s@%s", bus_name,
-               master->unique);
-
        /* Return error if the busid submitted doesn't match the device's actual
         * busid.
         */
@@ -247,7 +187,6 @@ err:
        return ret;
 }
 
-
 static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
 {
        if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
@@ -262,6 +201,36 @@ static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
        return 0;
 }
 
+/**
+ * drm_irq_by_busid - Get interrupt from bus ID
+ * @dev: DRM device
+ * @data: IOCTL parameter pointing to a drm_irq_busid structure
+ * @file_priv: DRM file private.
+ *
+ * Finds the PCI device with the specified bus id and gets its IRQ number.
+ * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
+ * to that of the device that this DRM instance attached to.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int drm_irq_by_busid(struct drm_device *dev, void *data,
+                    struct drm_file *file_priv)
+{
+       struct drm_irq_busid *p = data;
+
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
+       /* UMS was only ever support on PCI devices. */
+       if (WARN_ON(!dev->pdev))
+               return -EINVAL;
+
+       if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+               return -EINVAL;
+
+       return drm_pci_irq_by_busid(dev, p);
+}
+
 static void drm_pci_agp_init(struct drm_device *dev)
 {
        if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
@@ -286,25 +255,17 @@ void drm_pci_agp_destroy(struct drm_device *dev)
        }
 }
 
-static struct drm_bus drm_pci_bus = {
-       .bus_type = DRIVER_BUS_PCI,
-       .get_irq = drm_pci_get_irq,
-       .get_name = drm_pci_get_name,
-       .set_busid = drm_pci_set_busid,
-       .set_unique = drm_pci_set_unique,
-       .irq_by_busid = drm_pci_irq_by_busid,
-};
-
 /**
- * Register.
- *
- * \param pdev - PCI device structure
- * \param ent entry from the PCI ID table with device type flags
- * \return zero on success or a negative number on failure.
+ * drm_get_pci_dev - Register a PCI device with the DRM subsystem
+ * @pdev: PCI device
+ * @ent: entry from the PCI ID table that matches @pdev
+ * @driver: DRM device driver
  *
  * Attempt to gets inter module "drm" information. If we are first
  * then register the character device and inter module information.
  * Try and register, if we fail to register, backout previous work.
+ *
+ * Return: 0 on success or a negative error code on failure.
  */
 int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                    struct drm_driver *driver)
@@ -357,15 +318,14 @@ err_free:
 EXPORT_SYMBOL(drm_get_pci_dev);
 
 /**
- * PCI device initialization. Called direct from modules at load time.
- *
- * \return zero on success or a negative number on failure.
+ * drm_pci_init - Register matching PCI devices with the DRM subsystem
+ * @driver: DRM device driver
+ * @pdriver: PCI device driver
  *
- * Initializes a drm_device structures,registering the
- * stubs and initializing the AGP device.
+ * Initializes a drm_device structures, registering the stubs and initializing
+ * the AGP device.
  *
- * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
- * after the initialization for driver customization.
+ * Return: 0 on success or a negative error code on failure.
  */
 int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
 {
@@ -375,9 +335,6 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
 
        DRM_DEBUG("\n");
 
-       driver->kdriver.pci = pdriver;
-       driver->bus = &drm_pci_bus;
-
        if (driver->driver_features & DRIVER_MODESET)
                return pci_register_driver(pdriver);
 
@@ -453,11 +410,31 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
 }
 
 void drm_pci_agp_destroy(struct drm_device *dev) {}
+
+int drm_irq_by_busid(struct drm_device *dev, void *data,
+                    struct drm_file *file_priv)
+{
+       return -EINVAL;
+}
+
+int drm_pci_set_unique(struct drm_device *dev,
+                      struct drm_master *master,
+                      struct drm_unique *u)
+{
+       return -EINVAL;
+}
 #endif
 
 EXPORT_SYMBOL(drm_pci_init);
 
-/*@}*/
+/**
+ * drm_pci_exit - Unregister matching PCI devices from the DRM subsystem
+ * @driver: DRM device driver
+ * @pdriver: PCI device driver
+ *
+ * Unregisters one or more devices matched by a PCI driver from the DRM
+ * subsystem.
+ */
 void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
 {
        struct drm_device *dev, *tmp;