Merge tag 'topic/drm-misc-2016-04-29' of git://anongit.freedesktop.org/drm-intel...
authorDave Airlie <airlied@redhat.com>
Wed, 4 May 2016 07:28:09 +0000 (17:28 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 4 May 2016 07:28:09 +0000 (17:28 +1000)
- prep work for struct_mutex-less gem_free_object
- more invasive/tricky mst fixes from Lyude for broken hw. I discussed
  this with Ville/Jani and we all agreed more soaking in -next would be
  real good this late in the -rc cycle. They're cc: stable too to make
  sure they're not getting lost. Feel free to cherry-pick those four if
  you disagree.
- few small things all over

* tag 'topic/drm-misc-2016-04-29' of git://anongit.freedesktop.org/drm-intel:
  drm/atomic: Add missing drm_crtc_internal.h include
  drm/dp: Allow signals to interrupt drm_aux-dev reads/writes
  drm: Quiet down drm_mode_getresources
  drm: Quiet down drm_mode_getconnector
  drm: Protect dev->filelist with its own mutex
  drm: Make drm_vm_open/close_locked private to drm_vm.c
  drm: Hide master MAP cleanup in drm_bufs.c
  drm: Forbid legacy MAP functions for DRIVER_MODESET
  drm: Push struct_mutex into ->master_destroy
  drm: Move drm_getmap into drm_bufs.c and give it a legacy prefix
  drm: Put legacy lastclose work into drm_legacy_dev_reinit
  drm: Give drm_agp_clear drm_legacy_ prefix
  drm/sysfs: Annote lockless show functions with READ_ONCE
  MAINTAINERS: Update the files list for the GMA500 DRM driver
  drm: rcar-du: Fix compilation warning
  drm/i915: Get rid of intel_dp_dpcd_read_wake()
  drm/dp_helper: Perform throw-away read before actual read in drm_dp_dpcd_read()
  drm/dp_helper: Retry aux transactions on all errors
  drm/dp_helper: Always wait before retrying native aux transactions

22 files changed:
MAINTAINERS
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/drm_agpsupport.c
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_dp_aux_dev.c
drivers/gpu/drm/drm_dp_helper.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_info.c
drivers/gpu/drm/drm_internal.h
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/drm_legacy.h
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/intel_dp.c
include/drm/drmP.h
include/drm/drm_agpsupport.h
include/drm/drm_legacy.h

index 9ef7b408beb346afe70c04414a4ec20b59d8e7cc..d1d6498af02fc6692112d0ca53c846f962e17fad 100644 (file)
@@ -3851,8 +3851,7 @@ M:        Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
 L:     dri-devel@lists.freedesktop.org
 T:     git git://github.com/patjak/drm-gma500
 S:     Maintained
-F:     drivers/gpu/drm/gma500
-F:     include/drm/gma500*
+F:     drivers/gpu/drm/gma500/
 
 DRM DRIVERS FOR NVIDIA TEGRA
 M:     Thierry Reding <thierry.reding@gmail.com>
index fa6a27bff298b7ad11649f5a790b131c478702e0..a087b9638cded5119a992e0c545f5f77627ae67e 100644 (file)
@@ -93,7 +93,7 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
        struct drm_device *ddev = adev->ddev;
        struct drm_file *file;
 
-       mutex_lock(&ddev->struct_mutex);
+       mutex_lock(&ddev->filelist_mutex);
 
        list_for_each_entry(file, &ddev->filelist, lhead) {
                struct drm_gem_object *gobj;
@@ -103,13 +103,13 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
                spin_lock(&file->table_lock);
                idr_for_each_entry(&file->object_idr, gobj, handle) {
                        WARN_ONCE(1, "And also active allocations!\n");
-                       drm_gem_object_unreference(gobj);
+                       drm_gem_object_unreference_unlocked(gobj);
                }
                idr_destroy(&file->object_idr);
                spin_unlock(&file->table_lock);
        }
 
-       mutex_unlock(&ddev->struct_mutex);
+       mutex_unlock(&ddev->filelist_mutex);
 }
 
 /*
@@ -769,7 +769,7 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
        struct drm_file *file;
        int r;
 
-       r = mutex_lock_interruptible(&dev->struct_mutex);
+       r = mutex_lock_interruptible(&dev->filelist_mutex);
        if (r)
                return r;
 
@@ -793,7 +793,7 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
                spin_unlock(&file->table_lock);
        }
 
-       mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->filelist_mutex);
        return 0;
 }
 
index a10ea6aec6291f4c233a0b1d49a12fcbace37f17..605bd243fb36d1fc69bf79f9aa46cc46268175ec 100644 (file)
@@ -423,7 +423,7 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev)
 }
 
 /**
- * drm_agp_clear - Clear AGP resource list
+ * drm_legacy_agp_clear - Clear AGP resource list
  * @dev: DRM device
  *
  * Iterate over all AGP resources and remove them. But keep the AGP head
@@ -434,7 +434,7 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev)
  * resources from getting destroyed. Drivers are responsible of cleaning them up
  * during device shutdown.
  */
-void drm_agp_clear(struct drm_device *dev)
+void drm_legacy_agp_clear(struct drm_device *dev)
 {
        struct drm_agp_mem *entry, *tempe;
 
index 8ee1db866e8004c95d9e7bbb038aff5f7daf2f84..2fabd8c4fd88f37367837a6df3a2431373244923 100644 (file)
@@ -31,6 +31,8 @@
 #include <drm/drm_mode.h>
 #include <drm/drm_plane_helper.h>
 
+#include "drm_crtc_internal.h"
+
 /**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
index f1a204d253cce0bfb2616cd4a9b0ebb400e5718c..9b34158c0f77b71a5d27051c281a57fff5895888 100644 (file)
@@ -396,6 +396,10 @@ int drm_legacy_addmap_ioctl(struct drm_device *dev, void *data,
        if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP || map->type == _DRM_SHM))
                return -EPERM;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        err = drm_addmap_core(dev, map->offset, map->size, map->type,
                              map->flags, &maplist);
 
@@ -416,6 +420,62 @@ int drm_legacy_addmap_ioctl(struct drm_device *dev, void *data,
        return 0;
 }
 
+/*
+ * Get a mapping information.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_map structure.
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches for the mapping with the specified offset and copies its information
+ * into userspace
+ */
+int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data,
+                           struct drm_file *file_priv)
+{
+       struct drm_map *map = data;
+       struct drm_map_list *r_list = NULL;
+       struct list_head *list;
+       int idx;
+       int i;
+
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
+       idx = map->offset;
+       if (idx < 0)
+               return -EINVAL;
+
+       i = 0;
+       mutex_lock(&dev->struct_mutex);
+       list_for_each(list, &dev->maplist) {
+               if (i == idx) {
+                       r_list = list_entry(list, struct drm_map_list, head);
+                       break;
+               }
+               i++;
+       }
+       if (!r_list || !r_list->map) {
+               mutex_unlock(&dev->struct_mutex);
+               return -EINVAL;
+       }
+
+       map->offset = r_list->map->offset;
+       map->size = r_list->map->size;
+       map->type = r_list->map->type;
+       map->flags = r_list->map->flags;
+       map->handle = (void *)(unsigned long) r_list->user_token;
+       map->mtrr = arch_phys_wc_index(r_list->map->mtrr);
+
+       mutex_unlock(&dev->struct_mutex);
+
+       return 0;
+}
+
 /**
  * Remove a map private from list and deallocate resources if the mapping
  * isn't in use.
@@ -482,18 +542,35 @@ int drm_legacy_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
 }
 EXPORT_SYMBOL(drm_legacy_rmmap_locked);
 
-int drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map)
+void drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map)
 {
-       int ret;
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return;
 
        mutex_lock(&dev->struct_mutex);
-       ret = drm_legacy_rmmap_locked(dev, map);
+       drm_legacy_rmmap_locked(dev, map);
        mutex_unlock(&dev->struct_mutex);
-
-       return ret;
 }
 EXPORT_SYMBOL(drm_legacy_rmmap);
 
+void drm_legacy_master_rmmaps(struct drm_device *dev, struct drm_master *master)
+{
+       struct drm_map_list *r_list, *list_temp;
+
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               return;
+
+       mutex_lock(&dev->struct_mutex);
+       list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
+               if (r_list->master == master) {
+                       drm_legacy_rmmap_locked(dev, r_list->map);
+                       r_list = NULL;
+               }
+       }
+       mutex_unlock(&dev->struct_mutex);
+}
+
 /* The rmmap ioctl appears to be unnecessary.  All mappings are torn down on
  * the last close of the device, and this is necessary for cleanup when things
  * exit uncleanly.  Therefore, having userland manually remove mappings seems
@@ -517,6 +594,10 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data,
        struct drm_map_list *r_list;
        int ret;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        mutex_lock(&dev->struct_mutex);
        list_for_each_entry(r_list, &dev->maplist, head) {
                if (r_list->map &&
index 4e5b015a5e3aa8b647b55fddd788409ded1fda2b..9626a0cc050a25df3daecf93ad2feb3aba36f57b 100644 (file)
@@ -1936,8 +1936,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                copied = 0;
                crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
                drm_for_each_crtc(crtc, dev) {
-                       DRM_DEBUG_KMS("[CRTC:%d:%s]\n",
-                                     crtc->base.id, crtc->name);
                        if (put_user(crtc->base.id, crtc_id + copied)) {
                                ret = -EFAULT;
                                goto out;
@@ -1952,8 +1950,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                copied = 0;
                encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
                drm_for_each_encoder(encoder, dev) {
-                       DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
-                                       encoder->name);
                        if (put_user(encoder->base.id, encoder_id +
                                     copied)) {
                                ret = -EFAULT;
@@ -1969,9 +1965,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
                copied = 0;
                connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
                drm_for_each_connector(connector, dev) {
-                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-                               connector->base.id,
-                               connector->name);
                        if (put_user(connector->base.id,
                                     connector_id + copied)) {
                                ret = -EFAULT;
@@ -1982,9 +1975,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
        }
        card_res->count_connectors = connector_count;
 
-       DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
-                 card_res->count_connectors, card_res->count_encoders);
-
 out:
        mutex_unlock(&dev->mode_config.mutex);
        return ret;
@@ -2143,8 +2133,6 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 
        memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
 
-       DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
-
        mutex_lock(&dev->mode_config.mutex);
 
        connector = drm_connector_find(dev, out_resp->connector_id);
index f73b38b33a8eb0c22ba0edfabbd07bdc82b3212c..3334baacf43d8d98d15546f9bb7019348cc6a2fb 100644 (file)
@@ -159,6 +159,12 @@ static ssize_t auxdev_read(struct file *file, char __user *buf, size_t count,
                uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
                ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
 
+               if (signal_pending(current)) {
+                       res = num_bytes_processed ?
+                               num_bytes_processed : -ERESTARTSYS;
+                       goto out;
+               }
+
                res = drm_dp_dpcd_read(aux_dev->aux, *offset, localbuf, todo);
                if (res <= 0) {
                        res = num_bytes_processed ? num_bytes_processed : res;
@@ -202,6 +208,12 @@ static ssize_t auxdev_write(struct file *file, const char __user *buf,
                uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
                ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
 
+               if (signal_pending(current)) {
+                       res = num_bytes_processed ?
+                               num_bytes_processed : -ERESTARTSYS;
+                       goto out;
+               }
+
                if (__copy_from_user(localbuf,
                                     buf + num_bytes_processed, todo)) {
                        res = num_bytes_processed ?
index df64ed1c0139e9213912e0f05043489ce6f0d0ba..eeaf5a7c3aa767a6676b9b6054a020b3fea87445 100644 (file)
@@ -178,8 +178,8 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
                              unsigned int offset, void *buffer, size_t size)
 {
        struct drm_dp_aux_msg msg;
-       unsigned int retry;
-       int err = 0;
+       unsigned int retry, native_reply;
+       int err = 0, ret = 0;
 
        memset(&msg, 0, sizeof(msg));
        msg.address = offset;
@@ -196,38 +196,39 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
         * sufficient, bump to 32 which makes Dell 4k monitors happier.
         */
        for (retry = 0; retry < 32; retry++) {
-
-               err = aux->transfer(aux, &msg);
-               if (err < 0) {
-                       if (err == -EBUSY)
-                               continue;
-
-                       goto unlock;
+               if (ret != 0 && ret != -ETIMEDOUT) {
+                       usleep_range(AUX_RETRY_INTERVAL,
+                                    AUX_RETRY_INTERVAL + 100);
                }
 
+               ret = aux->transfer(aux, &msg);
 
-               switch (msg.reply & DP_AUX_NATIVE_REPLY_MASK) {
-               case DP_AUX_NATIVE_REPLY_ACK:
-                       if (err < size)
-                               err = -EPROTO;
-                       goto unlock;
+               if (ret > 0) {
+                       native_reply = msg.reply & DP_AUX_NATIVE_REPLY_MASK;
+                       if (native_reply == DP_AUX_NATIVE_REPLY_ACK) {
+                               if (ret == size)
+                                       goto unlock;
 
-               case DP_AUX_NATIVE_REPLY_NACK:
-                       err = -EIO;
-                       goto unlock;
-
-               case DP_AUX_NATIVE_REPLY_DEFER:
-                       usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
-                       break;
+                               ret = -EPROTO;
+                       } else
+                               ret = -EIO;
                }
+
+               /*
+                * We want the error we return to be the error we received on
+                * the first transaction, since we may get a different error the
+                * next time we retry
+                */
+               if (!err)
+                       err = ret;
        }
 
        DRM_DEBUG_KMS("too many retries, giving up\n");
-       err = -EIO;
+       ret = err;
 
 unlock:
        mutex_unlock(&aux->hw_mutex);
-       return err;
+       return ret;
 }
 
 /**
@@ -247,6 +248,25 @@ unlock:
 ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
                         void *buffer, size_t size)
 {
+       int ret;
+
+       /*
+        * HP ZR24w corrupts the first DPCD access after entering power save
+        * mode. Eg. on a read, the entire buffer will be filled with the same
+        * byte. Do a throw away read to avoid corrupting anything we care
+        * about. Afterwards things will work correctly until the monitor
+        * gets woken up and subsequently re-enters power save mode.
+        *
+        * The user pressing any button on the monitor is enough to wake it
+        * up, so there is no particularly good place to do the workaround.
+        * We just have to do it before any DPCD access and hope that the
+        * monitor doesn't power down exactly after the throw away read.
+        */
+       ret = drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, DP_DPCD_REV, buffer,
+                                1);
+       if (ret != 1)
+               return ret;
+
        return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, offset, buffer,
                                  size);
 }
index f8a7a6e66b7e285b6db9aede95727e94b6544bce..bff89226a344bb292071d26dff56efb98760f951 100644 (file)
@@ -121,19 +121,11 @@ static void drm_master_destroy(struct kref *kref)
 {
        struct drm_master *master = container_of(kref, struct drm_master, refcount);
        struct drm_device *dev = master->minor->dev;
-       struct drm_map_list *r_list, *list_temp;
 
-       mutex_lock(&dev->struct_mutex);
        if (dev->driver->master_destroy)
                dev->driver->master_destroy(dev, master);
 
-       list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
-               if (r_list->master == master) {
-                       drm_legacy_rmmap_locked(dev, r_list->map);
-                       r_list = NULL;
-               }
-       }
-       mutex_unlock(&dev->struct_mutex);
+       drm_legacy_master_rmmaps(dev, master);
 
        idr_destroy(&master->magic_map);
        kfree(master->unique);
@@ -598,6 +590,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
        spin_lock_init(&dev->buf_lock);
        spin_lock_init(&dev->event_lock);
        mutex_init(&dev->struct_mutex);
+       mutex_init(&dev->filelist_mutex);
        mutex_init(&dev->ctxlist_mutex);
        mutex_init(&dev->master_mutex);
 
index aeef58ed359b7ab2fc8ac146bcc22dea271f6b93..7af7f8bcb3558244781c0ac4f486452e852deca9 100644 (file)
@@ -297,9 +297,9 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
        }
        mutex_unlock(&dev->master_mutex);
 
-       mutex_lock(&dev->struct_mutex);
+       mutex_lock(&dev->filelist_mutex);
        list_add(&priv->lhead, &dev->filelist);
-       mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->filelist_mutex);
 
 #ifdef __alpha__
        /*
@@ -381,14 +381,26 @@ static void drm_events_release(struct drm_file *file_priv)
  */
 static void drm_legacy_dev_reinit(struct drm_device *dev)
 {
-       if (drm_core_check_feature(dev, DRIVER_MODESET))
-               return;
+       if (dev->irq_enabled)
+               drm_irq_uninstall(dev);
+
+       mutex_lock(&dev->struct_mutex);
+
+       drm_legacy_agp_clear(dev);
+
+       drm_legacy_sg_cleanup(dev);
+       drm_legacy_vma_flush(dev);
+       drm_legacy_dma_takedown(dev);
+
+       mutex_unlock(&dev->struct_mutex);
 
        dev->sigdata.lock = NULL;
 
        dev->context_flag = 0;
        dev->last_context = 0;
        dev->if_version = 0;
+
+       DRM_DEBUG("lastclose completed\n");
 }
 
 /*
@@ -400,7 +412,7 @@ static void drm_legacy_dev_reinit(struct drm_device *dev)
  *
  * \sa drm_device
  */
-int drm_lastclose(struct drm_device * dev)
+void drm_lastclose(struct drm_device * dev)
 {
        DRM_DEBUG("\n");
 
@@ -408,23 +420,8 @@ int drm_lastclose(struct drm_device * dev)
                dev->driver->lastclose(dev);
        DRM_DEBUG("driver lastclose completed\n");
 
-       if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
-               drm_irq_uninstall(dev);
-
-       mutex_lock(&dev->struct_mutex);
-
-       drm_agp_clear(dev);
-
-       drm_legacy_sg_cleanup(dev);
-       drm_legacy_vma_flush(dev);
-       drm_legacy_dma_takedown(dev);
-
-       mutex_unlock(&dev->struct_mutex);
-
-       drm_legacy_dev_reinit(dev);
-
-       DRM_DEBUG("lastclose completed\n");
-       return 0;
+       if (!drm_core_check_feature(dev, DRIVER_MODESET))
+               drm_legacy_dev_reinit(dev);
 }
 
 /**
@@ -445,14 +442,16 @@ int drm_release(struct inode *inode, struct file *filp)
        struct drm_file *file_priv = filp->private_data;
        struct drm_minor *minor = file_priv->minor;
        struct drm_device *dev = minor->dev;
-       int retcode = 0;
 
        mutex_lock(&drm_global_mutex);
 
        DRM_DEBUG("open_count = %d\n", dev->open_count);
 
-       mutex_lock(&dev->struct_mutex);
+       mutex_lock(&dev->filelist_mutex);
        list_del(&file_priv->lhead);
+       mutex_unlock(&dev->filelist_mutex);
+
+       mutex_lock(&dev->struct_mutex);
        if (file_priv->magic)
                idr_remove(&file_priv->master->magic_map, file_priv->magic);
        mutex_unlock(&dev->struct_mutex);
@@ -538,7 +537,7 @@ int drm_release(struct inode *inode, struct file *filp)
         */
 
        if (!--dev->open_count) {
-               retcode = drm_lastclose(dev);
+               drm_lastclose(dev);
                if (drm_device_is_unplugged(dev))
                        drm_put_dev(dev);
        }
@@ -546,7 +545,7 @@ int drm_release(struct inode *inode, struct file *filp)
 
        drm_minor_release(minor);
 
-       return retcode;
+       return 0;
 }
 EXPORT_SYMBOL(drm_release);
 
index cbb4fc0fc969ee2236e112cbb5974742ceffc191..5d469b2f26f46c611c3a2dca3c6359a813d3aab2 100644 (file)
@@ -174,7 +174,7 @@ int drm_clients_info(struct seq_file *m, void *data)
        /* dev->filelist is sorted youngest first, but we want to present
         * oldest first (i.e. kernel, servers, clients), so walk backwardss.
         */
-       mutex_lock(&dev->struct_mutex);
+       mutex_lock(&dev->filelist_mutex);
        list_for_each_entry_reverse(priv, &dev->filelist, lhead) {
                struct task_struct *task;
 
@@ -190,7 +190,7 @@ int drm_clients_info(struct seq_file *m, void *data)
                           priv->magic);
                rcu_read_unlock();
        }
-       mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->filelist_mutex);
        return 0;
 }
 
index 43cbda3306ac060674b2ec6dfd233ace6a93be33..902cf6a152128231f60bb15aab51028262d17f8f 100644 (file)
@@ -26,7 +26,7 @@ extern unsigned int drm_timestamp_monotonic;
 
 /* drm_fops.c */
 extern struct mutex drm_global_mutex;
-int drm_lastclose(struct drm_device *dev);
+void drm_lastclose(struct drm_device *dev);
 
 /* drm_pci.c */
 int drm_pci_set_unique(struct drm_device *dev,
@@ -37,8 +37,6 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
 
 /* drm_vm.c */
 int drm_vma_info(struct seq_file *m, void *data);
-void drm_vm_open_locked(struct drm_device *dev, struct vm_area_struct *vma);
-void drm_vm_close_locked(struct drm_device *dev, struct vm_area_struct *vma);
 
 /* drm_prime.c */
 int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
index 8ce2a0c591165018c49392e7ad2b828a1fb3b94b..b7a39771c152e0b48ff4fd8cce4a6e9ab7fcbe95 100644 (file)
@@ -149,58 +149,6 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
        return 0;
 }
 
-/*
- * Get a mapping information.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_map structure.
- *
- * \return zero on success or a negative number on failure.
- *
- * Searches for the mapping with the specified offset and copies its information
- * into userspace
- */
-static int drm_getmap(struct drm_device *dev, void *data,
-              struct drm_file *file_priv)
-{
-       struct drm_map *map = data;
-       struct drm_map_list *r_list = NULL;
-       struct list_head *list;
-       int idx;
-       int i;
-
-       idx = map->offset;
-       if (idx < 0)
-               return -EINVAL;
-
-       i = 0;
-       mutex_lock(&dev->struct_mutex);
-       list_for_each(list, &dev->maplist) {
-               if (i == idx) {
-                       r_list = list_entry(list, struct drm_map_list, head);
-                       break;
-               }
-               i++;
-       }
-       if (!r_list || !r_list->map) {
-               mutex_unlock(&dev->struct_mutex);
-               return -EINVAL;
-       }
-
-       map->offset = r_list->map->offset;
-       map->size = r_list->map->size;
-       map->type = r_list->map->type;
-       map->flags = r_list->map->flags;
-       map->handle = (void *)(unsigned long) r_list->user_token;
-       map->mtrr = arch_phys_wc_index(r_list->map->mtrr);
-
-       mutex_unlock(&dev->struct_mutex);
-
-       return 0;
-}
-
 /*
  * Get client information.
  *
@@ -558,7 +506,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
        DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
        DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
        DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, DRM_UNLOCKED),
        DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
        DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
        DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
index 9b731786e4db2d90b95ff6020e253b0c6f883ee7..d3b6ee357a2b432aee09fb5b3780c6df84c7a577 100644 (file)
@@ -63,6 +63,8 @@ int drm_legacy_getsareactx(struct drm_device *d, void *v, struct drm_file *f);
 
 #define DRM_MAP_HASH_OFFSET 0x10000000
 
+int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data,
+                           struct drm_file *file_priv);
 int drm_legacy_addmap_ioctl(struct drm_device *d, void *v, struct drm_file *f);
 int drm_legacy_rmmap_ioctl(struct drm_device *d, void *v, struct drm_file *f);
 int drm_legacy_addbufs(struct drm_device *d, void *v, struct drm_file *f);
index a1fff1179a97ae5ec55e5f7489e367619de322f8..29d5a548d07a70c1fad5b5e13dc7413dd509c1b0 100644 (file)
@@ -250,7 +250,7 @@ void drm_pci_agp_destroy(struct drm_device *dev)
 {
        if (dev->agp) {
                arch_phys_wc_del(dev->agp->agp_mtrr);
-               drm_agp_clear(dev);
+               drm_legacy_agp_clear(dev);
                kfree(dev->agp);
                dev->agp = NULL;
        }
index d7d8cecfb0e69bcbfc15dca84bd9a0ea3b8464d6..fa7fadce8063fec0933ab14b6c64b43ac28adcd2 100644 (file)
@@ -208,9 +208,12 @@ static ssize_t status_show(struct device *device,
                           char *buf)
 {
        struct drm_connector *connector = to_drm_connector(device);
+       enum drm_connector_status status;
+
+       status = READ_ONCE(connector->status);
 
        return snprintf(buf, PAGE_SIZE, "%s\n",
-                       drm_get_connector_status_name(connector->status));
+                       drm_get_connector_status_name(status));
 }
 
 static ssize_t dpms_show(struct device *device,
@@ -231,9 +234,11 @@ static ssize_t enabled_show(struct device *device,
                           char *buf)
 {
        struct drm_connector *connector = to_drm_connector(device);
+       bool enabled;
+
+       enabled = READ_ONCE(connector->encoder);
 
-       return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" :
-                       "disabled");
+       return snprintf(buf, PAGE_SIZE, enabled ? "enabled\n" : "disabled\n");
 }
 
 static ssize_t edid_show(struct file *filp, struct kobject *kobj,
index f90bd5fe35babbc6b6eb216cefd0f0dad054932d..ac9f4b3ec615c5fb73cd00c4947d985ab4fa18b4 100644 (file)
@@ -395,16 +395,8 @@ static const struct vm_operations_struct drm_vm_sg_ops = {
        .close = drm_vm_close,
 };
 
-/**
- * \c open method for shared virtual memory.
- *
- * \param vma virtual memory area.
- *
- * Create a new drm_vma_entry structure as the \p vma private data entry and
- * add it to drm_device::vmalist.
- */
-void drm_vm_open_locked(struct drm_device *dev,
-               struct vm_area_struct *vma)
+static void drm_vm_open_locked(struct drm_device *dev,
+                              struct vm_area_struct *vma)
 {
        struct drm_vma_entry *vma_entry;
 
@@ -429,8 +421,8 @@ static void drm_vm_open(struct vm_area_struct *vma)
        mutex_unlock(&dev->struct_mutex);
 }
 
-void drm_vm_close_locked(struct drm_device *dev,
-               struct vm_area_struct *vma)
+static void drm_vm_close_locked(struct drm_device *dev,
+                               struct vm_area_struct *vma)
 {
        struct drm_vma_entry *pt, *temp;
 
index 4950d05d2948c82923c44a71feaa06a6b471ceac..8b8d6f07d7aad8e7971dd1deeaa628fb0659dde9 100644 (file)
@@ -528,6 +528,10 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
 
        seq_putc(m, '\n');
        print_batch_pool_stats(m, dev_priv);
+
+       mutex_unlock(&dev->struct_mutex);
+
+       mutex_lock(&dev->filelist_mutex);
        list_for_each_entry_reverse(file, &dev->filelist, lhead) {
                struct file_stats stats;
                struct task_struct *task;
@@ -548,8 +552,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
                print_file_stats(m, task ? task->comm : "<unknown>", stats);
                rcu_read_unlock();
        }
-
-       mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->filelist_mutex);
 
        return 0;
 }
@@ -2354,6 +2357,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
        else if (INTEL_INFO(dev)->gen >= 6)
                gen6_ppgtt_info(m, dev);
 
+       mutex_lock(&dev->filelist_mutex);
        list_for_each_entry_reverse(file, &dev->filelist, lhead) {
                struct drm_i915_file_private *file_priv = file->driver_priv;
                struct task_struct *task;
@@ -2368,6 +2372,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
                idr_for_each(&file_priv->context_idr, per_file_ctx,
                             (void *)(unsigned long)m);
        }
+       mutex_unlock(&dev->filelist_mutex);
 
 out_put:
        intel_runtime_pm_put(dev_priv);
@@ -2403,6 +2408,8 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
                   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit),
                   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit),
                   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+
+       mutex_lock(&dev->filelist_mutex);
        spin_lock(&dev_priv->rps.client_lock);
        list_for_each_entry_reverse(file, &dev->filelist, lhead) {
                struct drm_i915_file_private *file_priv = file->driver_priv;
@@ -2425,6 +2432,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
                   list_empty(&dev_priv->rps.mmioflips.link) ? "" : ", active");
        seq_printf(m, "Kernel boosts: %d\n", dev_priv->rps.boosts);
        spin_unlock(&dev_priv->rps.client_lock);
+       mutex_unlock(&dev->filelist_mutex);
 
        return 0;
 }
index a3fc49430c264f8b844c80fb76d4cbc30266d7b0..f192f58708c25dbedf74994b4a377098093f0dc3 100644 (file)
@@ -3073,37 +3073,6 @@ static void chv_dp_post_pll_disable(struct intel_encoder *encoder)
        chv_phy_powergate_lanes(encoder, false, 0x0);
 }
 
-/*
- * Native read with retry for link status and receiver capability reads for
- * cases where the sink may still be asleep.
- *
- * Sinks are *supposed* to come up within 1ms from an off state, but we're also
- * supposed to retry 3 times per the spec.
- */
-static ssize_t
-intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset,
-                       void *buffer, size_t size)
-{
-       ssize_t ret;
-       int i;
-
-       /*
-        * Sometime we just get the same incorrect byte repeated
-        * over the entire buffer. Doing just one throw away read
-        * initially seems to "solve" it.
-        */
-       drm_dp_dpcd_read(aux, DP_DPCD_REV, buffer, 1);
-
-       for (i = 0; i < 3; i++) {
-               ret = drm_dp_dpcd_read(aux, offset, buffer, size);
-               if (ret == size)
-                       return ret;
-               msleep(1);
-       }
-
-       return ret;
-}
-
 /*
  * Fetch AUX CH registers 0x202 - 0x207 which contain
  * link status information
@@ -3111,10 +3080,8 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset,
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
-       return intel_dp_dpcd_read_wake(&intel_dp->aux,
-                                      DP_LANE0_1_STATUS,
-                                      link_status,
-                                      DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
+       return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status,
+                               DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
 }
 
 /* These are source-specific values. */
@@ -3749,8 +3716,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint8_t rev;
 
-       if (intel_dp_dpcd_read_wake(&intel_dp->aux, 0x000, intel_dp->dpcd,
-                                   sizeof(intel_dp->dpcd)) < 0)
+       if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
+                            sizeof(intel_dp->dpcd)) < 0)
                return false; /* aux transfer failed */
 
        DRM_DEBUG_KMS("DPCD: %*ph\n", (int) sizeof(intel_dp->dpcd), intel_dp->dpcd);
@@ -3758,8 +3725,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        if (intel_dp->dpcd[DP_DPCD_REV] == 0)
                return false; /* DPCD not present */
 
-       if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT,
-                                   &intel_dp->sink_count, 1) < 0)
+       if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT,
+                            &intel_dp->sink_count, 1) < 0)
                return false;
 
        /*
@@ -3782,9 +3749,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        /* Check if the panel supports PSR */
        memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd));
        if (is_edp(intel_dp)) {
-               intel_dp_dpcd_read_wake(&intel_dp->aux, DP_PSR_SUPPORT,
-                                       intel_dp->psr_dpcd,
-                                       sizeof(intel_dp->psr_dpcd));
+               drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT,
+                                intel_dp->psr_dpcd,
+                                sizeof(intel_dp->psr_dpcd));
                if (intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED) {
                        dev_priv->psr.sink_support = true;
                        DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
@@ -3795,9 +3762,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
                        uint8_t frame_sync_cap;
 
                        dev_priv->psr.sink_support = true;
-                       intel_dp_dpcd_read_wake(&intel_dp->aux,
-                                       DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP,
-                                       &frame_sync_cap, 1);
+                       drm_dp_dpcd_read(&intel_dp->aux,
+                                        DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP,
+                                        &frame_sync_cap, 1);
                        dev_priv->psr.aux_frame_sync = frame_sync_cap ? true : false;
                        /* PSR2 needs frame sync as well */
                        dev_priv->psr.psr2_support = dev_priv->psr.aux_frame_sync;
@@ -3813,15 +3780,13 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        /* Intermediate frequency support */
        if (is_edp(intel_dp) &&
            (intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_DPCD_DISPLAY_CONTROL_CAPABLE) &&
-           (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_EDP_DPCD_REV, &rev, 1) == 1) &&
+           (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, &rev, 1) == 1) &&
            (rev >= 0x03)) { /* eDp v1.4 or higher */
                __le16 sink_rates[DP_MAX_SUPPORTED_RATES];
                int i;
 
-               intel_dp_dpcd_read_wake(&intel_dp->aux,
-                               DP_SUPPORTED_LINK_RATES,
-                               sink_rates,
-                               sizeof(sink_rates));
+               drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
+                               sink_rates, sizeof(sink_rates));
 
                for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
                        int val = le16_to_cpu(sink_rates[i]);
@@ -3844,9 +3809,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
                return true; /* no per-port downstream info */
 
-       if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_DOWNSTREAM_PORT_0,
-                                   intel_dp->downstream_ports,
-                                   DP_MAX_DOWNSTREAM_PORTS) < 0)
+       if (drm_dp_dpcd_read(&intel_dp->aux, DP_DOWNSTREAM_PORT_0,
+                            intel_dp->downstream_ports,
+                            DP_MAX_DOWNSTREAM_PORTS) < 0)
                return false; /* downstream port status fetch failed */
 
        return true;
@@ -3860,11 +3825,11 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
        if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
                return;
 
-       if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_OUI, buf, 3) == 3)
+       if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_OUI, buf, 3) == 3)
                DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
                              buf[0], buf[1], buf[2]);
 
-       if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_BRANCH_OUI, buf, 3) == 3)
+       if (drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_OUI, buf, 3) == 3)
                DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
                              buf[0], buf[1], buf[2]);
 }
@@ -3883,7 +3848,7 @@ intel_dp_probe_mst(struct intel_dp *intel_dp)
        if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
                return false;
 
-       if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_MSTM_CAP, buf, 1)) {
+       if (drm_dp_dpcd_read(&intel_dp->aux, DP_MSTM_CAP, buf, 1)) {
                if (buf[0] & DP_MST_CAP) {
                        DRM_DEBUG_KMS("Sink is MST capable\n");
                        intel_dp->is_mst = true;
@@ -4020,7 +3985,7 @@ stop:
 static bool
 intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
 {
-       return intel_dp_dpcd_read_wake(&intel_dp->aux,
+       return drm_dp_dpcd_read(&intel_dp->aux,
                                       DP_DEVICE_SERVICE_IRQ_VECTOR,
                                       sink_irq_vector, 1) == 1;
 }
@@ -4030,7 +3995,7 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
 {
        int ret;
 
-       ret = intel_dp_dpcd_read_wake(&intel_dp->aux,
+       ret = drm_dp_dpcd_read(&intel_dp->aux,
                                             DP_SINK_COUNT_ESI,
                                             sink_irq_vector, 14);
        if (ret != 14)
index 5de4cff05ac947506af97b692e78d169078b5027..7901768bb47c24c957973363bbd444c3ea77b236 100644 (file)
@@ -769,6 +769,7 @@ struct drm_device {
        atomic_t buf_alloc;             /**< Buffer allocation in progress */
        /*@} */
 
+       struct mutex filelist_mutex;
        struct list_head filelist;
 
        /** \name Memory management */
index 193ef19dfc5c54f061bff939150bf384be734ca6..b2d912670a7fb07c27685008bc62b7bf5310a8b5 100644 (file)
@@ -37,7 +37,7 @@ struct agp_memory *drm_agp_bind_pages(struct drm_device *dev,
                                uint32_t type);
 
 struct drm_agp_head *drm_agp_init(struct drm_device *dev);
-void drm_agp_clear(struct drm_device *dev);
+void drm_legacy_agp_clear(struct drm_device *dev);
 int drm_agp_acquire(struct drm_device *dev);
 int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
                          struct drm_file *file_priv);
@@ -93,7 +93,7 @@ static inline struct drm_agp_head *drm_agp_init(struct drm_device *dev)
        return NULL;
 }
 
-static inline void drm_agp_clear(struct drm_device *dev)
+static inline void drm_legacy_agp_clear(struct drm_device *dev)
 {
 }
 
index 3e698038dc7bf4d24b051c87a8283b9544131a9b..a5ef2c7e40f8e281e2419ff071b4d391846127f8 100644 (file)
@@ -154,8 +154,10 @@ struct drm_map_list {
 int drm_legacy_addmap(struct drm_device *d, resource_size_t offset,
                      unsigned int size, enum drm_map_type type,
                      enum drm_map_flags flags, struct drm_local_map **map_p);
-int drm_legacy_rmmap(struct drm_device *d, struct drm_local_map *map);
+void drm_legacy_rmmap(struct drm_device *d, struct drm_local_map *map);
 int drm_legacy_rmmap_locked(struct drm_device *d, struct drm_local_map *map);
+void drm_legacy_master_rmmaps(struct drm_device *dev,
+                             struct drm_master *master);
 struct drm_local_map *drm_legacy_getsarea(struct drm_device *dev);
 int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma);