LCOV - code coverage report
Current view: top level - dev/pci/drm - drm_crtc.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 2147 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 147 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2006-2008 Intel Corporation
       3             :  * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
       4             :  * Copyright (c) 2008 Red Hat Inc.
       5             :  *
       6             :  * DRM core CRTC related functions
       7             :  *
       8             :  * Permission to use, copy, modify, distribute, and sell this software and its
       9             :  * documentation for any purpose is hereby granted without fee, provided that
      10             :  * the above copyright notice appear in all copies and that both that copyright
      11             :  * notice and this permission notice appear in supporting documentation, and
      12             :  * that the name of the copyright holders not be used in advertising or
      13             :  * publicity pertaining to distribution of the software without specific,
      14             :  * written prior permission.  The copyright holders make no representations
      15             :  * about the suitability of this software for any purpose.  It is provided "as
      16             :  * is" without express or implied warranty.
      17             :  *
      18             :  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
      19             :  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
      20             :  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
      21             :  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
      22             :  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
      23             :  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      24             :  * OF THIS SOFTWARE.
      25             :  *
      26             :  * Authors:
      27             :  *      Keith Packard
      28             :  *      Eric Anholt <eric@anholt.net>
      29             :  *      Dave Airlie <airlied@linux.ie>
      30             :  *      Jesse Barnes <jesse.barnes@intel.com>
      31             :  */
      32             : #ifdef __linux__
      33             : #include <linux/ctype.h>
      34             : #include <linux/list.h>
      35             : #include <linux/slab.h>
      36             : #include <linux/export.h>
      37             : #endif
      38             : #include <dev/pci/drm/drmP.h>
      39             : #include <dev/pci/drm/drm_crtc.h>
      40             : #include <dev/pci/drm/drm_edid.h>
      41             : #include <dev/pci/drm/drm_fourcc.h>
      42             : #include <dev/pci/drm/drm_modeset_lock.h>
      43             : #include <dev/pci/drm/drm_atomic.h>
      44             : 
      45             : #include "drm_crtc_internal.h"
      46             : #include "drm_internal.h"
      47             : 
      48             : static struct drm_framebuffer *
      49             : internal_framebuffer_create(struct drm_device *dev,
      50             :                             struct drm_mode_fb_cmd2 *r,
      51             :                             struct drm_file *file_priv);
      52             : 
      53             : /* Avoid boilerplate.  I'm tired of typing. */
      54             : #define DRM_ENUM_NAME_FN(fnname, list)                          \
      55             :         const char *fnname(int val)                             \
      56             :         {                                                       \
      57             :                 int i;                                          \
      58             :                 for (i = 0; i < ARRAY_SIZE(list); i++) {     \
      59             :                         if (list[i].type == val)                \
      60             :                                 return list[i].name;            \
      61             :                 }                                               \
      62             :                 return "(unknown)";                           \
      63             :         }
      64             : 
      65             : /*
      66             :  * Global properties
      67             :  */
      68             : static const struct drm_prop_enum_list drm_dpms_enum_list[] = {
      69             :         { DRM_MODE_DPMS_ON, "On" },
      70             :         { DRM_MODE_DPMS_STANDBY, "Standby" },
      71             :         { DRM_MODE_DPMS_SUSPEND, "Suspend" },
      72             :         { DRM_MODE_DPMS_OFF, "Off" }
      73             : };
      74             : 
      75           0 : DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
      76             : 
      77             : static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
      78             :         { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
      79             :         { DRM_PLANE_TYPE_PRIMARY, "Primary" },
      80             :         { DRM_PLANE_TYPE_CURSOR, "Cursor" },
      81             : };
      82             : 
      83             : /*
      84             :  * Optional properties
      85             :  */
      86             : static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = {
      87             :         { DRM_MODE_SCALE_NONE, "None" },
      88             :         { DRM_MODE_SCALE_FULLSCREEN, "Full" },
      89             :         { DRM_MODE_SCALE_CENTER, "Center" },
      90             :         { DRM_MODE_SCALE_ASPECT, "Full aspect" },
      91             : };
      92             : 
      93             : static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
      94             :         { DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" },
      95             :         { DRM_MODE_PICTURE_ASPECT_4_3, "4:3" },
      96             :         { DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
      97             : };
      98             : 
      99             : /*
     100             :  * Non-global properties, but "required" for certain connectors.
     101             :  */
     102             : static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
     103             :         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
     104             :         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
     105             :         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
     106             : };
     107             : 
     108           0 : DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
     109             : 
     110             : static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {
     111             :         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
     112             :         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
     113             :         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
     114             : };
     115             : 
     116           0 : DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
     117             :                  drm_dvi_i_subconnector_enum_list)
     118             : 
     119             : static const struct drm_prop_enum_list drm_tv_select_enum_list[] = {
     120             :         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
     121             :         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
     122             :         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
     123             :         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
     124             :         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
     125             : };
     126             : 
     127           0 : DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
     128             : 
     129             : static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
     130             :         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
     131             :         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
     132             :         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
     133             :         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
     134             :         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
     135             : };
     136             : 
     137           0 : DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
     138             :                  drm_tv_subconnector_enum_list)
     139             : 
     140             : static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
     141             :         { DRM_MODE_DIRTY_OFF,      "Off"      },
     142             :         { DRM_MODE_DIRTY_ON,       "On"       },
     143             :         { DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
     144             : };
     145             : 
     146             : struct drm_conn_prop_enum_list {
     147             :         int type;
     148             :         const char *name;
     149             :         struct ida ida;
     150             : };
     151             : 
     152             : /*
     153             :  * Connector and encoder types.
     154             :  */
     155             : static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {
     156             :         { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
     157             :         { DRM_MODE_CONNECTOR_VGA, "VGA" },
     158             :         { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
     159             :         { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
     160             :         { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
     161             :         { DRM_MODE_CONNECTOR_Composite, "Composite" },
     162             :         { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
     163             :         { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
     164             :         { DRM_MODE_CONNECTOR_Component, "Component" },
     165             :         { DRM_MODE_CONNECTOR_9PinDIN, "DIN" },
     166             :         { DRM_MODE_CONNECTOR_DisplayPort, "DP" },
     167             :         { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
     168             :         { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
     169             :         { DRM_MODE_CONNECTOR_TV, "TV" },
     170             :         { DRM_MODE_CONNECTOR_eDP, "eDP" },
     171             :         { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
     172             :         { DRM_MODE_CONNECTOR_DSI, "DSI" },
     173             : };
     174             : 
     175             : static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
     176             :         { DRM_MODE_ENCODER_NONE, "None" },
     177             :         { DRM_MODE_ENCODER_DAC, "DAC" },
     178             :         { DRM_MODE_ENCODER_TMDS, "TMDS" },
     179             :         { DRM_MODE_ENCODER_LVDS, "LVDS" },
     180             :         { DRM_MODE_ENCODER_TVDAC, "TV" },
     181             :         { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
     182             :         { DRM_MODE_ENCODER_DSI, "DSI" },
     183             :         { DRM_MODE_ENCODER_DPMST, "DP MST" },
     184             : };
     185             : 
     186             : static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
     187             :         { SubPixelUnknown, "Unknown" },
     188             :         { SubPixelHorizontalRGB, "Horizontal RGB" },
     189             :         { SubPixelHorizontalBGR, "Horizontal BGR" },
     190             :         { SubPixelVerticalRGB, "Vertical RGB" },
     191             :         { SubPixelVerticalBGR, "Vertical BGR" },
     192             :         { SubPixelNone, "None" },
     193             : };
     194             : 
     195           0 : void drm_connector_ida_init(void)
     196             : {
     197             :         int i;
     198             : 
     199           0 :         for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
     200           0 :                 ida_init(&drm_connector_enum_list[i].ida);
     201           0 : }
     202             : 
     203           0 : void drm_connector_ida_destroy(void)
     204             : {
     205             :         int i;
     206             : 
     207           0 :         for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
     208           0 :                 ida_destroy(&drm_connector_enum_list[i].ida);
     209           0 : }
     210             : 
     211             : /**
     212             :  * drm_get_connector_status_name - return a string for connector status
     213             :  * @status: connector status to compute name of
     214             :  *
     215             :  * In contrast to the other drm_get_*_name functions this one here returns a
     216             :  * const pointer and hence is threadsafe.
     217             :  */
     218           0 : const char *drm_get_connector_status_name(enum drm_connector_status status)
     219             : {
     220           0 :         if (status == connector_status_connected)
     221           0 :                 return "connected";
     222           0 :         else if (status == connector_status_disconnected)
     223           0 :                 return "disconnected";
     224             :         else
     225           0 :                 return "unknown";
     226           0 : }
     227             : EXPORT_SYMBOL(drm_get_connector_status_name);
     228             : 
     229             : /**
     230             :  * drm_get_subpixel_order_name - return a string for a given subpixel enum
     231             :  * @order: enum of subpixel_order
     232             :  *
     233             :  * Note you could abuse this and return something out of bounds, but that
     234             :  * would be a caller error.  No unscrubbed user data should make it here.
     235             :  */
     236           0 : const char *drm_get_subpixel_order_name(enum subpixel_order order)
     237             : {
     238           0 :         return drm_subpixel_enum_list[order].name;
     239             : }
     240             : EXPORT_SYMBOL(drm_get_subpixel_order_name);
     241             : 
     242           0 : static char printable_char(int c)
     243             : {
     244           0 :         return isascii(c) && isprint(c) ? c : '?';
     245             : }
     246             : 
     247             : /**
     248             :  * drm_get_format_name - return a string for drm fourcc format
     249             :  * @format: format to compute name of
     250             :  *
     251             :  * Note that the buffer used by this function is globally shared and owned by
     252             :  * the function itself.
     253             :  *
     254             :  * FIXME: This isn't really multithreading safe.
     255             :  */
     256           0 : const char *drm_get_format_name(uint32_t format)
     257             : {
     258             :         static char buf[32];
     259             : 
     260           0 :         snprintf(buf, sizeof(buf),
     261             :                  "%c%c%c%c %s-endian (0x%08x)",
     262           0 :                  printable_char(format & 0xff),
     263           0 :                  printable_char((format >> 8) & 0xff),
     264           0 :                  printable_char((format >> 16) & 0xff),
     265           0 :                  printable_char((format >> 24) & 0x7f),
     266           0 :                  format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
     267             :                  format);
     268             : 
     269           0 :         return buf;
     270             : }
     271             : EXPORT_SYMBOL(drm_get_format_name);
     272             : 
     273             : /*
     274             :  * Internal function to assign a slot in the object idr and optionally
     275             :  * register the object into the idr.
     276             :  */
     277           0 : static int drm_mode_object_get_reg(struct drm_device *dev,
     278             :                                    struct drm_mode_object *obj,
     279             :                                    uint32_t obj_type,
     280             :                                    bool register_obj)
     281             : {
     282             :         int ret;
     283             : 
     284           0 :         mutex_lock(&dev->mode_config.idr_mutex);
     285           0 :         ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL);
     286           0 :         if (ret >= 0) {
     287             :                 /*
     288             :                  * Set up the object linking under the protection of the idr
     289             :                  * lock so that other users can't see inconsistent state.
     290             :                  */
     291           0 :                 obj->id = ret;
     292           0 :                 obj->type = obj_type;
     293           0 :         }
     294           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     295             : 
     296           0 :         return ret < 0 ? ret : 0;
     297             : }
     298             : 
     299             : /**
     300             :  * drm_mode_object_get - allocate a new modeset identifier
     301             :  * @dev: DRM device
     302             :  * @obj: object pointer, used to generate unique ID
     303             :  * @obj_type: object type
     304             :  *
     305             :  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
     306             :  * for tracking modes, CRTCs and connectors. Note that despite the _get postfix
     307             :  * modeset identifiers are _not_ reference counted. Hence don't use this for
     308             :  * reference counted modeset objects like framebuffers.
     309             :  *
     310             :  * Returns:
     311             :  * Zero on success, error code on failure.
     312             :  */
     313           0 : int drm_mode_object_get(struct drm_device *dev,
     314             :                         struct drm_mode_object *obj, uint32_t obj_type)
     315             : {
     316           0 :         return drm_mode_object_get_reg(dev, obj, obj_type, true);
     317             : }
     318             : 
     319           0 : static void drm_mode_object_register(struct drm_device *dev,
     320             :                                      struct drm_mode_object *obj)
     321             : {
     322           0 :         mutex_lock(&dev->mode_config.idr_mutex);
     323           0 :         idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
     324           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     325           0 : }
     326             : 
     327             : /**
     328             :  * drm_mode_object_put - free a modeset identifer
     329             :  * @dev: DRM device
     330             :  * @object: object to free
     331             :  *
     332             :  * Free @id from @dev's unique identifier pool. Note that despite the _get
     333             :  * postfix modeset identifiers are _not_ reference counted. Hence don't use this
     334             :  * for reference counted modeset objects like framebuffers.
     335             :  */
     336           0 : void drm_mode_object_put(struct drm_device *dev,
     337             :                          struct drm_mode_object *object)
     338             : {
     339           0 :         mutex_lock(&dev->mode_config.idr_mutex);
     340           0 :         idr_remove(&dev->mode_config.crtc_idr, object->id);
     341           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     342           0 : }
     343             : 
     344           0 : static struct drm_mode_object *_object_find(struct drm_device *dev,
     345             :                 uint32_t id, uint32_t type)
     346             : {
     347             :         struct drm_mode_object *obj = NULL;
     348             : 
     349           0 :         mutex_lock(&dev->mode_config.idr_mutex);
     350           0 :         obj = idr_find(&dev->mode_config.crtc_idr, id);
     351           0 :         if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
     352           0 :                 obj = NULL;
     353           0 :         if (obj && obj->id != id)
     354           0 :                 obj = NULL;
     355             :         /* don't leak out unref'd fb's */
     356           0 :         if (obj &&
     357           0 :             (obj->type == DRM_MODE_OBJECT_FB ||
     358           0 :              obj->type == DRM_MODE_OBJECT_BLOB))
     359           0 :                 obj = NULL;
     360           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     361             : 
     362           0 :         return obj;
     363             : }
     364             : 
     365             : /**
     366             :  * drm_mode_object_find - look up a drm object with static lifetime
     367             :  * @dev: drm device
     368             :  * @id: id of the mode object
     369             :  * @type: type of the mode object
     370             :  *
     371             :  * Note that framebuffers cannot be looked up with this functions - since those
     372             :  * are reference counted, they need special treatment.  Even with
     373             :  * DRM_MODE_OBJECT_ANY (although that will simply return NULL
     374             :  * rather than WARN_ON()).
     375             :  */
     376           0 : struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
     377             :                 uint32_t id, uint32_t type)
     378             : {
     379             :         struct drm_mode_object *obj = NULL;
     380             : 
     381             :         /* Framebuffers are reference counted and need their own lookup
     382             :          * function.*/
     383           0 :         WARN_ON(type == DRM_MODE_OBJECT_FB || type == DRM_MODE_OBJECT_BLOB);
     384           0 :         obj = _object_find(dev, id, type);
     385           0 :         return obj;
     386             : }
     387             : EXPORT_SYMBOL(drm_mode_object_find);
     388             : 
     389             : /**
     390             :  * drm_framebuffer_init - initialize a framebuffer
     391             :  * @dev: DRM device
     392             :  * @fb: framebuffer to be initialized
     393             :  * @funcs: ... with these functions
     394             :  *
     395             :  * Allocates an ID for the framebuffer's parent mode object, sets its mode
     396             :  * functions & device file and adds it to the master fd list.
     397             :  *
     398             :  * IMPORTANT:
     399             :  * This functions publishes the fb and makes it available for concurrent access
     400             :  * by other users. Which means by this point the fb _must_ be fully set up -
     401             :  * since all the fb attributes are invariant over its lifetime, no further
     402             :  * locking but only correct reference counting is required.
     403             :  *
     404             :  * Returns:
     405             :  * Zero on success, error code on failure.
     406             :  */
     407           0 : int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
     408             :                          const struct drm_framebuffer_funcs *funcs)
     409             : {
     410             :         int ret;
     411             : 
     412           0 :         mutex_lock(&dev->mode_config.fb_lock);
     413           0 :         kref_init(&fb->refcount);
     414           0 :         INIT_LIST_HEAD(&fb->filp_head);
     415           0 :         fb->dev = dev;
     416           0 :         fb->funcs = funcs;
     417             : 
     418           0 :         ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
     419           0 :         if (ret)
     420             :                 goto out;
     421             : 
     422           0 :         dev->mode_config.num_fb++;
     423           0 :         list_add(&fb->head, &dev->mode_config.fb_list);
     424             : out:
     425           0 :         mutex_unlock(&dev->mode_config.fb_lock);
     426             : 
     427           0 :         return ret;
     428             : }
     429             : EXPORT_SYMBOL(drm_framebuffer_init);
     430             : 
     431             : /* dev->mode_config.fb_lock must be held! */
     432           0 : static void __drm_framebuffer_unregister(struct drm_device *dev,
     433             :                                          struct drm_framebuffer *fb)
     434             : {
     435           0 :         mutex_lock(&dev->mode_config.idr_mutex);
     436           0 :         idr_remove(&dev->mode_config.crtc_idr, fb->base.id);
     437           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     438             : 
     439           0 :         fb->base.id = 0;
     440           0 : }
     441             : 
     442           0 : static void drm_framebuffer_free(struct kref *kref)
     443             : {
     444             :         struct drm_framebuffer *fb =
     445           0 :                         container_of(kref, struct drm_framebuffer, refcount);
     446           0 :         struct drm_device *dev = fb->dev;
     447             : 
     448             :         /*
     449             :          * The lookup idr holds a weak reference, which has not necessarily been
     450             :          * removed at this point. Check for that.
     451             :          */
     452           0 :         mutex_lock(&dev->mode_config.fb_lock);
     453           0 :         if (fb->base.id) {
     454             :                 /* Mark fb as reaped and drop idr ref. */
     455           0 :                 __drm_framebuffer_unregister(dev, fb);
     456           0 :         }
     457           0 :         mutex_unlock(&dev->mode_config.fb_lock);
     458             : 
     459           0 :         fb->funcs->destroy(fb);
     460           0 : }
     461             : 
     462           0 : static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev,
     463             :                                                         uint32_t id)
     464             : {
     465             :         struct drm_mode_object *obj = NULL;
     466             :         struct drm_framebuffer *fb;
     467             : 
     468           0 :         mutex_lock(&dev->mode_config.idr_mutex);
     469           0 :         obj = idr_find(&dev->mode_config.crtc_idr, id);
     470           0 :         if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id))
     471           0 :                 fb = NULL;
     472             :         else
     473           0 :                 fb = obj_to_fb(obj);
     474           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
     475             : 
     476           0 :         return fb;
     477             : }
     478             : 
     479             : /**
     480             :  * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
     481             :  * @dev: drm device
     482             :  * @id: id of the fb object
     483             :  *
     484             :  * If successful, this grabs an additional reference to the framebuffer -
     485             :  * callers need to make sure to eventually unreference the returned framebuffer
     486             :  * again, using @drm_framebuffer_unreference.
     487             :  */
     488           0 : struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
     489             :                                                uint32_t id)
     490             : {
     491             :         struct drm_framebuffer *fb;
     492             : 
     493           0 :         mutex_lock(&dev->mode_config.fb_lock);
     494           0 :         fb = __drm_framebuffer_lookup(dev, id);
     495           0 :         if (fb) {
     496           0 :                 if (!kref_get_unless_zero(&fb->refcount))
     497           0 :                         fb = NULL;
     498             :         }
     499           0 :         mutex_unlock(&dev->mode_config.fb_lock);
     500             : 
     501           0 :         return fb;
     502             : }
     503             : EXPORT_SYMBOL(drm_framebuffer_lookup);
     504             : 
     505             : /**
     506             :  * drm_framebuffer_unreference - unref a framebuffer
     507             :  * @fb: framebuffer to unref
     508             :  *
     509             :  * This functions decrements the fb's refcount and frees it if it drops to zero.
     510             :  */
     511           0 : void drm_framebuffer_unreference(struct drm_framebuffer *fb)
     512             : {
     513             :         DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
     514           0 :         kref_put(&fb->refcount, drm_framebuffer_free);
     515           0 : }
     516             : EXPORT_SYMBOL(drm_framebuffer_unreference);
     517             : 
     518             : /**
     519             :  * drm_framebuffer_reference - incr the fb refcnt
     520             :  * @fb: framebuffer
     521             :  *
     522             :  * This functions increments the fb's refcount.
     523             :  */
     524           0 : void drm_framebuffer_reference(struct drm_framebuffer *fb)
     525             : {
     526             :         DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
     527           0 :         kref_get(&fb->refcount);
     528           0 : }
     529             : EXPORT_SYMBOL(drm_framebuffer_reference);
     530             : 
     531             : /**
     532             :  * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
     533             :  * @fb: fb to unregister
     534             :  *
     535             :  * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
     536             :  * those used for fbdev. Note that the caller must hold a reference of it's own,
     537             :  * i.e. the object may not be destroyed through this call (since it'll lead to a
     538             :  * locking inversion).
     539             :  */
     540           0 : void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
     541             : {
     542             :         struct drm_device *dev;
     543             : 
     544           0 :         if (!fb)
     545           0 :                 return;
     546             : 
     547           0 :         dev = fb->dev;
     548             : 
     549           0 :         mutex_lock(&dev->mode_config.fb_lock);
     550             :         /* Mark fb as reaped and drop idr ref. */
     551           0 :         __drm_framebuffer_unregister(dev, fb);
     552           0 :         mutex_unlock(&dev->mode_config.fb_lock);
     553           0 : }
     554             : EXPORT_SYMBOL(drm_framebuffer_unregister_private);
     555             : 
     556             : /**
     557             :  * drm_framebuffer_cleanup - remove a framebuffer object
     558             :  * @fb: framebuffer to remove
     559             :  *
     560             :  * Cleanup framebuffer. This function is intended to be used from the drivers
     561             :  * ->destroy callback. It can also be used to clean up driver private
     562             :  *  framebuffers embedded into a larger structure.
     563             :  *
     564             :  * Note that this function does not remove the fb from active usuage - if it is
     565             :  * still used anywhere, hilarity can ensue since userspace could call getfb on
     566             :  * the id and get back -EINVAL. Obviously no concern at driver unload time.
     567             :  *
     568             :  * Also, the framebuffer will not be removed from the lookup idr - for
     569             :  * user-created framebuffers this will happen in in the rmfb ioctl. For
     570             :  * driver-private objects (e.g. for fbdev) drivers need to explicitly call
     571             :  * drm_framebuffer_unregister_private.
     572             :  */
     573           0 : void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
     574             : {
     575           0 :         struct drm_device *dev = fb->dev;
     576             : 
     577           0 :         mutex_lock(&dev->mode_config.fb_lock);
     578           0 :         list_del(&fb->head);
     579           0 :         dev->mode_config.num_fb--;
     580           0 :         mutex_unlock(&dev->mode_config.fb_lock);
     581           0 : }
     582             : EXPORT_SYMBOL(drm_framebuffer_cleanup);
     583             : 
     584             : /**
     585             :  * drm_framebuffer_remove - remove and unreference a framebuffer object
     586             :  * @fb: framebuffer to remove
     587             :  *
     588             :  * Scans all the CRTCs and planes in @dev's mode_config.  If they're
     589             :  * using @fb, removes it, setting it to NULL. Then drops the reference to the
     590             :  * passed-in framebuffer. Might take the modeset locks.
     591             :  *
     592             :  * Note that this function optimizes the cleanup away if the caller holds the
     593             :  * last reference to the framebuffer. It is also guaranteed to not take the
     594             :  * modeset locks in this case.
     595             :  */
     596           0 : void drm_framebuffer_remove(struct drm_framebuffer *fb)
     597             : {
     598             :         struct drm_device *dev;
     599             :         struct drm_crtc *crtc;
     600             :         struct drm_plane *plane;
     601           0 :         struct drm_mode_set set;
     602             :         int ret;
     603             : 
     604           0 :         if (!fb)
     605           0 :                 return;
     606             : 
     607           0 :         dev = fb->dev;
     608             : 
     609           0 :         WARN_ON(!list_empty(&fb->filp_head));
     610             : 
     611             :         /*
     612             :          * drm ABI mandates that we remove any deleted framebuffers from active
     613             :          * useage. But since most sane clients only remove framebuffers they no
     614             :          * longer need, try to optimize this away.
     615             :          *
     616             :          * Since we're holding a reference ourselves, observing a refcount of 1
     617             :          * means that we're the last holder and can skip it. Also, the refcount
     618             :          * can never increase from 1 again, so we don't need any barriers or
     619             :          * locks.
     620             :          *
     621             :          * Note that userspace could try to race with use and instate a new
     622             :          * usage _after_ we've cleared all current ones. End result will be an
     623             :          * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
     624             :          * in this manner.
     625             :          */
     626           0 :         if (atomic_read(&fb->refcount.refcount) > 1) {
     627           0 :                 drm_modeset_lock_all(dev);
     628             :                 /* remove from any CRTC */
     629           0 :                 drm_for_each_crtc(crtc, dev) {
     630           0 :                         if (crtc->primary->fb == fb) {
     631             :                                 /* should turn off the crtc */
     632           0 :                                 memset(&set, 0, sizeof(struct drm_mode_set));
     633           0 :                                 set.crtc = crtc;
     634           0 :                                 set.fb = NULL;
     635           0 :                                 ret = drm_mode_set_config_internal(&set);
     636           0 :                                 if (ret)
     637           0 :                                         DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
     638             :                         }
     639             :                 }
     640             : 
     641           0 :                 drm_for_each_plane(plane, dev) {
     642           0 :                         if (plane->fb == fb)
     643           0 :                                 drm_plane_force_disable(plane);
     644             :                 }
     645           0 :                 drm_modeset_unlock_all(dev);
     646           0 :         }
     647             : 
     648           0 :         drm_framebuffer_unreference(fb);
     649           0 : }
     650             : EXPORT_SYMBOL(drm_framebuffer_remove);
     651             : 
     652             : DEFINE_WW_CLASS(crtc_ww_class);
     653             : 
     654             : /**
     655             :  * drm_crtc_init_with_planes - Initialise a new CRTC object with
     656             :  *    specified primary and cursor planes.
     657             :  * @dev: DRM device
     658             :  * @crtc: CRTC object to init
     659             :  * @primary: Primary plane for CRTC
     660             :  * @cursor: Cursor plane for CRTC
     661             :  * @funcs: callbacks for the new CRTC
     662             :  *
     663             :  * Inits a new object created as base part of a driver crtc object.
     664             :  *
     665             :  * Returns:
     666             :  * Zero on success, error code on failure.
     667             :  */
     668           0 : int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
     669             :                               struct drm_plane *primary,
     670             :                               struct drm_plane *cursor,
     671             :                               const struct drm_crtc_funcs *funcs)
     672             : {
     673           0 :         struct drm_mode_config *config = &dev->mode_config;
     674             :         int ret;
     675             : 
     676           0 :         WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
     677           0 :         WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
     678             : 
     679           0 :         crtc->dev = dev;
     680           0 :         crtc->funcs = funcs;
     681             : 
     682           0 :         drm_modeset_lock_init(&crtc->mutex);
     683           0 :         ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
     684           0 :         if (ret)
     685           0 :                 return ret;
     686             : 
     687           0 :         crtc->base.properties = &crtc->properties;
     688             : 
     689           0 :         list_add_tail(&crtc->head, &config->crtc_list);
     690           0 :         config->num_crtc++;
     691             : 
     692           0 :         crtc->primary = primary;
     693           0 :         crtc->cursor = cursor;
     694           0 :         if (primary)
     695           0 :                 primary->possible_crtcs = 1 << drm_crtc_index(crtc);
     696           0 :         if (cursor)
     697           0 :                 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
     698             : 
     699           0 :         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
     700           0 :                 drm_object_attach_property(&crtc->base, config->prop_active, 0);
     701           0 :                 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
     702           0 :         }
     703             : 
     704           0 :         return 0;
     705           0 : }
     706             : EXPORT_SYMBOL(drm_crtc_init_with_planes);
     707             : 
     708             : /**
     709             :  * drm_crtc_cleanup - Clean up the core crtc usage
     710             :  * @crtc: CRTC to cleanup
     711             :  *
     712             :  * This function cleans up @crtc and removes it from the DRM mode setting
     713             :  * core. Note that the function does *not* free the crtc structure itself,
     714             :  * this is the responsibility of the caller.
     715             :  */
     716           0 : void drm_crtc_cleanup(struct drm_crtc *crtc)
     717             : {
     718           0 :         struct drm_device *dev = crtc->dev;
     719             : 
     720           0 :         kfree(crtc->gamma_store);
     721           0 :         crtc->gamma_store = NULL;
     722             : 
     723           0 :         drm_modeset_lock_fini(&crtc->mutex);
     724             : 
     725           0 :         drm_mode_object_put(dev, &crtc->base);
     726           0 :         list_del(&crtc->head);
     727           0 :         dev->mode_config.num_crtc--;
     728             : 
     729           0 :         WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
     730           0 :         if (crtc->state && crtc->funcs->atomic_destroy_state)
     731           0 :                 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
     732             : 
     733           0 :         memset(crtc, 0, sizeof(*crtc));
     734           0 : }
     735             : EXPORT_SYMBOL(drm_crtc_cleanup);
     736             : 
     737             : /**
     738             :  * drm_crtc_index - find the index of a registered CRTC
     739             :  * @crtc: CRTC to find index for
     740             :  *
     741             :  * Given a registered CRTC, return the index of that CRTC within a DRM
     742             :  * device's list of CRTCs.
     743             :  */
     744           0 : unsigned int drm_crtc_index(struct drm_crtc *crtc)
     745             : {
     746             :         unsigned int index = 0;
     747             :         struct drm_crtc *tmp;
     748             : 
     749           0 :         drm_for_each_crtc(tmp, crtc->dev) {
     750           0 :                 if (tmp == crtc)
     751             :                         return index;
     752             : 
     753           0 :                 index++;
     754             :         }
     755             : 
     756           0 :         BUG();
     757           0 : }
     758             : EXPORT_SYMBOL(drm_crtc_index);
     759             : 
     760             : /*
     761             :  * drm_mode_remove - remove and free a mode
     762             :  * @connector: connector list to modify
     763             :  * @mode: mode to remove
     764             :  *
     765             :  * Remove @mode from @connector's mode list, then free it.
     766             :  */
     767           0 : static void drm_mode_remove(struct drm_connector *connector,
     768             :                             struct drm_display_mode *mode)
     769             : {
     770           0 :         list_del(&mode->head);
     771           0 :         drm_mode_destroy(connector->dev, mode);
     772           0 : }
     773             : 
     774             : /**
     775             :  * drm_display_info_set_bus_formats - set the supported bus formats
     776             :  * @info: display info to store bus formats in
     777             :  * @formats: array containing the supported bus formats
     778             :  * @num_formats: the number of entries in the fmts array
     779             :  *
     780             :  * Store the supported bus formats in display info structure.
     781             :  * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for
     782             :  * a full list of available formats.
     783             :  */
     784           0 : int drm_display_info_set_bus_formats(struct drm_display_info *info,
     785             :                                      const u32 *formats,
     786             :                                      unsigned int num_formats)
     787             : {
     788             :         u32 *fmts = NULL;
     789             : 
     790           0 :         if (!formats && num_formats)
     791           0 :                 return -EINVAL;
     792             : 
     793           0 :         if (formats && num_formats) {
     794           0 :                 fmts = kmemdup(formats, sizeof(*formats) * num_formats,
     795             :                                GFP_KERNEL);
     796           0 :                 if (!fmts)
     797           0 :                         return -ENOMEM;
     798             :         }
     799             : 
     800           0 :         kfree(info->bus_formats);
     801           0 :         info->bus_formats = fmts;
     802           0 :         info->num_bus_formats = num_formats;
     803             : 
     804           0 :         return 0;
     805           0 : }
     806             : EXPORT_SYMBOL(drm_display_info_set_bus_formats);
     807             : 
     808             : /**
     809             :  * drm_connector_get_cmdline_mode - reads the user's cmdline mode
     810             :  * @connector: connector to quwery
     811             :  *
     812             :  * The kernel supports per-connector configration of its consoles through
     813             :  * use of the video= parameter. This function parses that option and
     814             :  * extracts the user's specified mode (or enable/disable status) for a
     815             :  * particular connector. This is typically only used during the early fbdev
     816             :  * setup.
     817             :  */
     818           0 : static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
     819             : {
     820           0 :         struct drm_cmdline_mode *mode = &connector->cmdline_mode;
     821             :         char *option = NULL;
     822             : 
     823             : #ifdef __linux__
     824             :         if (fb_get_options(connector->name, &option))
     825             :                 return;
     826             : #endif
     827             : 
     828           0 :         if (!drm_mode_parse_command_line_for_connector(option,
     829             :                                                        connector,
     830             :                                                        mode))
     831           0 :                 return;
     832             : 
     833           0 :         if (mode->force) {
     834             :                 const char *s;
     835             : 
     836           0 :                 switch (mode->force) {
     837             :                 case DRM_FORCE_OFF:
     838             :                         s = "OFF";
     839           0 :                         break;
     840             :                 case DRM_FORCE_ON_DIGITAL:
     841             :                         s = "ON - dig";
     842           0 :                         break;
     843             :                 default:
     844             :                 case DRM_FORCE_ON:
     845             :                         s = "ON";
     846           0 :                         break;
     847             :                 }
     848             : 
     849             :                 DRM_INFO("forcing %s connector %s\n", connector->name, s);
     850           0 :                 connector->force = mode->force;
     851           0 :         }
     852             : 
     853             :         DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
     854             :                       connector->name,
     855             :                       mode->xres, mode->yres,
     856             :                       mode->refresh_specified ? mode->refresh : 60,
     857             :                       mode->rb ? " reduced blanking" : "",
     858             :                       mode->margins ? " with margins" : "",
     859             :                       mode->interlace ?  " interlaced" : "");
     860           0 : }
     861             : 
     862             : /**
     863             :  * drm_connector_init - Init a preallocated connector
     864             :  * @dev: DRM device
     865             :  * @connector: the connector to init
     866             :  * @funcs: callbacks for this connector
     867             :  * @connector_type: user visible type of the connector
     868             :  *
     869             :  * Initialises a preallocated connector. Connectors should be
     870             :  * subclassed as part of driver connector objects.
     871             :  *
     872             :  * Returns:
     873             :  * Zero on success, error code on failure.
     874             :  */
     875           0 : int drm_connector_init(struct drm_device *dev,
     876             :                        struct drm_connector *connector,
     877             :                        const struct drm_connector_funcs *funcs,
     878             :                        int connector_type)
     879             : {
     880           0 :         struct drm_mode_config *config = &dev->mode_config;
     881             :         int ret;
     882             :         struct ida *connector_ida =
     883           0 :                 &drm_connector_enum_list[connector_type].ida;
     884             : 
     885           0 :         drm_modeset_lock_all(dev);
     886             : 
     887           0 :         ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false);
     888           0 :         if (ret)
     889             :                 goto out_unlock;
     890             : 
     891           0 :         connector->base.properties = &connector->properties;
     892           0 :         connector->dev = dev;
     893           0 :         connector->funcs = funcs;
     894           0 :         connector->connector_type = connector_type;
     895           0 :         connector->connector_type_id =
     896           0 :                 ida_simple_get(connector_ida, 1, 0, GFP_KERNEL);
     897           0 :         if (connector->connector_type_id < 0) {
     898             :                 ret = connector->connector_type_id;
     899           0 :                 goto out_put;
     900             :         }
     901           0 :         connector->name =
     902           0 :                 kasprintf(GFP_KERNEL, "%s-%d",
     903           0 :                           drm_connector_enum_list[connector_type].name,
     904             :                           connector->connector_type_id);
     905           0 :         if (!connector->name) {
     906             :                 ret = -ENOMEM;
     907           0 :                 goto out_put;
     908             :         }
     909             : 
     910           0 :         INIT_LIST_HEAD(&connector->probed_modes);
     911           0 :         INIT_LIST_HEAD(&connector->modes);
     912           0 :         connector->edid_blob_ptr = NULL;
     913           0 :         connector->status = connector_status_unknown;
     914             : 
     915           0 :         drm_connector_get_cmdline_mode(connector);
     916             : 
     917             :         /* We should add connectors at the end to avoid upsetting the connector
     918             :          * index too much. */
     919           0 :         list_add_tail(&connector->head, &config->connector_list);
     920           0 :         config->num_connector++;
     921             : 
     922           0 :         if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
     923           0 :                 drm_object_attach_property(&connector->base,
     924           0 :                                               config->edid_property,
     925             :                                               0);
     926             : 
     927           0 :         drm_object_attach_property(&connector->base,
     928           0 :                                       config->dpms_property, 0);
     929             : 
     930           0 :         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
     931           0 :                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
     932           0 :         }
     933             : 
     934           0 :         connector->debugfs_entry = NULL;
     935             : 
     936             : out_put:
     937           0 :         if (ret)
     938           0 :                 drm_mode_object_put(dev, &connector->base);
     939             : 
     940             : out_unlock:
     941           0 :         drm_modeset_unlock_all(dev);
     942             : 
     943           0 :         return ret;
     944             : }
     945             : EXPORT_SYMBOL(drm_connector_init);
     946             : 
     947             : /**
     948             :  * drm_connector_cleanup - cleans up an initialised connector
     949             :  * @connector: connector to cleanup
     950             :  *
     951             :  * Cleans up the connector but doesn't free the object.
     952             :  */
     953           0 : void drm_connector_cleanup(struct drm_connector *connector)
     954             : {
     955           0 :         struct drm_device *dev = connector->dev;
     956             :         struct drm_display_mode *mode, *t;
     957             : 
     958           0 :         if (connector->tile_group) {
     959           0 :                 drm_mode_put_tile_group(dev, connector->tile_group);
     960           0 :                 connector->tile_group = NULL;
     961           0 :         }
     962             : 
     963           0 :         list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
     964           0 :                 drm_mode_remove(connector, mode);
     965             : 
     966           0 :         list_for_each_entry_safe(mode, t, &connector->modes, head)
     967           0 :                 drm_mode_remove(connector, mode);
     968             : 
     969           0 :         ida_remove(&drm_connector_enum_list[connector->connector_type].ida,
     970           0 :                    connector->connector_type_id);
     971             : 
     972           0 :         kfree(connector->display_info.bus_formats);
     973           0 :         drm_mode_object_put(dev, &connector->base);
     974           0 :         kfree(connector->name);
     975           0 :         connector->name = NULL;
     976           0 :         list_del(&connector->head);
     977           0 :         dev->mode_config.num_connector--;
     978             : 
     979           0 :         WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);
     980           0 :         if (connector->state && connector->funcs->atomic_destroy_state)
     981           0 :                 connector->funcs->atomic_destroy_state(connector,
     982             :                                                        connector->state);
     983             : 
     984           0 :         memset(connector, 0, sizeof(*connector));
     985           0 : }
     986             : EXPORT_SYMBOL(drm_connector_cleanup);
     987             : 
     988             : /**
     989             :  * drm_connector_index - find the index of a registered connector
     990             :  * @connector: connector to find index for
     991             :  *
     992             :  * Given a registered connector, return the index of that connector within a DRM
     993             :  * device's list of connectors.
     994             :  */
     995           0 : unsigned int drm_connector_index(struct drm_connector *connector)
     996             : {
     997             :         unsigned int index = 0;
     998             :         struct drm_connector *tmp;
     999           0 :         struct drm_mode_config *config = &connector->dev->mode_config;
    1000             : 
    1001           0 :         WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
    1002             : 
    1003           0 :         drm_for_each_connector(tmp, connector->dev) {
    1004           0 :                 if (tmp == connector)
    1005             :                         return index;
    1006             : 
    1007           0 :                 index++;
    1008             :         }
    1009             : 
    1010           0 :         BUG();
    1011           0 : }
    1012             : EXPORT_SYMBOL(drm_connector_index);
    1013             : 
    1014             : /**
    1015             :  * drm_connector_register - register a connector
    1016             :  * @connector: the connector to register
    1017             :  *
    1018             :  * Register userspace interfaces for a connector
    1019             :  *
    1020             :  * Returns:
    1021             :  * Zero on success, error code on failure.
    1022             :  */
    1023           0 : int drm_connector_register(struct drm_connector *connector)
    1024             : {
    1025             :         int ret;
    1026             : 
    1027           0 :         drm_mode_object_register(connector->dev, &connector->base);
    1028             : 
    1029           0 :         ret = drm_sysfs_connector_add(connector);
    1030           0 :         if (ret)
    1031           0 :                 return ret;
    1032             : 
    1033           0 :         ret = drm_debugfs_connector_add(connector);
    1034           0 :         if (ret) {
    1035           0 :                 drm_sysfs_connector_remove(connector);
    1036           0 :                 return ret;
    1037             :         }
    1038             : 
    1039           0 :         return 0;
    1040           0 : }
    1041             : EXPORT_SYMBOL(drm_connector_register);
    1042             : 
    1043             : /**
    1044             :  * drm_connector_unregister - unregister a connector
    1045             :  * @connector: the connector to unregister
    1046             :  *
    1047             :  * Unregister userspace interfaces for a connector
    1048             :  */
    1049           0 : void drm_connector_unregister(struct drm_connector *connector)
    1050             : {
    1051           0 :         drm_sysfs_connector_remove(connector);
    1052           0 :         drm_debugfs_connector_remove(connector);
    1053           0 : }
    1054             : EXPORT_SYMBOL(drm_connector_unregister);
    1055             : 
    1056             : 
    1057             : /**
    1058             :  * drm_connector_unplug_all - unregister connector userspace interfaces
    1059             :  * @dev: drm device
    1060             :  *
    1061             :  * This function unregisters all connector userspace interfaces in sysfs. Should
    1062             :  * be call when the device is disconnected, e.g. from an usb driver's
    1063             :  * ->disconnect callback.
    1064             :  */
    1065           0 : void drm_connector_unplug_all(struct drm_device *dev)
    1066             : {
    1067             :         struct drm_connector *connector;
    1068             : 
    1069             :         /* FIXME: taking the mode config mutex ends up in a clash with sysfs */
    1070           0 :         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
    1071           0 :                 drm_connector_unregister(connector);
    1072             : 
    1073           0 : }
    1074             : EXPORT_SYMBOL(drm_connector_unplug_all);
    1075             : 
    1076             : /**
    1077             :  * drm_encoder_init - Init a preallocated encoder
    1078             :  * @dev: drm device
    1079             :  * @encoder: the encoder to init
    1080             :  * @funcs: callbacks for this encoder
    1081             :  * @encoder_type: user visible type of the encoder
    1082             :  *
    1083             :  * Initialises a preallocated encoder. Encoder should be
    1084             :  * subclassed as part of driver encoder objects.
    1085             :  *
    1086             :  * Returns:
    1087             :  * Zero on success, error code on failure.
    1088             :  */
    1089           0 : int drm_encoder_init(struct drm_device *dev,
    1090             :                       struct drm_encoder *encoder,
    1091             :                       const struct drm_encoder_funcs *funcs,
    1092             :                       int encoder_type)
    1093             : {
    1094             :         int ret;
    1095             : 
    1096           0 :         drm_modeset_lock_all(dev);
    1097             : 
    1098           0 :         ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
    1099           0 :         if (ret)
    1100             :                 goto out_unlock;
    1101             : 
    1102           0 :         encoder->dev = dev;
    1103           0 :         encoder->encoder_type = encoder_type;
    1104           0 :         encoder->funcs = funcs;
    1105           0 :         encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
    1106           0 :                                   drm_encoder_enum_list[encoder_type].name,
    1107           0 :                                   encoder->base.id);
    1108           0 :         if (!encoder->name) {
    1109             :                 ret = -ENOMEM;
    1110           0 :                 goto out_put;
    1111             :         }
    1112             : 
    1113           0 :         list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
    1114           0 :         dev->mode_config.num_encoder++;
    1115             : 
    1116             : out_put:
    1117           0 :         if (ret)
    1118           0 :                 drm_mode_object_put(dev, &encoder->base);
    1119             : 
    1120             : out_unlock:
    1121           0 :         drm_modeset_unlock_all(dev);
    1122             : 
    1123           0 :         return ret;
    1124             : }
    1125             : EXPORT_SYMBOL(drm_encoder_init);
    1126             : 
    1127             : /**
    1128             :  * drm_encoder_cleanup - cleans up an initialised encoder
    1129             :  * @encoder: encoder to cleanup
    1130             :  *
    1131             :  * Cleans up the encoder but doesn't free the object.
    1132             :  */
    1133           0 : void drm_encoder_cleanup(struct drm_encoder *encoder)
    1134             : {
    1135           0 :         struct drm_device *dev = encoder->dev;
    1136             : 
    1137           0 :         drm_modeset_lock_all(dev);
    1138           0 :         drm_mode_object_put(dev, &encoder->base);
    1139           0 :         kfree(encoder->name);
    1140           0 :         list_del(&encoder->head);
    1141           0 :         dev->mode_config.num_encoder--;
    1142           0 :         drm_modeset_unlock_all(dev);
    1143             : 
    1144           0 :         memset(encoder, 0, sizeof(*encoder));
    1145           0 : }
    1146             : EXPORT_SYMBOL(drm_encoder_cleanup);
    1147             : 
    1148             : /**
    1149             :  * drm_universal_plane_init - Initialize a new universal plane object
    1150             :  * @dev: DRM device
    1151             :  * @plane: plane object to init
    1152             :  * @possible_crtcs: bitmask of possible CRTCs
    1153             :  * @funcs: callbacks for the new plane
    1154             :  * @formats: array of supported formats (%DRM_FORMAT_*)
    1155             :  * @format_count: number of elements in @formats
    1156             :  * @type: type of plane (overlay, primary, cursor)
    1157             :  *
    1158             :  * Initializes a plane object of type @type.
    1159             :  *
    1160             :  * Returns:
    1161             :  * Zero on success, error code on failure.
    1162             :  */
    1163           0 : int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
    1164             :                              unsigned long possible_crtcs,
    1165             :                              const struct drm_plane_funcs *funcs,
    1166             :                              const uint32_t *formats, unsigned int format_count,
    1167             :                              enum drm_plane_type type)
    1168             : {
    1169           0 :         struct drm_mode_config *config = &dev->mode_config;
    1170             :         int ret;
    1171             : 
    1172           0 :         ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
    1173           0 :         if (ret)
    1174           0 :                 return ret;
    1175             : 
    1176           0 :         drm_modeset_lock_init(&plane->mutex);
    1177             : 
    1178           0 :         plane->base.properties = &plane->properties;
    1179           0 :         plane->dev = dev;
    1180           0 :         plane->funcs = funcs;
    1181           0 :         plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
    1182             :                                             GFP_KERNEL);
    1183           0 :         if (!plane->format_types) {
    1184             :                 DRM_DEBUG_KMS("out of memory when allocating plane\n");
    1185           0 :                 drm_mode_object_put(dev, &plane->base);
    1186           0 :                 return -ENOMEM;
    1187             :         }
    1188             : 
    1189           0 :         memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
    1190           0 :         plane->format_count = format_count;
    1191           0 :         plane->possible_crtcs = possible_crtcs;
    1192           0 :         plane->type = type;
    1193             : 
    1194           0 :         list_add_tail(&plane->head, &config->plane_list);
    1195           0 :         config->num_total_plane++;
    1196           0 :         if (plane->type == DRM_PLANE_TYPE_OVERLAY)
    1197           0 :                 config->num_overlay_plane++;
    1198             : 
    1199           0 :         drm_object_attach_property(&plane->base,
    1200           0 :                                    config->plane_type_property,
    1201           0 :                                    plane->type);
    1202             : 
    1203           0 :         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
    1204           0 :                 drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
    1205           0 :                 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
    1206           0 :                 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
    1207           0 :                 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
    1208           0 :                 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
    1209           0 :                 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
    1210           0 :                 drm_object_attach_property(&plane->base, config->prop_src_x, 0);
    1211           0 :                 drm_object_attach_property(&plane->base, config->prop_src_y, 0);
    1212           0 :                 drm_object_attach_property(&plane->base, config->prop_src_w, 0);
    1213           0 :                 drm_object_attach_property(&plane->base, config->prop_src_h, 0);
    1214           0 :         }
    1215             : 
    1216           0 :         return 0;
    1217           0 : }
    1218             : EXPORT_SYMBOL(drm_universal_plane_init);
    1219             : 
    1220             : /**
    1221             :  * drm_plane_init - Initialize a legacy plane
    1222             :  * @dev: DRM device
    1223             :  * @plane: plane object to init
    1224             :  * @possible_crtcs: bitmask of possible CRTCs
    1225             :  * @funcs: callbacks for the new plane
    1226             :  * @formats: array of supported formats (%DRM_FORMAT_*)
    1227             :  * @format_count: number of elements in @formats
    1228             :  * @is_primary: plane type (primary vs overlay)
    1229             :  *
    1230             :  * Legacy API to initialize a DRM plane.
    1231             :  *
    1232             :  * New drivers should call drm_universal_plane_init() instead.
    1233             :  *
    1234             :  * Returns:
    1235             :  * Zero on success, error code on failure.
    1236             :  */
    1237           0 : int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
    1238             :                    unsigned long possible_crtcs,
    1239             :                    const struct drm_plane_funcs *funcs,
    1240             :                    const uint32_t *formats, unsigned int format_count,
    1241             :                    bool is_primary)
    1242             : {
    1243             :         enum drm_plane_type type;
    1244             : 
    1245           0 :         type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
    1246           0 :         return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
    1247             :                                         formats, format_count, type);
    1248             : }
    1249             : EXPORT_SYMBOL(drm_plane_init);
    1250             : 
    1251             : /**
    1252             :  * drm_plane_cleanup - Clean up the core plane usage
    1253             :  * @plane: plane to cleanup
    1254             :  *
    1255             :  * This function cleans up @plane and removes it from the DRM mode setting
    1256             :  * core. Note that the function does *not* free the plane structure itself,
    1257             :  * this is the responsibility of the caller.
    1258             :  */
    1259           0 : void drm_plane_cleanup(struct drm_plane *plane)
    1260             : {
    1261           0 :         struct drm_device *dev = plane->dev;
    1262             : 
    1263           0 :         drm_modeset_lock_all(dev);
    1264           0 :         kfree(plane->format_types);
    1265           0 :         drm_mode_object_put(dev, &plane->base);
    1266             : 
    1267           0 :         BUG_ON(list_empty(&plane->head));
    1268             : 
    1269           0 :         list_del(&plane->head);
    1270           0 :         dev->mode_config.num_total_plane--;
    1271           0 :         if (plane->type == DRM_PLANE_TYPE_OVERLAY)
    1272           0 :                 dev->mode_config.num_overlay_plane--;
    1273           0 :         drm_modeset_unlock_all(dev);
    1274             : 
    1275           0 :         WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
    1276           0 :         if (plane->state && plane->funcs->atomic_destroy_state)
    1277           0 :                 plane->funcs->atomic_destroy_state(plane, plane->state);
    1278             : 
    1279           0 :         memset(plane, 0, sizeof(*plane));
    1280           0 : }
    1281             : EXPORT_SYMBOL(drm_plane_cleanup);
    1282             : 
    1283             : /**
    1284             :  * drm_plane_index - find the index of a registered plane
    1285             :  * @plane: plane to find index for
    1286             :  *
    1287             :  * Given a registered plane, return the index of that CRTC within a DRM
    1288             :  * device's list of planes.
    1289             :  */
    1290           0 : unsigned int drm_plane_index(struct drm_plane *plane)
    1291             : {
    1292             :         unsigned int index = 0;
    1293             :         struct drm_plane *tmp;
    1294             : 
    1295           0 :         drm_for_each_plane(tmp, plane->dev) {
    1296           0 :                 if (tmp == plane)
    1297             :                         return index;
    1298             : 
    1299           0 :                 index++;
    1300             :         }
    1301             : 
    1302           0 :         BUG();
    1303           0 : }
    1304             : EXPORT_SYMBOL(drm_plane_index);
    1305             : 
    1306             : /**
    1307             :  * drm_plane_from_index - find the registered plane at an index
    1308             :  * @dev: DRM device
    1309             :  * @idx: index of registered plane to find for
    1310             :  *
    1311             :  * Given a plane index, return the registered plane from DRM device's
    1312             :  * list of planes with matching index.
    1313             :  */
    1314             : struct drm_plane *
    1315           0 : drm_plane_from_index(struct drm_device *dev, int idx)
    1316             : {
    1317             :         struct drm_plane *plane;
    1318             :         unsigned int i = 0;
    1319             : 
    1320           0 :         drm_for_each_plane(plane, dev) {
    1321           0 :                 if (i == idx)
    1322           0 :                         return plane;
    1323           0 :                 i++;
    1324             :         }
    1325           0 :         return NULL;
    1326           0 : }
    1327             : EXPORT_SYMBOL(drm_plane_from_index);
    1328             : 
    1329             : /**
    1330             :  * drm_plane_force_disable - Forcibly disable a plane
    1331             :  * @plane: plane to disable
    1332             :  *
    1333             :  * Forces the plane to be disabled.
    1334             :  *
    1335             :  * Used when the plane's current framebuffer is destroyed,
    1336             :  * and when restoring fbdev mode.
    1337             :  */
    1338           0 : void drm_plane_force_disable(struct drm_plane *plane)
    1339             : {
    1340             :         int ret;
    1341             : 
    1342           0 :         if (!plane->fb)
    1343           0 :                 return;
    1344             : 
    1345           0 :         plane->old_fb = plane->fb;
    1346           0 :         ret = plane->funcs->disable_plane(plane);
    1347           0 :         if (ret) {
    1348           0 :                 DRM_ERROR("failed to disable plane with busy fb\n");
    1349           0 :                 plane->old_fb = NULL;
    1350           0 :                 return;
    1351             :         }
    1352             :         /* disconnect the plane from the fb and crtc: */
    1353           0 :         drm_framebuffer_unreference(plane->old_fb);
    1354           0 :         plane->old_fb = NULL;
    1355           0 :         plane->fb = NULL;
    1356           0 :         plane->crtc = NULL;
    1357           0 : }
    1358             : EXPORT_SYMBOL(drm_plane_force_disable);
    1359             : 
    1360           0 : static int drm_mode_create_standard_properties(struct drm_device *dev)
    1361             : {
    1362             :         struct drm_property *prop;
    1363             : 
    1364             :         /*
    1365             :          * Standard properties (apply to all connectors)
    1366             :          */
    1367           0 :         prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
    1368             :                                    DRM_MODE_PROP_IMMUTABLE,
    1369             :                                    "EDID", 0);
    1370           0 :         if (!prop)
    1371           0 :                 return -ENOMEM;
    1372           0 :         dev->mode_config.edid_property = prop;
    1373             : 
    1374           0 :         prop = drm_property_create_enum(dev, 0,
    1375             :                                    "DPMS", drm_dpms_enum_list,
    1376             :                                    ARRAY_SIZE(drm_dpms_enum_list));
    1377           0 :         if (!prop)
    1378           0 :                 return -ENOMEM;
    1379           0 :         dev->mode_config.dpms_property = prop;
    1380             : 
    1381           0 :         prop = drm_property_create(dev,
    1382             :                                    DRM_MODE_PROP_BLOB |
    1383             :                                    DRM_MODE_PROP_IMMUTABLE,
    1384             :                                    "PATH", 0);
    1385           0 :         if (!prop)
    1386           0 :                 return -ENOMEM;
    1387           0 :         dev->mode_config.path_property = prop;
    1388             : 
    1389           0 :         prop = drm_property_create(dev,
    1390             :                                    DRM_MODE_PROP_BLOB |
    1391             :                                    DRM_MODE_PROP_IMMUTABLE,
    1392             :                                    "TILE", 0);
    1393           0 :         if (!prop)
    1394           0 :                 return -ENOMEM;
    1395           0 :         dev->mode_config.tile_property = prop;
    1396             : 
    1397           0 :         prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
    1398             :                                         "type", drm_plane_type_enum_list,
    1399             :                                         ARRAY_SIZE(drm_plane_type_enum_list));
    1400           0 :         if (!prop)
    1401           0 :                 return -ENOMEM;
    1402           0 :         dev->mode_config.plane_type_property = prop;
    1403             : 
    1404           0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
    1405             :                         "SRC_X", 0, UINT_MAX);
    1406           0 :         if (!prop)
    1407           0 :                 return -ENOMEM;
    1408           0 :         dev->mode_config.prop_src_x = prop;
    1409             : 
    1410           0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
    1411             :                         "SRC_Y", 0, UINT_MAX);
    1412           0 :         if (!prop)
    1413           0 :                 return -ENOMEM;
    1414           0 :         dev->mode_config.prop_src_y = prop;
    1415             : 
    1416           0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
    1417             :                         "SRC_W", 0, UINT_MAX);
    1418           0 :         if (!prop)
    1419           0 :                 return -ENOMEM;
    1420           0 :         dev->mode_config.prop_src_w = prop;
    1421             : 
    1422           0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
    1423             :                         "SRC_H", 0, UINT_MAX);
    1424           0 :         if (!prop)
    1425           0 :                 return -ENOMEM;
    1426           0 :         dev->mode_config.prop_src_h = prop;
    1427             : 
    1428           0 :         prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
    1429             :                         "CRTC_X", INT_MIN, INT_MAX);
    1430           0 :         if (!prop)
    1431           0 :                 return -ENOMEM;
    1432           0 :         dev->mode_config.prop_crtc_x = prop;
    1433             : 
    1434           0 :         prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
    1435             :                         "CRTC_Y", INT_MIN, INT_MAX);
    1436           0 :         if (!prop)
    1437           0 :                 return -ENOMEM;
    1438           0 :         dev->mode_config.prop_crtc_y = prop;
    1439             : 
    1440           0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
    1441             :                         "CRTC_W", 0, INT_MAX);
    1442           0 :         if (!prop)
    1443           0 :                 return -ENOMEM;
    1444           0 :         dev->mode_config.prop_crtc_w = prop;
    1445             : 
    1446           0 :         prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
    1447             :                         "CRTC_H", 0, INT_MAX);
    1448           0 :         if (!prop)
    1449           0 :                 return -ENOMEM;
    1450           0 :         dev->mode_config.prop_crtc_h = prop;
    1451             : 
    1452           0 :         prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
    1453             :                         "FB_ID", DRM_MODE_OBJECT_FB);
    1454           0 :         if (!prop)
    1455           0 :                 return -ENOMEM;
    1456           0 :         dev->mode_config.prop_fb_id = prop;
    1457             : 
    1458           0 :         prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
    1459             :                         "CRTC_ID", DRM_MODE_OBJECT_CRTC);
    1460           0 :         if (!prop)
    1461           0 :                 return -ENOMEM;
    1462           0 :         dev->mode_config.prop_crtc_id = prop;
    1463             : 
    1464           0 :         prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
    1465             :                         "ACTIVE");
    1466           0 :         if (!prop)
    1467           0 :                 return -ENOMEM;
    1468           0 :         dev->mode_config.prop_active = prop;
    1469             : 
    1470           0 :         prop = drm_property_create(dev,
    1471             :                         DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
    1472             :                         "MODE_ID", 0);
    1473           0 :         if (!prop)
    1474           0 :                 return -ENOMEM;
    1475           0 :         dev->mode_config.prop_mode_id = prop;
    1476             : 
    1477           0 :         return 0;
    1478           0 : }
    1479             : 
    1480             : /**
    1481             :  * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
    1482             :  * @dev: DRM device
    1483             :  *
    1484             :  * Called by a driver the first time a DVI-I connector is made.
    1485             :  */
    1486           0 : int drm_mode_create_dvi_i_properties(struct drm_device *dev)
    1487             : {
    1488             :         struct drm_property *dvi_i_selector;
    1489             :         struct drm_property *dvi_i_subconnector;
    1490             : 
    1491           0 :         if (dev->mode_config.dvi_i_select_subconnector_property)
    1492           0 :                 return 0;
    1493             : 
    1494             :         dvi_i_selector =
    1495           0 :                 drm_property_create_enum(dev, 0,
    1496             :                                     "select subconnector",
    1497             :                                     drm_dvi_i_select_enum_list,
    1498             :                                     ARRAY_SIZE(drm_dvi_i_select_enum_list));
    1499           0 :         dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
    1500             : 
    1501           0 :         dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
    1502             :                                     "subconnector",
    1503             :                                     drm_dvi_i_subconnector_enum_list,
    1504             :                                     ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
    1505           0 :         dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
    1506             : 
    1507           0 :         return 0;
    1508           0 : }
    1509             : EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
    1510             : 
    1511             : /**
    1512             :  * drm_create_tv_properties - create TV specific connector properties
    1513             :  * @dev: DRM device
    1514             :  * @num_modes: number of different TV formats (modes) supported
    1515             :  * @modes: array of pointers to strings containing name of each format
    1516             :  *
    1517             :  * Called by a driver's TV initialization routine, this function creates
    1518             :  * the TV specific connector properties for a given device.  Caller is
    1519             :  * responsible for allocating a list of format names and passing them to
    1520             :  * this routine.
    1521             :  */
    1522           0 : int drm_mode_create_tv_properties(struct drm_device *dev,
    1523             :                                   unsigned int num_modes,
    1524             :                                   const char * const modes[])
    1525             : {
    1526             :         struct drm_property *tv_selector;
    1527             :         struct drm_property *tv_subconnector;
    1528             :         unsigned int i;
    1529             : 
    1530           0 :         if (dev->mode_config.tv_select_subconnector_property)
    1531           0 :                 return 0;
    1532             : 
    1533             :         /*
    1534             :          * Basic connector properties
    1535             :          */
    1536           0 :         tv_selector = drm_property_create_enum(dev, 0,
    1537             :                                           "select subconnector",
    1538             :                                           drm_tv_select_enum_list,
    1539             :                                           ARRAY_SIZE(drm_tv_select_enum_list));
    1540           0 :         if (!tv_selector)
    1541             :                 goto nomem;
    1542             : 
    1543           0 :         dev->mode_config.tv_select_subconnector_property = tv_selector;
    1544             : 
    1545             :         tv_subconnector =
    1546           0 :                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
    1547             :                                     "subconnector",
    1548             :                                     drm_tv_subconnector_enum_list,
    1549             :                                     ARRAY_SIZE(drm_tv_subconnector_enum_list));
    1550           0 :         if (!tv_subconnector)
    1551             :                 goto nomem;
    1552           0 :         dev->mode_config.tv_subconnector_property = tv_subconnector;
    1553             : 
    1554             :         /*
    1555             :          * Other, TV specific properties: margins & TV modes.
    1556             :          */
    1557           0 :         dev->mode_config.tv_left_margin_property =
    1558           0 :                 drm_property_create_range(dev, 0, "left margin", 0, 100);
    1559           0 :         if (!dev->mode_config.tv_left_margin_property)
    1560             :                 goto nomem;
    1561             : 
    1562           0 :         dev->mode_config.tv_right_margin_property =
    1563           0 :                 drm_property_create_range(dev, 0, "right margin", 0, 100);
    1564           0 :         if (!dev->mode_config.tv_right_margin_property)
    1565             :                 goto nomem;
    1566             : 
    1567           0 :         dev->mode_config.tv_top_margin_property =
    1568           0 :                 drm_property_create_range(dev, 0, "top margin", 0, 100);
    1569           0 :         if (!dev->mode_config.tv_top_margin_property)
    1570             :                 goto nomem;
    1571             : 
    1572           0 :         dev->mode_config.tv_bottom_margin_property =
    1573           0 :                 drm_property_create_range(dev, 0, "bottom margin", 0, 100);
    1574           0 :         if (!dev->mode_config.tv_bottom_margin_property)
    1575             :                 goto nomem;
    1576             : 
    1577           0 :         dev->mode_config.tv_mode_property =
    1578           0 :                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
    1579             :                                     "mode", num_modes);
    1580           0 :         if (!dev->mode_config.tv_mode_property)
    1581             :                 goto nomem;
    1582             : 
    1583           0 :         for (i = 0; i < num_modes; i++)
    1584           0 :                 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
    1585           0 :                                       i, modes[i]);
    1586             : 
    1587           0 :         dev->mode_config.tv_brightness_property =
    1588           0 :                 drm_property_create_range(dev, 0, "brightness", 0, 100);
    1589           0 :         if (!dev->mode_config.tv_brightness_property)
    1590             :                 goto nomem;
    1591             : 
    1592           0 :         dev->mode_config.tv_contrast_property =
    1593           0 :                 drm_property_create_range(dev, 0, "contrast", 0, 100);
    1594           0 :         if (!dev->mode_config.tv_contrast_property)
    1595             :                 goto nomem;
    1596             : 
    1597           0 :         dev->mode_config.tv_flicker_reduction_property =
    1598           0 :                 drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
    1599           0 :         if (!dev->mode_config.tv_flicker_reduction_property)
    1600             :                 goto nomem;
    1601             : 
    1602           0 :         dev->mode_config.tv_overscan_property =
    1603           0 :                 drm_property_create_range(dev, 0, "overscan", 0, 100);
    1604           0 :         if (!dev->mode_config.tv_overscan_property)
    1605             :                 goto nomem;
    1606             : 
    1607           0 :         dev->mode_config.tv_saturation_property =
    1608           0 :                 drm_property_create_range(dev, 0, "saturation", 0, 100);
    1609           0 :         if (!dev->mode_config.tv_saturation_property)
    1610             :                 goto nomem;
    1611             : 
    1612           0 :         dev->mode_config.tv_hue_property =
    1613           0 :                 drm_property_create_range(dev, 0, "hue", 0, 100);
    1614           0 :         if (!dev->mode_config.tv_hue_property)
    1615             :                 goto nomem;
    1616             : 
    1617           0 :         return 0;
    1618             : nomem:
    1619           0 :         return -ENOMEM;
    1620           0 : }
    1621             : EXPORT_SYMBOL(drm_mode_create_tv_properties);
    1622             : 
    1623             : /**
    1624             :  * drm_mode_create_scaling_mode_property - create scaling mode property
    1625             :  * @dev: DRM device
    1626             :  *
    1627             :  * Called by a driver the first time it's needed, must be attached to desired
    1628             :  * connectors.
    1629             :  */
    1630           0 : int drm_mode_create_scaling_mode_property(struct drm_device *dev)
    1631             : {
    1632             :         struct drm_property *scaling_mode;
    1633             : 
    1634           0 :         if (dev->mode_config.scaling_mode_property)
    1635           0 :                 return 0;
    1636             : 
    1637             :         scaling_mode =
    1638           0 :                 drm_property_create_enum(dev, 0, "scaling mode",
    1639             :                                 drm_scaling_mode_enum_list,
    1640             :                                     ARRAY_SIZE(drm_scaling_mode_enum_list));
    1641             : 
    1642           0 :         dev->mode_config.scaling_mode_property = scaling_mode;
    1643             : 
    1644           0 :         return 0;
    1645           0 : }
    1646             : EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
    1647             : 
    1648             : /**
    1649             :  * drm_mode_create_aspect_ratio_property - create aspect ratio property
    1650             :  * @dev: DRM device
    1651             :  *
    1652             :  * Called by a driver the first time it's needed, must be attached to desired
    1653             :  * connectors.
    1654             :  *
    1655             :  * Returns:
    1656             :  * Zero on success, negative errno on failure.
    1657             :  */
    1658           0 : int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
    1659             : {
    1660           0 :         if (dev->mode_config.aspect_ratio_property)
    1661           0 :                 return 0;
    1662             : 
    1663           0 :         dev->mode_config.aspect_ratio_property =
    1664           0 :                 drm_property_create_enum(dev, 0, "aspect ratio",
    1665             :                                 drm_aspect_ratio_enum_list,
    1666             :                                 ARRAY_SIZE(drm_aspect_ratio_enum_list));
    1667             : 
    1668           0 :         if (dev->mode_config.aspect_ratio_property == NULL)
    1669           0 :                 return -ENOMEM;
    1670             : 
    1671           0 :         return 0;
    1672           0 : }
    1673             : EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
    1674             : 
    1675             : /**
    1676             :  * drm_mode_create_dirty_property - create dirty property
    1677             :  * @dev: DRM device
    1678             :  *
    1679             :  * Called by a driver the first time it's needed, must be attached to desired
    1680             :  * connectors.
    1681             :  */
    1682           0 : int drm_mode_create_dirty_info_property(struct drm_device *dev)
    1683             : {
    1684             :         struct drm_property *dirty_info;
    1685             : 
    1686           0 :         if (dev->mode_config.dirty_info_property)
    1687           0 :                 return 0;
    1688             : 
    1689             :         dirty_info =
    1690           0 :                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
    1691             :                                     "dirty",
    1692             :                                     drm_dirty_info_enum_list,
    1693             :                                     ARRAY_SIZE(drm_dirty_info_enum_list));
    1694           0 :         dev->mode_config.dirty_info_property = dirty_info;
    1695             : 
    1696           0 :         return 0;
    1697           0 : }
    1698             : EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
    1699             : 
    1700             : /**
    1701             :  * drm_mode_create_suggested_offset_properties - create suggests offset properties
    1702             :  * @dev: DRM device
    1703             :  *
    1704             :  * Create the the suggested x/y offset property for connectors.
    1705             :  */
    1706           0 : int drm_mode_create_suggested_offset_properties(struct drm_device *dev)
    1707             : {
    1708           0 :         if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property)
    1709           0 :                 return 0;
    1710             : 
    1711           0 :         dev->mode_config.suggested_x_property =
    1712           0 :                 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff);
    1713             : 
    1714           0 :         dev->mode_config.suggested_y_property =
    1715           0 :                 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff);
    1716             : 
    1717           0 :         if (dev->mode_config.suggested_x_property == NULL ||
    1718           0 :             dev->mode_config.suggested_y_property == NULL)
    1719           0 :                 return -ENOMEM;
    1720           0 :         return 0;
    1721           0 : }
    1722             : EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
    1723             : 
    1724             : /**
    1725             :  * drm_mode_getresources - get graphics configuration
    1726             :  * @dev: drm device for the ioctl
    1727             :  * @data: data pointer for the ioctl
    1728             :  * @file_priv: drm file for the ioctl call
    1729             :  *
    1730             :  * Construct a set of configuration description structures and return
    1731             :  * them to the user, including CRTC, connector and framebuffer configuration.
    1732             :  *
    1733             :  * Called by the user via ioctl.
    1734             :  *
    1735             :  * Returns:
    1736             :  * Zero on success, negative errno on failure.
    1737             :  */
    1738           0 : int drm_mode_getresources(struct drm_device *dev, void *data,
    1739             :                           struct drm_file *file_priv)
    1740             : {
    1741           0 :         struct drm_mode_card_res *card_res = data;
    1742             :         struct list_head *lh;
    1743             :         struct drm_framebuffer *fb;
    1744             :         struct drm_connector *connector;
    1745             :         struct drm_crtc *crtc;
    1746             :         struct drm_encoder *encoder;
    1747             :         int ret = 0;
    1748             :         int connector_count = 0;
    1749             :         int crtc_count = 0;
    1750             :         int fb_count = 0;
    1751             :         int encoder_count = 0;
    1752             :         int copied = 0;
    1753             :         uint32_t __user *fb_id;
    1754             :         uint32_t __user *crtc_id;
    1755             :         uint32_t __user *connector_id;
    1756             :         uint32_t __user *encoder_id;
    1757             : 
    1758           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    1759           0 :                 return -EINVAL;
    1760             : 
    1761             : 
    1762           0 :         mutex_lock(&file_priv->fbs_lock);
    1763             :         /*
    1764             :          * For the non-control nodes we need to limit the list of resources
    1765             :          * by IDs in the group list for this node
    1766             :          */
    1767           0 :         list_for_each(lh, &file_priv->fbs)
    1768           0 :                 fb_count++;
    1769             : 
    1770             :         /* handle this in 4 parts */
    1771             :         /* FBs */
    1772           0 :         if (card_res->count_fbs >= fb_count) {
    1773             :                 copied = 0;
    1774           0 :                 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
    1775           0 :                 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
    1776           0 :                         if (put_user(fb->base.id, fb_id + copied)) {
    1777           0 :                                 mutex_unlock(&file_priv->fbs_lock);
    1778           0 :                                 return -EFAULT;
    1779             :                         }
    1780           0 :                         copied++;
    1781             :                 }
    1782             :         }
    1783           0 :         card_res->count_fbs = fb_count;
    1784           0 :         mutex_unlock(&file_priv->fbs_lock);
    1785             : 
    1786             :         /* mode_config.mutex protects the connector list against e.g. DP MST
    1787             :          * connector hot-adding. CRTC/Plane lists are invariant. */
    1788           0 :         mutex_lock(&dev->mode_config.mutex);
    1789           0 :         drm_for_each_crtc(crtc, dev)
    1790           0 :                 crtc_count++;
    1791             : 
    1792           0 :         drm_for_each_connector(connector, dev)
    1793           0 :                 connector_count++;
    1794             : 
    1795           0 :         drm_for_each_encoder(encoder, dev)
    1796           0 :                 encoder_count++;
    1797             : 
    1798           0 :         card_res->max_height = dev->mode_config.max_height;
    1799           0 :         card_res->min_height = dev->mode_config.min_height;
    1800           0 :         card_res->max_width = dev->mode_config.max_width;
    1801           0 :         card_res->min_width = dev->mode_config.min_width;
    1802             : 
    1803             :         /* CRTCs */
    1804           0 :         if (card_res->count_crtcs >= crtc_count) {
    1805             :                 copied = 0;
    1806           0 :                 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
    1807           0 :                 drm_for_each_crtc(crtc, dev) {
    1808             :                         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
    1809           0 :                         if (put_user(crtc->base.id, crtc_id + copied)) {
    1810             :                                 ret = -EFAULT;
    1811           0 :                                 goto out;
    1812             :                         }
    1813           0 :                         copied++;
    1814             :                 }
    1815             :         }
    1816           0 :         card_res->count_crtcs = crtc_count;
    1817             : 
    1818             :         /* Encoders */
    1819           0 :         if (card_res->count_encoders >= encoder_count) {
    1820             :                 copied = 0;
    1821           0 :                 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
    1822           0 :                 drm_for_each_encoder(encoder, dev) {
    1823             :                         DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
    1824             :                                         encoder->name);
    1825           0 :                         if (put_user(encoder->base.id, encoder_id +
    1826             :                                      copied)) {
    1827             :                                 ret = -EFAULT;
    1828           0 :                                 goto out;
    1829             :                         }
    1830           0 :                         copied++;
    1831             :                 }
    1832             :         }
    1833           0 :         card_res->count_encoders = encoder_count;
    1834             : 
    1835             :         /* Connectors */
    1836           0 :         if (card_res->count_connectors >= connector_count) {
    1837             :                 copied = 0;
    1838           0 :                 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
    1839           0 :                 drm_for_each_connector(connector, dev) {
    1840             :                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
    1841             :                                 connector->base.id,
    1842             :                                 connector->name);
    1843           0 :                         if (put_user(connector->base.id,
    1844             :                                      connector_id + copied)) {
    1845             :                                 ret = -EFAULT;
    1846           0 :                                 goto out;
    1847             :                         }
    1848           0 :                         copied++;
    1849             :                 }
    1850             :         }
    1851           0 :         card_res->count_connectors = connector_count;
    1852             : 
    1853           0 :         DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
    1854             :                   card_res->count_connectors, card_res->count_encoders);
    1855             : 
    1856             : out:
    1857           0 :         mutex_unlock(&dev->mode_config.mutex);
    1858           0 :         return ret;
    1859           0 : }
    1860             : 
    1861             : /**
    1862             :  * drm_mode_getcrtc - get CRTC configuration
    1863             :  * @dev: drm device for the ioctl
    1864             :  * @data: data pointer for the ioctl
    1865             :  * @file_priv: drm file for the ioctl call
    1866             :  *
    1867             :  * Construct a CRTC configuration structure to return to the user.
    1868             :  *
    1869             :  * Called by the user via ioctl.
    1870             :  *
    1871             :  * Returns:
    1872             :  * Zero on success, negative errno on failure.
    1873             :  */
    1874           0 : int drm_mode_getcrtc(struct drm_device *dev,
    1875             :                      void *data, struct drm_file *file_priv)
    1876             : {
    1877           0 :         struct drm_mode_crtc *crtc_resp = data;
    1878             :         struct drm_crtc *crtc;
    1879             : 
    1880           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    1881           0 :                 return -EINVAL;
    1882             : 
    1883           0 :         crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
    1884           0 :         if (!crtc)
    1885           0 :                 return -ENOENT;
    1886             : 
    1887           0 :         drm_modeset_lock_crtc(crtc, crtc->primary);
    1888           0 :         crtc_resp->gamma_size = crtc->gamma_size;
    1889           0 :         if (crtc->primary->fb)
    1890           0 :                 crtc_resp->fb_id = crtc->primary->fb->base.id;
    1891             :         else
    1892           0 :                 crtc_resp->fb_id = 0;
    1893             : 
    1894           0 :         if (crtc->state) {
    1895           0 :                 crtc_resp->x = crtc->primary->state->src_x >> 16;
    1896           0 :                 crtc_resp->y = crtc->primary->state->src_y >> 16;
    1897           0 :                 if (crtc->state->enable) {
    1898           0 :                         drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
    1899           0 :                         crtc_resp->mode_valid = 1;
    1900             : 
    1901           0 :                 } else {
    1902           0 :                         crtc_resp->mode_valid = 0;
    1903             :                 }
    1904             :         } else {
    1905           0 :                 crtc_resp->x = crtc->x;
    1906           0 :                 crtc_resp->y = crtc->y;
    1907           0 :                 if (crtc->enabled) {
    1908           0 :                         drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
    1909           0 :                         crtc_resp->mode_valid = 1;
    1910             : 
    1911           0 :                 } else {
    1912           0 :                         crtc_resp->mode_valid = 0;
    1913             :                 }
    1914             :         }
    1915           0 :         drm_modeset_unlock_crtc(crtc);
    1916             : 
    1917           0 :         return 0;
    1918           0 : }
    1919             : 
    1920           0 : static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
    1921             :                                          const struct drm_file *file_priv)
    1922             : {
    1923             :         /*
    1924             :          * If user-space hasn't configured the driver to expose the stereo 3D
    1925             :          * modes, don't expose them.
    1926             :          */
    1927           0 :         if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode))
    1928           0 :                 return false;
    1929             : 
    1930           0 :         return true;
    1931           0 : }
    1932             : 
    1933           0 : static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)
    1934             : {
    1935             :         /* For atomic drivers only state objects are synchronously updated and
    1936             :          * protected by modeset locks, so check those first. */
    1937           0 :         if (connector->state)
    1938           0 :                 return connector->state->best_encoder;
    1939           0 :         return connector->encoder;
    1940           0 : }
    1941             : 
    1942             : /* helper for getconnector and getproperties ioctls */
    1943           0 : static int get_properties(struct drm_mode_object *obj, bool atomic,
    1944             :                 uint32_t __user *prop_ptr, uint64_t __user *prop_values,
    1945             :                 uint32_t *arg_count_props)
    1946             : {
    1947             :         int props_count;
    1948             :         int i, ret, copied;
    1949             : 
    1950           0 :         props_count = obj->properties->count;
    1951           0 :         if (!atomic)
    1952           0 :                 props_count -= obj->properties->atomic_count;
    1953             : 
    1954           0 :         if ((*arg_count_props >= props_count) && props_count) {
    1955           0 :                 for (i = 0, copied = 0; copied < props_count; i++) {
    1956           0 :                         struct drm_property *prop = obj->properties->properties[i];
    1957           0 :                         uint64_t val;
    1958             : 
    1959           0 :                         if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
    1960           0 :                                 continue;
    1961             : 
    1962           0 :                         ret = drm_object_property_get_value(obj, prop, &val);
    1963           0 :                         if (ret)
    1964           0 :                                 return ret;
    1965             : 
    1966           0 :                         if (put_user(prop->base.id, prop_ptr + copied))
    1967           0 :                                 return -EFAULT;
    1968             : 
    1969           0 :                         if (put_user(val, prop_values + copied))
    1970           0 :                                 return -EFAULT;
    1971             : 
    1972           0 :                         copied++;
    1973           0 :                 }
    1974             :         }
    1975           0 :         *arg_count_props = props_count;
    1976             : 
    1977           0 :         return 0;
    1978           0 : }
    1979             : 
    1980             : /**
    1981             :  * drm_mode_getconnector - get connector configuration
    1982             :  * @dev: drm device for the ioctl
    1983             :  * @data: data pointer for the ioctl
    1984             :  * @file_priv: drm file for the ioctl call
    1985             :  *
    1986             :  * Construct a connector configuration structure to return to the user.
    1987             :  *
    1988             :  * Called by the user via ioctl.
    1989             :  *
    1990             :  * Returns:
    1991             :  * Zero on success, negative errno on failure.
    1992             :  */
    1993           0 : int drm_mode_getconnector(struct drm_device *dev, void *data,
    1994             :                           struct drm_file *file_priv)
    1995             : {
    1996           0 :         struct drm_mode_get_connector *out_resp = data;
    1997             :         struct drm_connector *connector;
    1998             :         struct drm_encoder *encoder;
    1999             :         struct drm_display_mode *mode;
    2000             :         int mode_count = 0;
    2001             :         int encoders_count = 0;
    2002             :         int ret = 0;
    2003             :         int copied = 0;
    2004             :         int i;
    2005           0 :         struct drm_mode_modeinfo u_mode;
    2006             :         struct drm_mode_modeinfo __user *mode_ptr;
    2007             :         uint32_t __user *encoder_ptr;
    2008             : 
    2009           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    2010           0 :                 return -EINVAL;
    2011             : 
    2012           0 :         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
    2013             : 
    2014             :         DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
    2015             : 
    2016           0 :         mutex_lock(&dev->mode_config.mutex);
    2017             : 
    2018           0 :         connector = drm_connector_find(dev, out_resp->connector_id);
    2019           0 :         if (!connector) {
    2020             :                 ret = -ENOENT;
    2021           0 :                 goto out_unlock;
    2022             :         }
    2023             : 
    2024           0 :         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
    2025           0 :                 if (connector->encoder_ids[i] != 0)
    2026           0 :                         encoders_count++;
    2027             : 
    2028           0 :         if (out_resp->count_modes == 0) {
    2029           0 :                 connector->funcs->fill_modes(connector,
    2030           0 :                                              dev->mode_config.max_width,
    2031           0 :                                              dev->mode_config.max_height);
    2032           0 :         }
    2033             : 
    2034             :         /* delayed so we get modes regardless of pre-fill_modes state */
    2035           0 :         list_for_each_entry(mode, &connector->modes, head)
    2036           0 :                 if (drm_mode_expose_to_userspace(mode, file_priv))
    2037           0 :                         mode_count++;
    2038             : 
    2039           0 :         out_resp->connector_id = connector->base.id;
    2040           0 :         out_resp->connector_type = connector->connector_type;
    2041           0 :         out_resp->connector_type_id = connector->connector_type_id;
    2042           0 :         out_resp->mm_width = connector->display_info.width_mm;
    2043           0 :         out_resp->mm_height = connector->display_info.height_mm;
    2044           0 :         out_resp->subpixel = connector->display_info.subpixel_order;
    2045           0 :         out_resp->connection = connector->status;
    2046             : 
    2047           0 :         drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
    2048           0 :         encoder = drm_connector_get_encoder(connector);
    2049           0 :         if (encoder)
    2050           0 :                 out_resp->encoder_id = encoder->base.id;
    2051             :         else
    2052           0 :                 out_resp->encoder_id = 0;
    2053             : 
    2054             :         /*
    2055             :          * This ioctl is called twice, once to determine how much space is
    2056             :          * needed, and the 2nd time to fill it.
    2057             :          */
    2058           0 :         if ((out_resp->count_modes >= mode_count) && mode_count) {
    2059             :                 copied = 0;
    2060           0 :                 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
    2061           0 :                 list_for_each_entry(mode, &connector->modes, head) {
    2062           0 :                         if (!drm_mode_expose_to_userspace(mode, file_priv))
    2063             :                                 continue;
    2064             : 
    2065           0 :                         drm_mode_convert_to_umode(&u_mode, mode);
    2066           0 :                         if (copy_to_user(mode_ptr + copied,
    2067             :                                          &u_mode, sizeof(u_mode))) {
    2068             :                                 ret = -EFAULT;
    2069           0 :                                 goto out;
    2070             :                         }
    2071           0 :                         copied++;
    2072           0 :                 }
    2073             :         }
    2074           0 :         out_resp->count_modes = mode_count;
    2075             : 
    2076           0 :         ret = get_properties(&connector->base, file_priv->atomic,
    2077           0 :                         (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
    2078           0 :                         (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
    2079           0 :                         &out_resp->count_props);
    2080           0 :         if (ret)
    2081             :                 goto out;
    2082             : 
    2083           0 :         if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
    2084             :                 copied = 0;
    2085           0 :                 encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
    2086           0 :                 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
    2087           0 :                         if (connector->encoder_ids[i] != 0) {
    2088           0 :                                 if (put_user(connector->encoder_ids[i],
    2089             :                                              encoder_ptr + copied)) {
    2090             :                                         ret = -EFAULT;
    2091           0 :                                         goto out;
    2092             :                                 }
    2093           0 :                                 copied++;
    2094           0 :                         }
    2095             :                 }
    2096             :         }
    2097           0 :         out_resp->count_encoders = encoders_count;
    2098             : 
    2099             : out:
    2100           0 :         drm_modeset_unlock(&dev->mode_config.connection_mutex);
    2101             : 
    2102             : out_unlock:
    2103           0 :         mutex_unlock(&dev->mode_config.mutex);
    2104             : 
    2105           0 :         return ret;
    2106           0 : }
    2107             : 
    2108           0 : static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
    2109             : {
    2110             :         struct drm_connector *connector;
    2111           0 :         struct drm_device *dev = encoder->dev;
    2112             :         bool uses_atomic = false;
    2113             : 
    2114             :         /* For atomic drivers only state objects are synchronously updated and
    2115             :          * protected by modeset locks, so check those first. */
    2116           0 :         drm_for_each_connector(connector, dev) {
    2117           0 :                 if (!connector->state)
    2118             :                         continue;
    2119             : 
    2120             :                 uses_atomic = true;
    2121             : 
    2122           0 :                 if (connector->state->best_encoder != encoder)
    2123             :                         continue;
    2124             : 
    2125           0 :                 return connector->state->crtc;
    2126             :         }
    2127             : 
    2128             :         /* Don't return stale data (e.g. pending async disable). */
    2129           0 :         if (uses_atomic)
    2130           0 :                 return NULL;
    2131             : 
    2132           0 :         return encoder->crtc;
    2133           0 : }
    2134             : 
    2135             : /**
    2136             :  * drm_mode_getencoder - get encoder configuration
    2137             :  * @dev: drm device for the ioctl
    2138             :  * @data: data pointer for the ioctl
    2139             :  * @file_priv: drm file for the ioctl call
    2140             :  *
    2141             :  * Construct a encoder configuration structure to return to the user.
    2142             :  *
    2143             :  * Called by the user via ioctl.
    2144             :  *
    2145             :  * Returns:
    2146             :  * Zero on success, negative errno on failure.
    2147             :  */
    2148           0 : int drm_mode_getencoder(struct drm_device *dev, void *data,
    2149             :                         struct drm_file *file_priv)
    2150             : {
    2151           0 :         struct drm_mode_get_encoder *enc_resp = data;
    2152             :         struct drm_encoder *encoder;
    2153             :         struct drm_crtc *crtc;
    2154             : 
    2155           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    2156           0 :                 return -EINVAL;
    2157             : 
    2158           0 :         encoder = drm_encoder_find(dev, enc_resp->encoder_id);
    2159           0 :         if (!encoder)
    2160           0 :                 return -ENOENT;
    2161             : 
    2162           0 :         drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
    2163           0 :         crtc = drm_encoder_get_crtc(encoder);
    2164           0 :         if (crtc)
    2165           0 :                 enc_resp->crtc_id = crtc->base.id;
    2166             :         else
    2167           0 :                 enc_resp->crtc_id = 0;
    2168           0 :         drm_modeset_unlock(&dev->mode_config.connection_mutex);
    2169             : 
    2170           0 :         enc_resp->encoder_type = encoder->encoder_type;
    2171           0 :         enc_resp->encoder_id = encoder->base.id;
    2172           0 :         enc_resp->possible_crtcs = encoder->possible_crtcs;
    2173           0 :         enc_resp->possible_clones = encoder->possible_clones;
    2174             : 
    2175           0 :         return 0;
    2176           0 : }
    2177             : 
    2178             : /**
    2179             :  * drm_mode_getplane_res - enumerate all plane resources
    2180             :  * @dev: DRM device
    2181             :  * @data: ioctl data
    2182             :  * @file_priv: DRM file info
    2183             :  *
    2184             :  * Construct a list of plane ids to return to the user.
    2185             :  *
    2186             :  * Called by the user via ioctl.
    2187             :  *
    2188             :  * Returns:
    2189             :  * Zero on success, negative errno on failure.
    2190             :  */
    2191           0 : int drm_mode_getplane_res(struct drm_device *dev, void *data,
    2192             :                           struct drm_file *file_priv)
    2193             : {
    2194           0 :         struct drm_mode_get_plane_res *plane_resp = data;
    2195             :         struct drm_mode_config *config;
    2196             :         struct drm_plane *plane;
    2197             :         uint32_t __user *plane_ptr;
    2198             :         int copied = 0;
    2199             :         unsigned num_planes;
    2200             : 
    2201           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    2202           0 :                 return -EINVAL;
    2203             : 
    2204           0 :         config = &dev->mode_config;
    2205             : 
    2206           0 :         if (file_priv->universal_planes)
    2207           0 :                 num_planes = config->num_total_plane;
    2208             :         else
    2209           0 :                 num_planes = config->num_overlay_plane;
    2210             : 
    2211             :         /*
    2212             :          * This ioctl is called twice, once to determine how much space is
    2213             :          * needed, and the 2nd time to fill it.
    2214             :          */
    2215           0 :         if (num_planes &&
    2216           0 :             (plane_resp->count_planes >= num_planes)) {
    2217           0 :                 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
    2218             : 
    2219             :                 /* Plane lists are invariant, no locking needed. */
    2220           0 :                 drm_for_each_plane(plane, dev) {
    2221             :                         /*
    2222             :                          * Unless userspace set the 'universal planes'
    2223             :                          * capability bit, only advertise overlays.
    2224             :                          */
    2225           0 :                         if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
    2226           0 :                             !file_priv->universal_planes)
    2227             :                                 continue;
    2228             : 
    2229           0 :                         if (put_user(plane->base.id, plane_ptr + copied))
    2230           0 :                                 return -EFAULT;
    2231           0 :                         copied++;
    2232           0 :                 }
    2233             :         }
    2234           0 :         plane_resp->count_planes = num_planes;
    2235             : 
    2236           0 :         return 0;
    2237           0 : }
    2238             : 
    2239             : /**
    2240             :  * drm_mode_getplane - get plane configuration
    2241             :  * @dev: DRM device
    2242             :  * @data: ioctl data
    2243             :  * @file_priv: DRM file info
    2244             :  *
    2245             :  * Construct a plane configuration structure to return to the user.
    2246             :  *
    2247             :  * Called by the user via ioctl.
    2248             :  *
    2249             :  * Returns:
    2250             :  * Zero on success, negative errno on failure.
    2251             :  */
    2252           0 : int drm_mode_getplane(struct drm_device *dev, void *data,
    2253             :                       struct drm_file *file_priv)
    2254             : {
    2255           0 :         struct drm_mode_get_plane *plane_resp = data;
    2256             :         struct drm_plane *plane;
    2257             :         uint32_t __user *format_ptr;
    2258             : 
    2259           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    2260           0 :                 return -EINVAL;
    2261             : 
    2262           0 :         plane = drm_plane_find(dev, plane_resp->plane_id);
    2263           0 :         if (!plane)
    2264           0 :                 return -ENOENT;
    2265             : 
    2266           0 :         drm_modeset_lock(&plane->mutex, NULL);
    2267           0 :         if (plane->crtc)
    2268           0 :                 plane_resp->crtc_id = plane->crtc->base.id;
    2269             :         else
    2270           0 :                 plane_resp->crtc_id = 0;
    2271             : 
    2272           0 :         if (plane->fb)
    2273           0 :                 plane_resp->fb_id = plane->fb->base.id;
    2274             :         else
    2275           0 :                 plane_resp->fb_id = 0;
    2276           0 :         drm_modeset_unlock(&plane->mutex);
    2277             : 
    2278           0 :         plane_resp->plane_id = plane->base.id;
    2279           0 :         plane_resp->possible_crtcs = plane->possible_crtcs;
    2280           0 :         plane_resp->gamma_size = 0;
    2281             : 
    2282             :         /*
    2283             :          * This ioctl is called twice, once to determine how much space is
    2284             :          * needed, and the 2nd time to fill it.
    2285             :          */
    2286           0 :         if (plane->format_count &&
    2287           0 :             (plane_resp->count_format_types >= plane->format_count)) {
    2288           0 :                 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
    2289           0 :                 if (copy_to_user(format_ptr,
    2290           0 :                                  plane->format_types,
    2291           0 :                                  sizeof(uint32_t) * plane->format_count)) {
    2292           0 :                         return -EFAULT;
    2293             :                 }
    2294             :         }
    2295           0 :         plane_resp->count_format_types = plane->format_count;
    2296             : 
    2297           0 :         return 0;
    2298           0 : }
    2299             : 
    2300             : /**
    2301             :  * drm_plane_check_pixel_format - Check if the plane supports the pixel format
    2302             :  * @plane: plane to check for format support
    2303             :  * @format: the pixel format
    2304             :  *
    2305             :  * Returns:
    2306             :  * Zero of @plane has @format in its list of supported pixel formats, -EINVAL
    2307             :  * otherwise.
    2308             :  */
    2309           0 : int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format)
    2310             : {
    2311             :         unsigned int i;
    2312             : 
    2313           0 :         for (i = 0; i < plane->format_count; i++) {
    2314           0 :                 if (format == plane->format_types[i])
    2315           0 :                         return 0;
    2316             :         }
    2317             : 
    2318           0 :         return -EINVAL;
    2319           0 : }
    2320             : 
    2321           0 : static int check_src_coords(uint32_t src_x, uint32_t src_y,
    2322             :                             uint32_t src_w, uint32_t src_h,
    2323             :                             const struct drm_framebuffer *fb)
    2324             : {
    2325             :         unsigned int fb_width, fb_height;
    2326             : 
    2327           0 :         fb_width = fb->width << 16;
    2328           0 :         fb_height = fb->height << 16;
    2329             : 
    2330             :         /* Make sure source coordinates are inside the fb. */
    2331           0 :         if (src_w > fb_width ||
    2332           0 :             src_x > fb_width - src_w ||
    2333           0 :             src_h > fb_height ||
    2334           0 :             src_y > fb_height - src_h) {
    2335             :                 DRM_DEBUG_KMS("Invalid source coordinates "
    2336             :                               "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
    2337             :                               src_w >> 16, ((src_w & 0xffff) * 15625) >> 10,
    2338             :                               src_h >> 16, ((src_h & 0xffff) * 15625) >> 10,
    2339             :                               src_x >> 16, ((src_x & 0xffff) * 15625) >> 10,
    2340             :                               src_y >> 16, ((src_y & 0xffff) * 15625) >> 10);
    2341           0 :                 return -ENOSPC;
    2342             :         }
    2343             : 
    2344           0 :         return 0;
    2345           0 : }
    2346             : 
    2347             : /*
    2348             :  * setplane_internal - setplane handler for internal callers
    2349             :  *
    2350             :  * Note that we assume an extra reference has already been taken on fb.  If the
    2351             :  * update fails, this reference will be dropped before return; if it succeeds,
    2352             :  * the previous framebuffer (if any) will be unreferenced instead.
    2353             :  *
    2354             :  * src_{x,y,w,h} are provided in 16.16 fixed point format
    2355             :  */
    2356           0 : static int __setplane_internal(struct drm_plane *plane,
    2357             :                                struct drm_crtc *crtc,
    2358             :                                struct drm_framebuffer *fb,
    2359             :                                int32_t crtc_x, int32_t crtc_y,
    2360             :                                uint32_t crtc_w, uint32_t crtc_h,
    2361             :                                /* src_{x,y,w,h} values are 16.16 fixed point */
    2362             :                                uint32_t src_x, uint32_t src_y,
    2363             :                                uint32_t src_w, uint32_t src_h)
    2364             : {
    2365             :         int ret = 0;
    2366             : 
    2367             :         /* No fb means shut it down */
    2368           0 :         if (!fb) {
    2369           0 :                 plane->old_fb = plane->fb;
    2370           0 :                 ret = plane->funcs->disable_plane(plane);
    2371           0 :                 if (!ret) {
    2372           0 :                         plane->crtc = NULL;
    2373           0 :                         plane->fb = NULL;
    2374           0 :                 } else {
    2375           0 :                         plane->old_fb = NULL;
    2376             :                 }
    2377             :                 goto out;
    2378             :         }
    2379             : 
    2380             :         /* Check whether this plane is usable on this CRTC */
    2381           0 :         if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
    2382             :                 DRM_DEBUG_KMS("Invalid crtc for plane\n");
    2383             :                 ret = -EINVAL;
    2384           0 :                 goto out;
    2385             :         }
    2386             : 
    2387             :         /* Check whether this plane supports the fb pixel format. */
    2388           0 :         ret = drm_plane_check_pixel_format(plane, fb->pixel_format);
    2389           0 :         if (ret) {
    2390             :                 DRM_DEBUG_KMS("Invalid pixel format %s\n",
    2391             :                               drm_get_format_name(fb->pixel_format));
    2392             :                 goto out;
    2393             :         }
    2394             : 
    2395             :         /* Give drivers some help against integer overflows */
    2396           0 :         if (crtc_w > INT_MAX ||
    2397           0 :             crtc_x > INT_MAX - (int32_t) crtc_w ||
    2398           0 :             crtc_h > INT_MAX ||
    2399           0 :             crtc_y > INT_MAX - (int32_t) crtc_h) {
    2400             :                 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
    2401             :                               crtc_w, crtc_h, crtc_x, crtc_y);
    2402             :                 ret = -ERANGE;
    2403           0 :                 goto out;
    2404             :         }
    2405             : 
    2406           0 :         ret = check_src_coords(src_x, src_y, src_w, src_h, fb);
    2407           0 :         if (ret)
    2408             :                 goto out;
    2409             : 
    2410           0 :         plane->old_fb = plane->fb;
    2411           0 :         ret = plane->funcs->update_plane(plane, crtc, fb,
    2412             :                                          crtc_x, crtc_y, crtc_w, crtc_h,
    2413             :                                          src_x, src_y, src_w, src_h);
    2414           0 :         if (!ret) {
    2415           0 :                 plane->crtc = crtc;
    2416           0 :                 plane->fb = fb;
    2417             :                 fb = NULL;
    2418           0 :         } else {
    2419           0 :                 plane->old_fb = NULL;
    2420             :         }
    2421             : 
    2422             : out:
    2423           0 :         if (fb)
    2424           0 :                 drm_framebuffer_unreference(fb);
    2425           0 :         if (plane->old_fb)
    2426           0 :                 drm_framebuffer_unreference(plane->old_fb);
    2427           0 :         plane->old_fb = NULL;
    2428             : 
    2429           0 :         return ret;
    2430             : }
    2431             : 
    2432           0 : static int setplane_internal(struct drm_plane *plane,
    2433             :                              struct drm_crtc *crtc,
    2434             :                              struct drm_framebuffer *fb,
    2435             :                              int32_t crtc_x, int32_t crtc_y,
    2436             :                              uint32_t crtc_w, uint32_t crtc_h,
    2437             :                              /* src_{x,y,w,h} values are 16.16 fixed point */
    2438             :                              uint32_t src_x, uint32_t src_y,
    2439             :                              uint32_t src_w, uint32_t src_h)
    2440             : {
    2441             :         int ret;
    2442             : 
    2443           0 :         drm_modeset_lock_all(plane->dev);
    2444           0 :         ret = __setplane_internal(plane, crtc, fb,
    2445             :                                   crtc_x, crtc_y, crtc_w, crtc_h,
    2446             :                                   src_x, src_y, src_w, src_h);
    2447           0 :         drm_modeset_unlock_all(plane->dev);
    2448             : 
    2449           0 :         return ret;
    2450             : }
    2451             : 
    2452             : /**
    2453             :  * drm_mode_setplane - configure a plane's configuration
    2454             :  * @dev: DRM device
    2455             :  * @data: ioctl data*
    2456             :  * @file_priv: DRM file info
    2457             :  *
    2458             :  * Set plane configuration, including placement, fb, scaling, and other factors.
    2459             :  * Or pass a NULL fb to disable (planes may be disabled without providing a
    2460             :  * valid crtc).
    2461             :  *
    2462             :  * Returns:
    2463             :  * Zero on success, negative errno on failure.
    2464             :  */
    2465           0 : int drm_mode_setplane(struct drm_device *dev, void *data,
    2466             :                       struct drm_file *file_priv)
    2467             : {
    2468           0 :         struct drm_mode_set_plane *plane_req = data;
    2469             :         struct drm_plane *plane;
    2470             :         struct drm_crtc *crtc = NULL;
    2471             :         struct drm_framebuffer *fb = NULL;
    2472             : 
    2473           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    2474           0 :                 return -EINVAL;
    2475             : 
    2476             :         /*
    2477             :          * First, find the plane, crtc, and fb objects.  If not available,
    2478             :          * we don't bother to call the driver.
    2479             :          */
    2480           0 :         plane = drm_plane_find(dev, plane_req->plane_id);
    2481           0 :         if (!plane) {
    2482             :                 DRM_DEBUG_KMS("Unknown plane ID %d\n",
    2483             :                               plane_req->plane_id);
    2484           0 :                 return -ENOENT;
    2485             :         }
    2486             : 
    2487           0 :         if (plane_req->fb_id) {
    2488           0 :                 fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
    2489           0 :                 if (!fb) {
    2490             :                         DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
    2491             :                                       plane_req->fb_id);
    2492           0 :                         return -ENOENT;
    2493             :                 }
    2494             : 
    2495           0 :                 crtc = drm_crtc_find(dev, plane_req->crtc_id);
    2496           0 :                 if (!crtc) {
    2497             :                         DRM_DEBUG_KMS("Unknown crtc ID %d\n",
    2498             :                                       plane_req->crtc_id);
    2499           0 :                         return -ENOENT;
    2500             :                 }
    2501             :         }
    2502             : 
    2503             :         /*
    2504             :          * setplane_internal will take care of deref'ing either the old or new
    2505             :          * framebuffer depending on success.
    2506             :          */
    2507           0 :         return setplane_internal(plane, crtc, fb,
    2508           0 :                                  plane_req->crtc_x, plane_req->crtc_y,
    2509           0 :                                  plane_req->crtc_w, plane_req->crtc_h,
    2510           0 :                                  plane_req->src_x, plane_req->src_y,
    2511           0 :                                  plane_req->src_w, plane_req->src_h);
    2512           0 : }
    2513             : 
    2514             : /**
    2515             :  * drm_mode_set_config_internal - helper to call ->set_config
    2516             :  * @set: modeset config to set
    2517             :  *
    2518             :  * This is a little helper to wrap internal calls to the ->set_config driver
    2519             :  * interface. The only thing it adds is correct refcounting dance.
    2520             :  *
    2521             :  * Returns:
    2522             :  * Zero on success, negative errno on failure.
    2523             :  */
    2524           0 : int drm_mode_set_config_internal(struct drm_mode_set *set)
    2525             : {
    2526           0 :         struct drm_crtc *crtc = set->crtc;
    2527             :         struct drm_framebuffer *fb;
    2528             :         struct drm_crtc *tmp;
    2529             :         int ret;
    2530             : 
    2531             :         /*
    2532             :          * NOTE: ->set_config can also disable other crtcs (if we steal all
    2533             :          * connectors from it), hence we need to refcount the fbs across all
    2534             :          * crtcs. Atomic modeset will have saner semantics ...
    2535             :          */
    2536           0 :         drm_for_each_crtc(tmp, crtc->dev)
    2537           0 :                 tmp->primary->old_fb = tmp->primary->fb;
    2538             : 
    2539           0 :         fb = set->fb;
    2540             : 
    2541           0 :         ret = crtc->funcs->set_config(set);
    2542           0 :         if (ret == 0) {
    2543           0 :                 crtc->primary->crtc = crtc;
    2544           0 :                 crtc->primary->fb = fb;
    2545           0 :         }
    2546             : 
    2547           0 :         drm_for_each_crtc(tmp, crtc->dev) {
    2548           0 :                 if (tmp->primary->fb)
    2549           0 :                         drm_framebuffer_reference(tmp->primary->fb);
    2550           0 :                 if (tmp->primary->old_fb)
    2551           0 :                         drm_framebuffer_unreference(tmp->primary->old_fb);
    2552           0 :                 tmp->primary->old_fb = NULL;
    2553             :         }
    2554             : 
    2555           0 :         return ret;
    2556             : }
    2557             : EXPORT_SYMBOL(drm_mode_set_config_internal);
    2558             : 
    2559             : /**
    2560             :  * drm_crtc_get_hv_timing - Fetches hdisplay/vdisplay for given mode
    2561             :  * @mode: mode to query
    2562             :  * @hdisplay: hdisplay value to fill in
    2563             :  * @vdisplay: vdisplay value to fill in
    2564             :  *
    2565             :  * The vdisplay value will be doubled if the specified mode is a stereo mode of
    2566             :  * the appropriate layout.
    2567             :  */
    2568           0 : void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
    2569             :                             int *hdisplay, int *vdisplay)
    2570             : {
    2571           0 :         struct drm_display_mode adjusted;
    2572             : 
    2573           0 :         drm_mode_copy(&adjusted, mode);
    2574           0 :         drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
    2575           0 :         *hdisplay = adjusted.crtc_hdisplay;
    2576           0 :         *vdisplay = adjusted.crtc_vdisplay;
    2577           0 : }
    2578             : EXPORT_SYMBOL(drm_crtc_get_hv_timing);
    2579             : 
    2580             : /**
    2581             :  * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
    2582             :  *     CRTC viewport
    2583             :  * @crtc: CRTC that framebuffer will be displayed on
    2584             :  * @x: x panning
    2585             :  * @y: y panning
    2586             :  * @mode: mode that framebuffer will be displayed under
    2587             :  * @fb: framebuffer to check size of
    2588             :  */
    2589           0 : int drm_crtc_check_viewport(const struct drm_crtc *crtc,
    2590             :                             int x, int y,
    2591             :                             const struct drm_display_mode *mode,
    2592             :                             const struct drm_framebuffer *fb)
    2593             : 
    2594             : {
    2595           0 :         int hdisplay, vdisplay;
    2596             : 
    2597           0 :         drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
    2598             : 
    2599           0 :         if (crtc->state &&
    2600           0 :             crtc->primary->state->rotation & (BIT(DRM_ROTATE_90) |
    2601             :                                               BIT(DRM_ROTATE_270)))
    2602           0 :                 swap(hdisplay, vdisplay);
    2603             : 
    2604           0 :         return check_src_coords(x << 16, y << 16,
    2605           0 :                                 hdisplay << 16, vdisplay << 16, fb);
    2606           0 : }
    2607             : EXPORT_SYMBOL(drm_crtc_check_viewport);
    2608             : 
    2609             : /**
    2610             :  * drm_mode_setcrtc - set CRTC configuration
    2611             :  * @dev: drm device for the ioctl
    2612             :  * @data: data pointer for the ioctl
    2613             :  * @file_priv: drm file for the ioctl call
    2614             :  *
    2615             :  * Build a new CRTC configuration based on user request.
    2616             :  *
    2617             :  * Called by the user via ioctl.
    2618             :  *
    2619             :  * Returns:
    2620             :  * Zero on success, negative errno on failure.
    2621             :  */
    2622           0 : int drm_mode_setcrtc(struct drm_device *dev, void *data,
    2623             :                      struct drm_file *file_priv)
    2624             : {
    2625           0 :         struct drm_mode_config *config = &dev->mode_config;
    2626           0 :         struct drm_mode_crtc *crtc_req = data;
    2627             :         struct drm_crtc *crtc;
    2628             :         struct drm_connector **connector_set = NULL, *connector;
    2629             :         struct drm_framebuffer *fb = NULL;
    2630             :         struct drm_display_mode *mode = NULL;
    2631           0 :         struct drm_mode_set set;
    2632             :         uint32_t __user *set_connectors_ptr;
    2633             :         int ret;
    2634             :         int i;
    2635             : 
    2636           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    2637           0 :                 return -EINVAL;
    2638             : 
    2639             :         /*
    2640             :          * Universal plane src offsets are only 16.16, prevent havoc for
    2641             :          * drivers using universal plane code internally.
    2642             :          */
    2643           0 :         if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
    2644           0 :                 return -ERANGE;
    2645             : 
    2646           0 :         drm_modeset_lock_all(dev);
    2647           0 :         crtc = drm_crtc_find(dev, crtc_req->crtc_id);
    2648           0 :         if (!crtc) {
    2649             :                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
    2650             :                 ret = -ENOENT;
    2651           0 :                 goto out;
    2652             :         }
    2653             :         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
    2654             : 
    2655           0 :         if (crtc_req->mode_valid) {
    2656             :                 /* If we have a mode we need a framebuffer. */
    2657             :                 /* If we pass -1, set the mode with the currently bound fb */
    2658           0 :                 if (crtc_req->fb_id == -1) {
    2659           0 :                         if (!crtc->primary->fb) {
    2660             :                                 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
    2661             :                                 ret = -EINVAL;
    2662           0 :                                 goto out;
    2663             :                         }
    2664             :                         fb = crtc->primary->fb;
    2665             :                         /* Make refcounting symmetric with the lookup path. */
    2666           0 :                         drm_framebuffer_reference(fb);
    2667           0 :                 } else {
    2668           0 :                         fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
    2669           0 :                         if (!fb) {
    2670             :                                 DRM_DEBUG_KMS("Unknown FB ID%d\n",
    2671             :                                                 crtc_req->fb_id);
    2672             :                                 ret = -ENOENT;
    2673           0 :                                 goto out;
    2674             :                         }
    2675             :                 }
    2676             : 
    2677           0 :                 mode = drm_mode_create(dev);
    2678           0 :                 if (!mode) {
    2679             :                         ret = -ENOMEM;
    2680           0 :                         goto out;
    2681             :                 }
    2682             : 
    2683           0 :                 ret = drm_mode_convert_umode(mode, &crtc_req->mode);
    2684           0 :                 if (ret) {
    2685             :                         DRM_DEBUG_KMS("Invalid mode\n");
    2686             :                         goto out;
    2687             :                 }
    2688             : 
    2689             :                 /*
    2690             :                  * Check whether the primary plane supports the fb pixel format.
    2691             :                  * Drivers not implementing the universal planes API use a
    2692             :                  * default formats list provided by the DRM core which doesn't
    2693             :                  * match real hardware capabilities. Skip the check in that
    2694             :                  * case.
    2695             :                  */
    2696           0 :                 if (!crtc->primary->format_default) {
    2697           0 :                         ret = drm_plane_check_pixel_format(crtc->primary,
    2698           0 :                                                            fb->pixel_format);
    2699           0 :                         if (ret) {
    2700             :                                 DRM_DEBUG_KMS("Invalid pixel format %s\n",
    2701             :                                         drm_get_format_name(fb->pixel_format));
    2702             :                                 goto out;
    2703             :                         }
    2704             :                 }
    2705             : 
    2706           0 :                 ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
    2707             :                                               mode, fb);
    2708           0 :                 if (ret)
    2709             :                         goto out;
    2710             : 
    2711             :         }
    2712             : 
    2713           0 :         if (crtc_req->count_connectors == 0 && mode) {
    2714             :                 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
    2715             :                 ret = -EINVAL;
    2716           0 :                 goto out;
    2717             :         }
    2718             : 
    2719           0 :         if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
    2720             :                 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
    2721             :                           crtc_req->count_connectors);
    2722             :                 ret = -EINVAL;
    2723           0 :                 goto out;
    2724             :         }
    2725             : 
    2726           0 :         if (crtc_req->count_connectors > 0) {
    2727           0 :                 u32 out_id;
    2728             : 
    2729             :                 /* Avoid unbounded kernel memory allocation */
    2730           0 :                 if (crtc_req->count_connectors > config->num_connector) {
    2731             :                         ret = -EINVAL;
    2732           0 :                         goto out;
    2733             :                 }
    2734             : 
    2735           0 :                 connector_set = kmalloc_array(crtc_req->count_connectors,
    2736             :                                               sizeof(struct drm_connector *),
    2737             :                                               GFP_KERNEL);
    2738           0 :                 if (!connector_set) {
    2739             :                         ret = -ENOMEM;
    2740           0 :                         goto out;
    2741             :                 }
    2742             : 
    2743           0 :                 for (i = 0; i < crtc_req->count_connectors; i++) {
    2744           0 :                         set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
    2745           0 :                         if (get_user(out_id, &set_connectors_ptr[i])) {
    2746             :                                 ret = -EFAULT;
    2747           0 :                                 goto out;
    2748             :                         }
    2749             : 
    2750           0 :                         connector = drm_connector_find(dev, out_id);
    2751           0 :                         if (!connector) {
    2752             :                                 DRM_DEBUG_KMS("Connector id %d unknown\n",
    2753             :                                                 out_id);
    2754             :                                 ret = -ENOENT;
    2755           0 :                                 goto out;
    2756             :                         }
    2757             :                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
    2758             :                                         connector->base.id,
    2759             :                                         connector->name);
    2760             : 
    2761           0 :                         connector_set[i] = connector;
    2762             :                 }
    2763           0 :         }
    2764             : 
    2765           0 :         set.crtc = crtc;
    2766           0 :         set.x = crtc_req->x;
    2767           0 :         set.y = crtc_req->y;
    2768           0 :         set.mode = mode;
    2769           0 :         set.connectors = connector_set;
    2770           0 :         set.num_connectors = crtc_req->count_connectors;
    2771           0 :         set.fb = fb;
    2772           0 :         ret = drm_mode_set_config_internal(&set);
    2773             : 
    2774             : out:
    2775           0 :         if (fb)
    2776           0 :                 drm_framebuffer_unreference(fb);
    2777             : 
    2778           0 :         kfree(connector_set);
    2779           0 :         drm_mode_destroy(dev, mode);
    2780           0 :         drm_modeset_unlock_all(dev);
    2781           0 :         return ret;
    2782           0 : }
    2783             : 
    2784             : /**
    2785             :  * drm_mode_cursor_universal - translate legacy cursor ioctl call into a
    2786             :  *     universal plane handler call
    2787             :  * @crtc: crtc to update cursor for
    2788             :  * @req: data pointer for the ioctl
    2789             :  * @file_priv: drm file for the ioctl call
    2790             :  *
    2791             :  * Legacy cursor ioctl's work directly with driver buffer handles.  To
    2792             :  * translate legacy ioctl calls into universal plane handler calls, we need to
    2793             :  * wrap the native buffer handle in a drm_framebuffer.
    2794             :  *
    2795             :  * Note that we assume any handle passed to the legacy ioctls was a 32-bit ARGB
    2796             :  * buffer with a pitch of 4*width; the universal plane interface should be used
    2797             :  * directly in cases where the hardware can support other buffer settings and
    2798             :  * userspace wants to make use of these capabilities.
    2799             :  *
    2800             :  * Returns:
    2801             :  * Zero on success, negative errno on failure.
    2802             :  */
    2803           0 : static int drm_mode_cursor_universal(struct drm_crtc *crtc,
    2804             :                                      struct drm_mode_cursor2 *req,
    2805             :                                      struct drm_file *file_priv)
    2806             : {
    2807           0 :         struct drm_device *dev = crtc->dev;
    2808             :         struct drm_framebuffer *fb = NULL;
    2809           0 :         struct drm_mode_fb_cmd2 fbreq = {
    2810           0 :                 .width = req->width,
    2811           0 :                 .height = req->height,
    2812             :                 .pixel_format = DRM_FORMAT_ARGB8888,
    2813           0 :                 .pitches = { req->width * 4 },
    2814           0 :                 .handles = { req->handle },
    2815             :         };
    2816             :         int32_t crtc_x, crtc_y;
    2817             :         uint32_t crtc_w = 0, crtc_h = 0;
    2818             :         uint32_t src_w = 0, src_h = 0;
    2819             :         int ret = 0;
    2820             : 
    2821           0 :         BUG_ON(!crtc->cursor);
    2822           0 :         WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL);
    2823             : 
    2824             :         /*
    2825             :          * Obtain fb we'll be using (either new or existing) and take an extra
    2826             :          * reference to it if fb != null.  setplane will take care of dropping
    2827             :          * the reference if the plane update fails.
    2828             :          */
    2829           0 :         if (req->flags & DRM_MODE_CURSOR_BO) {
    2830           0 :                 if (req->handle) {
    2831           0 :                         fb = internal_framebuffer_create(dev, &fbreq, file_priv);
    2832           0 :                         if (IS_ERR(fb)) {
    2833             :                                 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
    2834           0 :                                 return PTR_ERR(fb);
    2835             :                         }
    2836             :                 } else {
    2837             :                         fb = NULL;
    2838             :                 }
    2839             :         } else {
    2840           0 :                 fb = crtc->cursor->fb;
    2841           0 :                 if (fb)
    2842           0 :                         drm_framebuffer_reference(fb);
    2843             :         }
    2844             : 
    2845           0 :         if (req->flags & DRM_MODE_CURSOR_MOVE) {
    2846           0 :                 crtc_x = req->x;
    2847           0 :                 crtc_y = req->y;
    2848           0 :         } else {
    2849           0 :                 crtc_x = crtc->cursor_x;
    2850           0 :                 crtc_y = crtc->cursor_y;
    2851             :         }
    2852             : 
    2853           0 :         if (fb) {
    2854           0 :                 crtc_w = fb->width;
    2855           0 :                 crtc_h = fb->height;
    2856           0 :                 src_w = fb->width << 16;
    2857           0 :                 src_h = fb->height << 16;
    2858           0 :         }
    2859             : 
    2860             :         /*
    2861             :          * setplane_internal will take care of deref'ing either the old or new
    2862             :          * framebuffer depending on success.
    2863             :          */
    2864           0 :         ret = __setplane_internal(crtc->cursor, crtc, fb,
    2865             :                                 crtc_x, crtc_y, crtc_w, crtc_h,
    2866             :                                 0, 0, src_w, src_h);
    2867             : 
    2868             :         /* Update successful; save new cursor position, if necessary */
    2869           0 :         if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
    2870           0 :                 crtc->cursor_x = req->x;
    2871           0 :                 crtc->cursor_y = req->y;
    2872           0 :         }
    2873             : 
    2874           0 :         return ret;
    2875           0 : }
    2876             : 
    2877           0 : static int drm_mode_cursor_common(struct drm_device *dev,
    2878             :                                   struct drm_mode_cursor2 *req,
    2879             :                                   struct drm_file *file_priv)
    2880             : {
    2881             :         struct drm_crtc *crtc;
    2882             :         int ret = 0;
    2883             : 
    2884           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    2885           0 :                 return -EINVAL;
    2886             : 
    2887           0 :         if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
    2888           0 :                 return -EINVAL;
    2889             : 
    2890           0 :         crtc = drm_crtc_find(dev, req->crtc_id);
    2891           0 :         if (!crtc) {
    2892             :                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
    2893           0 :                 return -ENOENT;
    2894             :         }
    2895             : 
    2896             :         /*
    2897             :          * If this crtc has a universal cursor plane, call that plane's update
    2898             :          * handler rather than using legacy cursor handlers.
    2899             :          */
    2900           0 :         drm_modeset_lock_crtc(crtc, crtc->cursor);
    2901           0 :         if (crtc->cursor) {
    2902           0 :                 ret = drm_mode_cursor_universal(crtc, req, file_priv);
    2903           0 :                 goto out;
    2904             :         }
    2905             : 
    2906           0 :         if (req->flags & DRM_MODE_CURSOR_BO) {
    2907           0 :                 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
    2908             :                         ret = -ENXIO;
    2909           0 :                         goto out;
    2910             :                 }
    2911             :                 /* Turns off the cursor if handle is 0 */
    2912           0 :                 if (crtc->funcs->cursor_set2)
    2913           0 :                         ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
    2914           0 :                                                       req->width, req->height, req->hot_x, req->hot_y);
    2915             :                 else
    2916           0 :                         ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
    2917           0 :                                                       req->width, req->height);
    2918             :         }
    2919             : 
    2920           0 :         if (req->flags & DRM_MODE_CURSOR_MOVE) {
    2921           0 :                 if (crtc->funcs->cursor_move) {
    2922           0 :                         ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
    2923             :                 } else {
    2924             :                         ret = -EFAULT;
    2925           0 :                         goto out;
    2926             :                 }
    2927           0 :         }
    2928             : out:
    2929           0 :         drm_modeset_unlock_crtc(crtc);
    2930             : 
    2931           0 :         return ret;
    2932             : 
    2933           0 : }
    2934             : 
    2935             : 
    2936             : /**
    2937             :  * drm_mode_cursor_ioctl - set CRTC's cursor configuration
    2938             :  * @dev: drm device for the ioctl
    2939             :  * @data: data pointer for the ioctl
    2940             :  * @file_priv: drm file for the ioctl call
    2941             :  *
    2942             :  * Set the cursor configuration based on user request.
    2943             :  *
    2944             :  * Called by the user via ioctl.
    2945             :  *
    2946             :  * Returns:
    2947             :  * Zero on success, negative errno on failure.
    2948             :  */
    2949           0 : int drm_mode_cursor_ioctl(struct drm_device *dev,
    2950             :                           void *data, struct drm_file *file_priv)
    2951             : {
    2952           0 :         struct drm_mode_cursor *req = data;
    2953           0 :         struct drm_mode_cursor2 new_req;
    2954             : 
    2955           0 :         memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
    2956           0 :         new_req.hot_x = new_req.hot_y = 0;
    2957             : 
    2958           0 :         return drm_mode_cursor_common(dev, &new_req, file_priv);
    2959           0 : }
    2960             : 
    2961             : /**
    2962             :  * drm_mode_cursor2_ioctl - set CRTC's cursor configuration
    2963             :  * @dev: drm device for the ioctl
    2964             :  * @data: data pointer for the ioctl
    2965             :  * @file_priv: drm file for the ioctl call
    2966             :  *
    2967             :  * Set the cursor configuration based on user request. This implements the 2nd
    2968             :  * version of the cursor ioctl, which allows userspace to additionally specify
    2969             :  * the hotspot of the pointer.
    2970             :  *
    2971             :  * Called by the user via ioctl.
    2972             :  *
    2973             :  * Returns:
    2974             :  * Zero on success, negative errno on failure.
    2975             :  */
    2976           0 : int drm_mode_cursor2_ioctl(struct drm_device *dev,
    2977             :                            void *data, struct drm_file *file_priv)
    2978             : {
    2979           0 :         struct drm_mode_cursor2 *req = data;
    2980             : 
    2981           0 :         return drm_mode_cursor_common(dev, req, file_priv);
    2982             : }
    2983             : 
    2984             : /**
    2985             :  * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description
    2986             :  * @bpp: bits per pixels
    2987             :  * @depth: bit depth per pixel
    2988             :  *
    2989             :  * Computes a drm fourcc pixel format code for the given @bpp/@depth values.
    2990             :  * Useful in fbdev emulation code, since that deals in those values.
    2991             :  */
    2992           0 : uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
    2993             : {
    2994             :         uint32_t fmt;
    2995             : 
    2996           0 :         switch (bpp) {
    2997             :         case 8:
    2998             :                 fmt = DRM_FORMAT_C8;
    2999           0 :                 break;
    3000             :         case 16:
    3001           0 :                 if (depth == 15)
    3002           0 :                         fmt = DRM_FORMAT_XRGB1555;
    3003             :                 else
    3004             :                         fmt = DRM_FORMAT_RGB565;
    3005             :                 break;
    3006             :         case 24:
    3007             :                 fmt = DRM_FORMAT_RGB888;
    3008           0 :                 break;
    3009             :         case 32:
    3010           0 :                 if (depth == 24)
    3011           0 :                         fmt = DRM_FORMAT_XRGB8888;
    3012           0 :                 else if (depth == 30)
    3013           0 :                         fmt = DRM_FORMAT_XRGB2101010;
    3014             :                 else
    3015             :                         fmt = DRM_FORMAT_ARGB8888;
    3016             :                 break;
    3017             :         default:
    3018           0 :                 DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
    3019             :                 fmt = DRM_FORMAT_XRGB8888;
    3020           0 :                 break;
    3021             :         }
    3022             : 
    3023           0 :         return fmt;
    3024             : }
    3025             : EXPORT_SYMBOL(drm_mode_legacy_fb_format);
    3026             : 
    3027             : /**
    3028             :  * drm_mode_addfb - add an FB to the graphics configuration
    3029             :  * @dev: drm device for the ioctl
    3030             :  * @data: data pointer for the ioctl
    3031             :  * @file_priv: drm file for the ioctl call
    3032             :  *
    3033             :  * Add a new FB to the specified CRTC, given a user request. This is the
    3034             :  * original addfb ioctl which only supported RGB formats.
    3035             :  *
    3036             :  * Called by the user via ioctl.
    3037             :  *
    3038             :  * Returns:
    3039             :  * Zero on success, negative errno on failure.
    3040             :  */
    3041           0 : int drm_mode_addfb(struct drm_device *dev,
    3042             :                    void *data, struct drm_file *file_priv)
    3043             : {
    3044           0 :         struct drm_mode_fb_cmd *or = data;
    3045           0 :         struct drm_mode_fb_cmd2 r = {};
    3046             :         int ret;
    3047             : 
    3048             :         /* convert to new format and call new ioctl */
    3049           0 :         r.fb_id = or->fb_id;
    3050           0 :         r.width = or->width;
    3051           0 :         r.height = or->height;
    3052           0 :         r.pitches[0] = or->pitch;
    3053           0 :         r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
    3054           0 :         r.handles[0] = or->handle;
    3055             : 
    3056           0 :         ret = drm_mode_addfb2(dev, &r, file_priv);
    3057           0 :         if (ret)
    3058           0 :                 return ret;
    3059             : 
    3060           0 :         or->fb_id = r.fb_id;
    3061             : 
    3062           0 :         return 0;
    3063           0 : }
    3064             : 
    3065           0 : static int format_check(const struct drm_mode_fb_cmd2 *r)
    3066             : {
    3067           0 :         uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
    3068             : 
    3069           0 :         switch (format) {
    3070             :         case DRM_FORMAT_C8:
    3071             :         case DRM_FORMAT_RGB332:
    3072             :         case DRM_FORMAT_BGR233:
    3073             :         case DRM_FORMAT_XRGB4444:
    3074             :         case DRM_FORMAT_XBGR4444:
    3075             :         case DRM_FORMAT_RGBX4444:
    3076             :         case DRM_FORMAT_BGRX4444:
    3077             :         case DRM_FORMAT_ARGB4444:
    3078             :         case DRM_FORMAT_ABGR4444:
    3079             :         case DRM_FORMAT_RGBA4444:
    3080             :         case DRM_FORMAT_BGRA4444:
    3081             :         case DRM_FORMAT_XRGB1555:
    3082             :         case DRM_FORMAT_XBGR1555:
    3083             :         case DRM_FORMAT_RGBX5551:
    3084             :         case DRM_FORMAT_BGRX5551:
    3085             :         case DRM_FORMAT_ARGB1555:
    3086             :         case DRM_FORMAT_ABGR1555:
    3087             :         case DRM_FORMAT_RGBA5551:
    3088             :         case DRM_FORMAT_BGRA5551:
    3089             :         case DRM_FORMAT_RGB565:
    3090             :         case DRM_FORMAT_BGR565:
    3091             :         case DRM_FORMAT_RGB888:
    3092             :         case DRM_FORMAT_BGR888:
    3093             :         case DRM_FORMAT_XRGB8888:
    3094             :         case DRM_FORMAT_XBGR8888:
    3095             :         case DRM_FORMAT_RGBX8888:
    3096             :         case DRM_FORMAT_BGRX8888:
    3097             :         case DRM_FORMAT_ARGB8888:
    3098             :         case DRM_FORMAT_ABGR8888:
    3099             :         case DRM_FORMAT_RGBA8888:
    3100             :         case DRM_FORMAT_BGRA8888:
    3101             :         case DRM_FORMAT_XRGB2101010:
    3102             :         case DRM_FORMAT_XBGR2101010:
    3103             :         case DRM_FORMAT_RGBX1010102:
    3104             :         case DRM_FORMAT_BGRX1010102:
    3105             :         case DRM_FORMAT_ARGB2101010:
    3106             :         case DRM_FORMAT_ABGR2101010:
    3107             :         case DRM_FORMAT_RGBA1010102:
    3108             :         case DRM_FORMAT_BGRA1010102:
    3109             :         case DRM_FORMAT_YUYV:
    3110             :         case DRM_FORMAT_YVYU:
    3111             :         case DRM_FORMAT_UYVY:
    3112             :         case DRM_FORMAT_VYUY:
    3113             :         case DRM_FORMAT_AYUV:
    3114             :         case DRM_FORMAT_NV12:
    3115             :         case DRM_FORMAT_NV21:
    3116             :         case DRM_FORMAT_NV16:
    3117             :         case DRM_FORMAT_NV61:
    3118             :         case DRM_FORMAT_NV24:
    3119             :         case DRM_FORMAT_NV42:
    3120             :         case DRM_FORMAT_YUV410:
    3121             :         case DRM_FORMAT_YVU410:
    3122             :         case DRM_FORMAT_YUV411:
    3123             :         case DRM_FORMAT_YVU411:
    3124             :         case DRM_FORMAT_YUV420:
    3125             :         case DRM_FORMAT_YVU420:
    3126             :         case DRM_FORMAT_YUV422:
    3127             :         case DRM_FORMAT_YVU422:
    3128             :         case DRM_FORMAT_YUV444:
    3129             :         case DRM_FORMAT_YVU444:
    3130           0 :                 return 0;
    3131             :         default:
    3132             :                 DRM_DEBUG_KMS("invalid pixel format %s\n",
    3133             :                               drm_get_format_name(r->pixel_format));
    3134           0 :                 return -EINVAL;
    3135             :         }
    3136           0 : }
    3137             : 
    3138           0 : static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
    3139             : {
    3140             :         int ret, hsub, vsub, num_planes, i;
    3141             : 
    3142           0 :         ret = format_check(r);
    3143           0 :         if (ret) {
    3144             :                 DRM_DEBUG_KMS("bad framebuffer format %s\n",
    3145             :                               drm_get_format_name(r->pixel_format));
    3146           0 :                 return ret;
    3147             :         }
    3148             : 
    3149           0 :         hsub = drm_format_horz_chroma_subsampling(r->pixel_format);
    3150           0 :         vsub = drm_format_vert_chroma_subsampling(r->pixel_format);
    3151           0 :         num_planes = drm_format_num_planes(r->pixel_format);
    3152             : 
    3153           0 :         if (r->width == 0 || r->width % hsub) {
    3154             :                 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
    3155           0 :                 return -EINVAL;
    3156             :         }
    3157             : 
    3158           0 :         if (r->height == 0 || r->height % vsub) {
    3159             :                 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
    3160           0 :                 return -EINVAL;
    3161             :         }
    3162             : 
    3163           0 :         for (i = 0; i < num_planes; i++) {
    3164           0 :                 unsigned int width = r->width / (i != 0 ? hsub : 1);
    3165           0 :                 unsigned int height = r->height / (i != 0 ? vsub : 1);
    3166           0 :                 unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
    3167             : 
    3168           0 :                 if (!r->handles[i]) {
    3169             :                         DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
    3170           0 :                         return -EINVAL;
    3171             :                 }
    3172             : 
    3173           0 :                 if ((uint64_t) width * cpp > UINT_MAX)
    3174           0 :                         return -ERANGE;
    3175             : 
    3176           0 :                 if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
    3177           0 :                         return -ERANGE;
    3178             : 
    3179           0 :                 if (r->pitches[i] < width * cpp) {
    3180             :                         DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
    3181           0 :                         return -EINVAL;
    3182             :                 }
    3183             : 
    3184           0 :                 if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) {
    3185             :                         DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n",
    3186             :                                       r->modifier[i], i);
    3187           0 :                         return -EINVAL;
    3188             :                 }
    3189             : 
    3190             :                 /* modifier specific checks: */
    3191           0 :                 switch (r->modifier[i]) {
    3192             :                 case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
    3193             :                         /* NOTE: the pitch restriction may be lifted later if it turns
    3194             :                          * out that no hw has this restriction:
    3195             :                          */
    3196           0 :                         if (r->pixel_format != DRM_FORMAT_NV12 ||
    3197           0 :                                         width % 128 || height % 32 ||
    3198           0 :                                         r->pitches[i] % 128) {
    3199             :                                 DRM_DEBUG_KMS("bad modifier data for plane %d\n", i);
    3200           0 :                                 return -EINVAL;
    3201             :                         }
    3202             :                         break;
    3203             : 
    3204             :                 default:
    3205             :                         break;
    3206             :                 }
    3207           0 :         }
    3208             : 
    3209           0 :         for (i = num_planes; i < 4; i++) {
    3210           0 :                 if (r->modifier[i]) {
    3211             :                         DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i);
    3212           0 :                         return -EINVAL;
    3213             :                 }
    3214             : 
    3215             :                 /* Pre-FB_MODIFIERS userspace didn't clear the structs properly. */
    3216           0 :                 if (!(r->flags & DRM_MODE_FB_MODIFIERS))
    3217             :                         continue;
    3218             : 
    3219           0 :                 if (r->handles[i]) {
    3220             :                         DRM_DEBUG_KMS("buffer object handle for unused plane %d\n", i);
    3221           0 :                         return -EINVAL;
    3222             :                 }
    3223             : 
    3224           0 :                 if (r->pitches[i]) {
    3225             :                         DRM_DEBUG_KMS("non-zero pitch for unused plane %d\n", i);
    3226           0 :                         return -EINVAL;
    3227             :                 }
    3228             : 
    3229           0 :                 if (r->offsets[i]) {
    3230             :                         DRM_DEBUG_KMS("non-zero offset for unused plane %d\n", i);
    3231           0 :                         return -EINVAL;
    3232             :                 }
    3233             :         }
    3234             : 
    3235           0 :         return 0;
    3236           0 : }
    3237             : 
    3238             : static struct drm_framebuffer *
    3239           0 : internal_framebuffer_create(struct drm_device *dev,
    3240             :                             struct drm_mode_fb_cmd2 *r,
    3241             :                             struct drm_file *file_priv)
    3242             : {
    3243           0 :         struct drm_mode_config *config = &dev->mode_config;
    3244             :         struct drm_framebuffer *fb;
    3245             :         int ret;
    3246             : 
    3247           0 :         if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {
    3248             :                 DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
    3249           0 :                 return ERR_PTR(-EINVAL);
    3250             :         }
    3251             : 
    3252           0 :         if ((config->min_width > r->width) || (r->width > config->max_width)) {
    3253             :                 DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
    3254             :                           r->width, config->min_width, config->max_width);
    3255           0 :                 return ERR_PTR(-EINVAL);
    3256             :         }
    3257           0 :         if ((config->min_height > r->height) || (r->height > config->max_height)) {
    3258             :                 DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
    3259             :                           r->height, config->min_height, config->max_height);
    3260           0 :                 return ERR_PTR(-EINVAL);
    3261             :         }
    3262             : 
    3263           0 :         if (r->flags & DRM_MODE_FB_MODIFIERS &&
    3264           0 :             !dev->mode_config.allow_fb_modifiers) {
    3265             :                 DRM_DEBUG_KMS("driver does not support fb modifiers\n");
    3266           0 :                 return ERR_PTR(-EINVAL);
    3267             :         }
    3268             : 
    3269           0 :         ret = framebuffer_check(r);
    3270           0 :         if (ret)
    3271           0 :                 return ERR_PTR(ret);
    3272             : 
    3273           0 :         fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
    3274           0 :         if (IS_ERR(fb)) {
    3275             :                 DRM_DEBUG_KMS("could not create framebuffer\n");
    3276           0 :                 return fb;
    3277             :         }
    3278             : 
    3279             :         return fb;
    3280           0 : }
    3281             : 
    3282             : /**
    3283             :  * drm_mode_addfb2 - add an FB to the graphics configuration
    3284             :  * @dev: drm device for the ioctl
    3285             :  * @data: data pointer for the ioctl
    3286             :  * @file_priv: drm file for the ioctl call
    3287             :  *
    3288             :  * Add a new FB to the specified CRTC, given a user request with format. This is
    3289             :  * the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
    3290             :  * and uses fourcc codes as pixel format specifiers.
    3291             :  *
    3292             :  * Called by the user via ioctl.
    3293             :  *
    3294             :  * Returns:
    3295             :  * Zero on success, negative errno on failure.
    3296             :  */
    3297           0 : int drm_mode_addfb2(struct drm_device *dev,
    3298             :                     void *data, struct drm_file *file_priv)
    3299             : {
    3300           0 :         struct drm_mode_fb_cmd2 *r = data;
    3301             :         struct drm_framebuffer *fb;
    3302             : 
    3303           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    3304           0 :                 return -EINVAL;
    3305             : 
    3306           0 :         fb = internal_framebuffer_create(dev, r, file_priv);
    3307           0 :         if (IS_ERR(fb))
    3308           0 :                 return PTR_ERR(fb);
    3309             : 
    3310             :         /* Transfer ownership to the filp for reaping on close */
    3311             : 
    3312             :         DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
    3313           0 :         mutex_lock(&file_priv->fbs_lock);
    3314           0 :         r->fb_id = fb->base.id;
    3315           0 :         list_add(&fb->filp_head, &file_priv->fbs);
    3316           0 :         mutex_unlock(&file_priv->fbs_lock);
    3317             : 
    3318           0 :         return 0;
    3319           0 : }
    3320             : 
    3321             : struct drm_mode_rmfb_work {
    3322             :         struct work_struct work;
    3323             :         struct list_head fbs;
    3324             : };
    3325             : 
    3326           0 : static void drm_mode_rmfb_work_fn(struct work_struct *w)
    3327             : {
    3328           0 :         struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
    3329             : 
    3330           0 :         while (!list_empty(&arg->fbs)) {
    3331             :                 struct drm_framebuffer *fb =
    3332           0 :                         list_first_entry(&arg->fbs, typeof(*fb), filp_head);
    3333             : 
    3334           0 :                 list_del_init(&fb->filp_head);
    3335           0 :                 drm_framebuffer_remove(fb);
    3336             :         }
    3337           0 : }
    3338             : 
    3339             : /**
    3340             :  * drm_mode_rmfb - remove an FB from the configuration
    3341             :  * @dev: drm device for the ioctl
    3342             :  * @data: data pointer for the ioctl
    3343             :  * @file_priv: drm file for the ioctl call
    3344             :  *
    3345             :  * Remove the FB specified by the user.
    3346             :  *
    3347             :  * Called by the user via ioctl.
    3348             :  *
    3349             :  * Returns:
    3350             :  * Zero on success, negative errno on failure.
    3351             :  */
    3352           0 : int drm_mode_rmfb(struct drm_device *dev,
    3353             :                    void *data, struct drm_file *file_priv)
    3354             : {
    3355             :         struct drm_framebuffer *fb = NULL;
    3356             :         struct drm_framebuffer *fbl = NULL;
    3357           0 :         uint32_t *id = data;
    3358             :         int found = 0;
    3359             : 
    3360           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    3361           0 :                 return -EINVAL;
    3362             : 
    3363           0 :         mutex_lock(&file_priv->fbs_lock);
    3364           0 :         mutex_lock(&dev->mode_config.fb_lock);
    3365           0 :         fb = __drm_framebuffer_lookup(dev, *id);
    3366           0 :         if (!fb)
    3367             :                 goto fail_lookup;
    3368             : 
    3369           0 :         list_for_each_entry(fbl, &file_priv->fbs, filp_head)
    3370           0 :                 if (fb == fbl)
    3371           0 :                         found = 1;
    3372           0 :         if (!found)
    3373             :                 goto fail_lookup;
    3374             : 
    3375           0 :         list_del_init(&fb->filp_head);
    3376           0 :         mutex_unlock(&dev->mode_config.fb_lock);
    3377           0 :         mutex_unlock(&file_priv->fbs_lock);
    3378             : 
    3379             :         /*
    3380             :          * we now own the reference that was stored in the fbs list
    3381             :          *
    3382             :          * drm_framebuffer_remove may fail with -EINTR on pending signals,
    3383             :          * so run this in a separate stack as there's no way to correctly
    3384             :          * handle this after the fb is already removed from the lookup table.
    3385             :          */
    3386           0 :         if (atomic_read(&fb->refcount.refcount) > 1) {
    3387           0 :                 struct drm_mode_rmfb_work arg;
    3388             : 
    3389           0 :                 INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
    3390           0 :                 INIT_LIST_HEAD(&arg.fbs);
    3391           0 :                 list_add_tail(&fb->filp_head, &arg.fbs);
    3392             : 
    3393           0 :                 schedule_work(&arg.work);
    3394           0 :                 flush_work(&arg.work);
    3395             :                 destroy_work_on_stack(&arg.work);
    3396           0 :         } else
    3397           0 :                 drm_framebuffer_unreference(fb);
    3398             : 
    3399           0 :         return 0;
    3400             : 
    3401             : fail_lookup:
    3402           0 :         mutex_unlock(&dev->mode_config.fb_lock);
    3403           0 :         mutex_unlock(&file_priv->fbs_lock);
    3404             : 
    3405           0 :         return -ENOENT;
    3406           0 : }
    3407             : 
    3408             : /**
    3409             :  * drm_mode_getfb - get FB info
    3410             :  * @dev: drm device for the ioctl
    3411             :  * @data: data pointer for the ioctl
    3412             :  * @file_priv: drm file for the ioctl call
    3413             :  *
    3414             :  * Lookup the FB given its ID and return info about it.
    3415             :  *
    3416             :  * Called by the user via ioctl.
    3417             :  *
    3418             :  * Returns:
    3419             :  * Zero on success, negative errno on failure.
    3420             :  */
    3421           0 : int drm_mode_getfb(struct drm_device *dev,
    3422             :                    void *data, struct drm_file *file_priv)
    3423             : {
    3424           0 :         struct drm_mode_fb_cmd *r = data;
    3425             :         struct drm_framebuffer *fb;
    3426             :         int ret;
    3427             : 
    3428           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    3429           0 :                 return -EINVAL;
    3430             : 
    3431           0 :         fb = drm_framebuffer_lookup(dev, r->fb_id);
    3432           0 :         if (!fb)
    3433           0 :                 return -ENOENT;
    3434             : 
    3435           0 :         r->height = fb->height;
    3436           0 :         r->width = fb->width;
    3437           0 :         r->depth = fb->depth;
    3438           0 :         r->bpp = fb->bits_per_pixel;
    3439           0 :         r->pitch = fb->pitches[0];
    3440           0 :         if (fb->funcs->create_handle) {
    3441           0 :                 if (file_priv->is_master || capable(CAP_SYS_ADMIN) ||
    3442           0 :                     drm_is_control_client(file_priv)) {
    3443           0 :                         ret = fb->funcs->create_handle(fb, file_priv,
    3444           0 :                                                        &r->handle);
    3445           0 :                 } else {
    3446             :                         /* GET_FB() is an unprivileged ioctl so we must not
    3447             :                          * return a buffer-handle to non-master processes! For
    3448             :                          * backwards-compatibility reasons, we cannot make
    3449             :                          * GET_FB() privileged, so just return an invalid handle
    3450             :                          * for non-masters. */
    3451           0 :                         r->handle = 0;
    3452             :                         ret = 0;
    3453             :                 }
    3454             :         } else {
    3455             :                 ret = -ENODEV;
    3456             :         }
    3457             : 
    3458           0 :         drm_framebuffer_unreference(fb);
    3459             : 
    3460           0 :         return ret;
    3461           0 : }
    3462             : 
    3463             : /**
    3464             :  * drm_mode_dirtyfb_ioctl - flush frontbuffer rendering on an FB
    3465             :  * @dev: drm device for the ioctl
    3466             :  * @data: data pointer for the ioctl
    3467             :  * @file_priv: drm file for the ioctl call
    3468             :  *
    3469             :  * Lookup the FB and flush out the damaged area supplied by userspace as a clip
    3470             :  * rectangle list. Generic userspace which does frontbuffer rendering must call
    3471             :  * this ioctl to flush out the changes on manual-update display outputs, e.g.
    3472             :  * usb display-link, mipi manual update panels or edp panel self refresh modes.
    3473             :  *
    3474             :  * Modesetting drivers which always update the frontbuffer do not need to
    3475             :  * implement the corresponding ->dirty framebuffer callback.
    3476             :  *
    3477             :  * Called by the user via ioctl.
    3478             :  *
    3479             :  * Returns:
    3480             :  * Zero on success, negative errno on failure.
    3481             :  */
    3482           0 : int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
    3483             :                            void *data, struct drm_file *file_priv)
    3484             : {
    3485             :         struct drm_clip_rect __user *clips_ptr;
    3486             :         struct drm_clip_rect *clips = NULL;
    3487           0 :         struct drm_mode_fb_dirty_cmd *r = data;
    3488             :         struct drm_framebuffer *fb;
    3489             :         unsigned flags;
    3490             :         int num_clips;
    3491             :         int ret;
    3492             : 
    3493           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    3494           0 :                 return -EINVAL;
    3495             : 
    3496           0 :         fb = drm_framebuffer_lookup(dev, r->fb_id);
    3497           0 :         if (!fb)
    3498           0 :                 return -ENOENT;
    3499             : 
    3500           0 :         num_clips = r->num_clips;
    3501           0 :         clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
    3502             : 
    3503           0 :         if (!num_clips != !clips_ptr) {
    3504             :                 ret = -EINVAL;
    3505           0 :                 goto out_err1;
    3506             :         }
    3507             : 
    3508           0 :         flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
    3509             : 
    3510             :         /* If userspace annotates copy, clips must come in pairs */
    3511           0 :         if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
    3512             :                 ret = -EINVAL;
    3513           0 :                 goto out_err1;
    3514             :         }
    3515             : 
    3516           0 :         if (num_clips && clips_ptr) {
    3517           0 :                 if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
    3518             :                         ret = -EINVAL;
    3519           0 :                         goto out_err1;
    3520             :                 }
    3521           0 :                 clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
    3522           0 :                 if (!clips) {
    3523             :                         ret = -ENOMEM;
    3524           0 :                         goto out_err1;
    3525             :                 }
    3526             : 
    3527           0 :                 ret = copy_from_user(clips, clips_ptr,
    3528           0 :                                      num_clips * sizeof(*clips));
    3529           0 :                 if (ret) {
    3530             :                         ret = -EFAULT;
    3531           0 :                         goto out_err2;
    3532             :                 }
    3533             :         }
    3534             : 
    3535           0 :         if (fb->funcs->dirty) {
    3536           0 :                 ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
    3537             :                                        clips, num_clips);
    3538           0 :         } else {
    3539             :                 ret = -ENOSYS;
    3540             :         }
    3541             : 
    3542             : out_err2:
    3543           0 :         kfree(clips);
    3544             : out_err1:
    3545           0 :         drm_framebuffer_unreference(fb);
    3546             : 
    3547           0 :         return ret;
    3548           0 : }
    3549             : 
    3550             : /**
    3551             :  * drm_fb_release - remove and free the FBs on this file
    3552             :  * @priv: drm file for the ioctl
    3553             :  *
    3554             :  * Destroy all the FBs associated with @filp.
    3555             :  *
    3556             :  * Called by the user via ioctl.
    3557             :  *
    3558             :  * Returns:
    3559             :  * Zero on success, negative errno on failure.
    3560             :  */
    3561           0 : void drm_fb_release(struct drm_file *priv)
    3562             : {
    3563             :         struct drm_framebuffer *fb, *tfb;
    3564           0 :         struct drm_mode_rmfb_work arg;
    3565             : 
    3566           0 :         INIT_LIST_HEAD(&arg.fbs);
    3567             : 
    3568             :         /*
    3569             :          * When the file gets released that means no one else can access the fb
    3570             :          * list any more, so no need to grab fpriv->fbs_lock. And we need to
    3571             :          * avoid upsetting lockdep since the universal cursor code adds a
    3572             :          * framebuffer while holding mutex locks.
    3573             :          *
    3574             :          * Note that a real deadlock between fpriv->fbs_lock and the modeset
    3575             :          * locks is impossible here since no one else but this function can get
    3576             :          * at it any more.
    3577             :          */
    3578           0 :         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
    3579           0 :                 if (atomic_read(&fb->refcount.refcount) > 1) {
    3580           0 :                         list_move_tail(&fb->filp_head, &arg.fbs);
    3581           0 :                 } else {
    3582           0 :                         list_del_init(&fb->filp_head);
    3583             : 
    3584             :                         /* This drops the fpriv->fbs reference. */
    3585           0 :                         drm_framebuffer_unreference(fb);
    3586             :                 }
    3587             :         }
    3588             : 
    3589           0 :         if (!list_empty(&arg.fbs)) {
    3590           0 :                 INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
    3591             : 
    3592           0 :                 schedule_work(&arg.work);
    3593           0 :                 flush_work(&arg.work);
    3594             :                 destroy_work_on_stack(&arg.work);
    3595           0 :         }
    3596           0 : }
    3597             : 
    3598             : /**
    3599             :  * drm_property_create - create a new property type
    3600             :  * @dev: drm device
    3601             :  * @flags: flags specifying the property type
    3602             :  * @name: name of the property
    3603             :  * @num_values: number of pre-defined values
    3604             :  *
    3605             :  * This creates a new generic drm property which can then be attached to a drm
    3606             :  * object with drm_object_attach_property. The returned property object must be
    3607             :  * freed with drm_property_destroy.
    3608             :  *
    3609             :  * Note that the DRM core keeps a per-device list of properties and that, if
    3610             :  * drm_mode_config_cleanup() is called, it will destroy all properties created
    3611             :  * by the driver.
    3612             :  *
    3613             :  * Returns:
    3614             :  * A pointer to the newly created property on success, NULL on failure.
    3615             :  */
    3616           0 : struct drm_property *drm_property_create(struct drm_device *dev, int flags,
    3617             :                                          const char *name, int num_values)
    3618             : {
    3619             :         struct drm_property *property = NULL;
    3620             :         int ret;
    3621             : 
    3622           0 :         property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
    3623           0 :         if (!property)
    3624           0 :                 return NULL;
    3625             : 
    3626           0 :         property->dev = dev;
    3627             : 
    3628           0 :         if (num_values) {
    3629           0 :                 property->values = kcalloc(num_values, sizeof(uint64_t),
    3630             :                                            GFP_KERNEL);
    3631           0 :                 if (!property->values)
    3632             :                         goto fail;
    3633             :         }
    3634             : 
    3635           0 :         ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
    3636           0 :         if (ret)
    3637             :                 goto fail;
    3638             : 
    3639           0 :         property->flags = flags;
    3640           0 :         property->num_values = num_values;
    3641           0 :         INIT_LIST_HEAD(&property->enum_list);
    3642             : 
    3643           0 :         if (name) {
    3644           0 :                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
    3645           0 :                 property->name[DRM_PROP_NAME_LEN-1] = '\0';
    3646           0 :         }
    3647             : 
    3648           0 :         list_add_tail(&property->head, &dev->mode_config.property_list);
    3649             : 
    3650           0 :         WARN_ON(!drm_property_type_valid(property));
    3651             : 
    3652           0 :         return property;
    3653             : fail:
    3654           0 :         kfree(property->values);
    3655           0 :         kfree(property);
    3656           0 :         return NULL;
    3657           0 : }
    3658             : EXPORT_SYMBOL(drm_property_create);
    3659             : 
    3660             : /**
    3661             :  * drm_property_create_enum - create a new enumeration property type
    3662             :  * @dev: drm device
    3663             :  * @flags: flags specifying the property type
    3664             :  * @name: name of the property
    3665             :  * @props: enumeration lists with property values
    3666             :  * @num_values: number of pre-defined values
    3667             :  *
    3668             :  * This creates a new generic drm property which can then be attached to a drm
    3669             :  * object with drm_object_attach_property. The returned property object must be
    3670             :  * freed with drm_property_destroy.
    3671             :  *
    3672             :  * Userspace is only allowed to set one of the predefined values for enumeration
    3673             :  * properties.
    3674             :  *
    3675             :  * Returns:
    3676             :  * A pointer to the newly created property on success, NULL on failure.
    3677             :  */
    3678           0 : struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
    3679             :                                          const char *name,
    3680             :                                          const struct drm_prop_enum_list *props,
    3681             :                                          int num_values)
    3682             : {
    3683             :         struct drm_property *property;
    3684             :         int i, ret;
    3685             : 
    3686           0 :         flags |= DRM_MODE_PROP_ENUM;
    3687             : 
    3688           0 :         property = drm_property_create(dev, flags, name, num_values);
    3689           0 :         if (!property)
    3690           0 :                 return NULL;
    3691             : 
    3692           0 :         for (i = 0; i < num_values; i++) {
    3693           0 :                 ret = drm_property_add_enum(property, i,
    3694           0 :                                       props[i].type,
    3695           0 :                                       props[i].name);
    3696           0 :                 if (ret) {
    3697           0 :                         drm_property_destroy(dev, property);
    3698           0 :                         return NULL;
    3699             :                 }
    3700             :         }
    3701             : 
    3702           0 :         return property;
    3703           0 : }
    3704             : EXPORT_SYMBOL(drm_property_create_enum);
    3705             : 
    3706             : /**
    3707             :  * drm_property_create_bitmask - create a new bitmask property type
    3708             :  * @dev: drm device
    3709             :  * @flags: flags specifying the property type
    3710             :  * @name: name of the property
    3711             :  * @props: enumeration lists with property bitflags
    3712             :  * @num_props: size of the @props array
    3713             :  * @supported_bits: bitmask of all supported enumeration values
    3714             :  *
    3715             :  * This creates a new bitmask drm property which can then be attached to a drm
    3716             :  * object with drm_object_attach_property. The returned property object must be
    3717             :  * freed with drm_property_destroy.
    3718             :  *
    3719             :  * Compared to plain enumeration properties userspace is allowed to set any
    3720             :  * or'ed together combination of the predefined property bitflag values
    3721             :  *
    3722             :  * Returns:
    3723             :  * A pointer to the newly created property on success, NULL on failure.
    3724             :  */
    3725           0 : struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
    3726             :                                          int flags, const char *name,
    3727             :                                          const struct drm_prop_enum_list *props,
    3728             :                                          int num_props,
    3729             :                                          uint64_t supported_bits)
    3730             : {
    3731             :         struct drm_property *property;
    3732             :         int i, ret, index = 0;
    3733           0 :         int num_values = hweight64(supported_bits);
    3734             : 
    3735           0 :         flags |= DRM_MODE_PROP_BITMASK;
    3736             : 
    3737           0 :         property = drm_property_create(dev, flags, name, num_values);
    3738           0 :         if (!property)
    3739           0 :                 return NULL;
    3740           0 :         for (i = 0; i < num_props; i++) {
    3741           0 :                 if (!(supported_bits & (1ULL << props[i].type)))
    3742             :                         continue;
    3743             : 
    3744           0 :                 if (WARN_ON(index >= num_values)) {
    3745           0 :                         drm_property_destroy(dev, property);
    3746           0 :                         return NULL;
    3747             :                 }
    3748             : 
    3749           0 :                 ret = drm_property_add_enum(property, index++,
    3750           0 :                                       props[i].type,
    3751           0 :                                       props[i].name);
    3752           0 :                 if (ret) {
    3753           0 :                         drm_property_destroy(dev, property);
    3754           0 :                         return NULL;
    3755             :                 }
    3756             :         }
    3757             : 
    3758           0 :         return property;
    3759           0 : }
    3760             : EXPORT_SYMBOL(drm_property_create_bitmask);
    3761             : 
    3762           0 : static struct drm_property *property_create_range(struct drm_device *dev,
    3763             :                                          int flags, const char *name,
    3764             :                                          uint64_t min, uint64_t max)
    3765             : {
    3766             :         struct drm_property *property;
    3767             : 
    3768           0 :         property = drm_property_create(dev, flags, name, 2);
    3769           0 :         if (!property)
    3770           0 :                 return NULL;
    3771             : 
    3772           0 :         property->values[0] = min;
    3773           0 :         property->values[1] = max;
    3774             : 
    3775           0 :         return property;
    3776           0 : }
    3777             : 
    3778             : /**
    3779             :  * drm_property_create_range - create a new unsigned ranged property type
    3780             :  * @dev: drm device
    3781             :  * @flags: flags specifying the property type
    3782             :  * @name: name of the property
    3783             :  * @min: minimum value of the property
    3784             :  * @max: maximum value of the property
    3785             :  *
    3786             :  * This creates a new generic drm property which can then be attached to a drm
    3787             :  * object with drm_object_attach_property. The returned property object must be
    3788             :  * freed with drm_property_destroy.
    3789             :  *
    3790             :  * Userspace is allowed to set any unsigned integer value in the (min, max)
    3791             :  * range inclusive.
    3792             :  *
    3793             :  * Returns:
    3794             :  * A pointer to the newly created property on success, NULL on failure.
    3795             :  */
    3796           0 : struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
    3797             :                                          const char *name,
    3798             :                                          uint64_t min, uint64_t max)
    3799             : {
    3800           0 :         return property_create_range(dev, DRM_MODE_PROP_RANGE | flags,
    3801             :                         name, min, max);
    3802             : }
    3803             : EXPORT_SYMBOL(drm_property_create_range);
    3804             : 
    3805             : /**
    3806             :  * drm_property_create_signed_range - create a new signed ranged property type
    3807             :  * @dev: drm device
    3808             :  * @flags: flags specifying the property type
    3809             :  * @name: name of the property
    3810             :  * @min: minimum value of the property
    3811             :  * @max: maximum value of the property
    3812             :  *
    3813             :  * This creates a new generic drm property which can then be attached to a drm
    3814             :  * object with drm_object_attach_property. The returned property object must be
    3815             :  * freed with drm_property_destroy.
    3816             :  *
    3817             :  * Userspace is allowed to set any signed integer value in the (min, max)
    3818             :  * range inclusive.
    3819             :  *
    3820             :  * Returns:
    3821             :  * A pointer to the newly created property on success, NULL on failure.
    3822             :  */
    3823           0 : struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
    3824             :                                          int flags, const char *name,
    3825             :                                          int64_t min, int64_t max)
    3826             : {
    3827           0 :         return property_create_range(dev, DRM_MODE_PROP_SIGNED_RANGE | flags,
    3828           0 :                         name, I642U64(min), I642U64(max));
    3829             : }
    3830             : EXPORT_SYMBOL(drm_property_create_signed_range);
    3831             : 
    3832             : /**
    3833             :  * drm_property_create_object - create a new object property type
    3834             :  * @dev: drm device
    3835             :  * @flags: flags specifying the property type
    3836             :  * @name: name of the property
    3837             :  * @type: object type from DRM_MODE_OBJECT_* defines
    3838             :  *
    3839             :  * This creates a new generic drm property which can then be attached to a drm
    3840             :  * object with drm_object_attach_property. The returned property object must be
    3841             :  * freed with drm_property_destroy.
    3842             :  *
    3843             :  * Userspace is only allowed to set this to any property value of the given
    3844             :  * @type. Only useful for atomic properties, which is enforced.
    3845             :  *
    3846             :  * Returns:
    3847             :  * A pointer to the newly created property on success, NULL on failure.
    3848             :  */
    3849           0 : struct drm_property *drm_property_create_object(struct drm_device *dev,
    3850             :                                          int flags, const char *name, uint32_t type)
    3851             : {
    3852             :         struct drm_property *property;
    3853             : 
    3854           0 :         flags |= DRM_MODE_PROP_OBJECT;
    3855             : 
    3856           0 :         if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC)))
    3857           0 :                 return NULL;
    3858             : 
    3859           0 :         property = drm_property_create(dev, flags, name, 1);
    3860           0 :         if (!property)
    3861           0 :                 return NULL;
    3862             : 
    3863           0 :         property->values[0] = type;
    3864             : 
    3865           0 :         return property;
    3866           0 : }
    3867             : EXPORT_SYMBOL(drm_property_create_object);
    3868             : 
    3869             : /**
    3870             :  * drm_property_create_bool - create a new boolean property type
    3871             :  * @dev: drm device
    3872             :  * @flags: flags specifying the property type
    3873             :  * @name: name of the property
    3874             :  *
    3875             :  * This creates a new generic drm property which can then be attached to a drm
    3876             :  * object with drm_object_attach_property. The returned property object must be
    3877             :  * freed with drm_property_destroy.
    3878             :  *
    3879             :  * This is implemented as a ranged property with only {0, 1} as valid values.
    3880             :  *
    3881             :  * Returns:
    3882             :  * A pointer to the newly created property on success, NULL on failure.
    3883             :  */
    3884           0 : struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
    3885             :                                          const char *name)
    3886             : {
    3887           0 :         return drm_property_create_range(dev, flags, name, 0, 1);
    3888             : }
    3889             : EXPORT_SYMBOL(drm_property_create_bool);
    3890             : 
    3891             : /**
    3892             :  * drm_property_add_enum - add a possible value to an enumeration property
    3893             :  * @property: enumeration property to change
    3894             :  * @index: index of the new enumeration
    3895             :  * @value: value of the new enumeration
    3896             :  * @name: symbolic name of the new enumeration
    3897             :  *
    3898             :  * This functions adds enumerations to a property.
    3899             :  *
    3900             :  * It's use is deprecated, drivers should use one of the more specific helpers
    3901             :  * to directly create the property with all enumerations already attached.
    3902             :  *
    3903             :  * Returns:
    3904             :  * Zero on success, error code on failure.
    3905             :  */
    3906           0 : int drm_property_add_enum(struct drm_property *property, int index,
    3907             :                           uint64_t value, const char *name)
    3908             : {
    3909             :         struct drm_property_enum *prop_enum;
    3910             : 
    3911           0 :         if (!(drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
    3912           0 :                         drm_property_type_is(property, DRM_MODE_PROP_BITMASK)))
    3913           0 :                 return -EINVAL;
    3914             : 
    3915             :         /*
    3916             :          * Bitmask enum properties have the additional constraint of values
    3917             :          * from 0 to 63
    3918             :          */
    3919           0 :         if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK) &&
    3920           0 :                         (value > 63))
    3921           0 :                 return -EINVAL;
    3922             : 
    3923           0 :         if (!list_empty(&property->enum_list)) {
    3924           0 :                 list_for_each_entry(prop_enum, &property->enum_list, head) {
    3925           0 :                         if (prop_enum->value == value) {
    3926           0 :                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
    3927           0 :                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
    3928           0 :                                 return 0;
    3929             :                         }
    3930             :                 }
    3931             :         }
    3932             : 
    3933           0 :         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
    3934           0 :         if (!prop_enum)
    3935           0 :                 return -ENOMEM;
    3936             : 
    3937           0 :         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
    3938           0 :         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
    3939           0 :         prop_enum->value = value;
    3940             : 
    3941           0 :         property->values[index] = value;
    3942           0 :         list_add_tail(&prop_enum->head, &property->enum_list);
    3943           0 :         return 0;
    3944           0 : }
    3945             : EXPORT_SYMBOL(drm_property_add_enum);
    3946             : 
    3947             : /**
    3948             :  * drm_property_destroy - destroy a drm property
    3949             :  * @dev: drm device
    3950             :  * @property: property to destry
    3951             :  *
    3952             :  * This function frees a property including any attached resources like
    3953             :  * enumeration values.
    3954             :  */
    3955           0 : void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
    3956             : {
    3957             :         struct drm_property_enum *prop_enum, *pt;
    3958             : 
    3959           0 :         list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) {
    3960           0 :                 list_del(&prop_enum->head);
    3961           0 :                 kfree(prop_enum);
    3962             :         }
    3963             : 
    3964           0 :         if (property->num_values)
    3965           0 :                 kfree(property->values);
    3966           0 :         drm_mode_object_put(dev, &property->base);
    3967           0 :         list_del(&property->head);
    3968           0 :         kfree(property);
    3969           0 : }
    3970             : EXPORT_SYMBOL(drm_property_destroy);
    3971             : 
    3972             : /**
    3973             :  * drm_object_attach_property - attach a property to a modeset object
    3974             :  * @obj: drm modeset object
    3975             :  * @property: property to attach
    3976             :  * @init_val: initial value of the property
    3977             :  *
    3978             :  * This attaches the given property to the modeset object with the given initial
    3979             :  * value. Currently this function cannot fail since the properties are stored in
    3980             :  * a statically sized array.
    3981             :  */
    3982           0 : void drm_object_attach_property(struct drm_mode_object *obj,
    3983             :                                 struct drm_property *property,
    3984             :                                 uint64_t init_val)
    3985             : {
    3986           0 :         int count = obj->properties->count;
    3987             : 
    3988           0 :         if (count == DRM_OBJECT_MAX_PROPERTY) {
    3989           0 :                 WARN(1, "Failed to attach object property (type: 0x%x). Please "
    3990             :                         "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
    3991             :                         "you see this message on the same object type.\n",
    3992             :                         obj->type);
    3993           0 :                 return;
    3994             :         }
    3995             : 
    3996           0 :         obj->properties->properties[count] = property;
    3997           0 :         obj->properties->values[count] = init_val;
    3998           0 :         obj->properties->count++;
    3999           0 :         if (property->flags & DRM_MODE_PROP_ATOMIC)
    4000           0 :                 obj->properties->atomic_count++;
    4001           0 : }
    4002             : EXPORT_SYMBOL(drm_object_attach_property);
    4003             : 
    4004             : /**
    4005             :  * drm_object_property_set_value - set the value of a property
    4006             :  * @obj: drm mode object to set property value for
    4007             :  * @property: property to set
    4008             :  * @val: value the property should be set to
    4009             :  *
    4010             :  * This functions sets a given property on a given object. This function only
    4011             :  * changes the software state of the property, it does not call into the
    4012             :  * driver's ->set_property callback.
    4013             :  *
    4014             :  * Returns:
    4015             :  * Zero on success, error code on failure.
    4016             :  */
    4017           0 : int drm_object_property_set_value(struct drm_mode_object *obj,
    4018             :                                   struct drm_property *property, uint64_t val)
    4019             : {
    4020             :         int i;
    4021             : 
    4022           0 :         for (i = 0; i < obj->properties->count; i++) {
    4023           0 :                 if (obj->properties->properties[i] == property) {
    4024           0 :                         obj->properties->values[i] = val;
    4025           0 :                         return 0;
    4026             :                 }
    4027             :         }
    4028             : 
    4029           0 :         return -EINVAL;
    4030           0 : }
    4031             : EXPORT_SYMBOL(drm_object_property_set_value);
    4032             : 
    4033             : /**
    4034             :  * drm_object_property_get_value - retrieve the value of a property
    4035             :  * @obj: drm mode object to get property value from
    4036             :  * @property: property to retrieve
    4037             :  * @val: storage for the property value
    4038             :  *
    4039             :  * This function retrieves the softare state of the given property for the given
    4040             :  * property. Since there is no driver callback to retrieve the current property
    4041             :  * value this might be out of sync with the hardware, depending upon the driver
    4042             :  * and property.
    4043             :  *
    4044             :  * Returns:
    4045             :  * Zero on success, error code on failure.
    4046             :  */
    4047           0 : int drm_object_property_get_value(struct drm_mode_object *obj,
    4048             :                                   struct drm_property *property, uint64_t *val)
    4049             : {
    4050             :         int i;
    4051             : 
    4052             : #ifdef __OpenBSD__
    4053           0 :         if (obj->type == DRM_MODE_OBJECT_CONNECTOR) {
    4054           0 :                 struct drm_connector *connector = obj_to_connector(obj);
    4055             : 
    4056           0 :                 if (property == connector->backlight_property) {
    4057             :                         struct backlight_device *bd =
    4058           0 :                                 connector->backlight_device;
    4059             : 
    4060           0 :                         if (bd->props.type == BACKLIGHT_FIRMWARE)
    4061           0 :                                 *val = bd->ops->get_brightness(bd);
    4062             :                         else
    4063           0 :                                 *val = bd->props.brightness;
    4064             :                         return 0;
    4065             :                 }
    4066           0 :         }
    4067             : #endif
    4068             : 
    4069             :         /* read-only properties bypass atomic mechanism and still store
    4070             :          * their value in obj->properties->values[].. mostly to avoid
    4071             :          * having to deal w/ EDID and similar props in atomic paths:
    4072             :          */
    4073           0 :         if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) &&
    4074           0 :                         !(property->flags & DRM_MODE_PROP_IMMUTABLE))
    4075           0 :                 return drm_atomic_get_property(obj, property, val);
    4076             : 
    4077           0 :         for (i = 0; i < obj->properties->count; i++) {
    4078           0 :                 if (obj->properties->properties[i] == property) {
    4079           0 :                         *val = obj->properties->values[i];
    4080           0 :                         return 0;
    4081             :                 }
    4082             :         }
    4083             : 
    4084           0 :         return -EINVAL;
    4085           0 : }
    4086             : EXPORT_SYMBOL(drm_object_property_get_value);
    4087             : 
    4088             : /**
    4089             :  * drm_mode_getproperty_ioctl - get the property metadata
    4090             :  * @dev: DRM device
    4091             :  * @data: ioctl data
    4092             :  * @file_priv: DRM file info
    4093             :  *
    4094             :  * This function retrieves the metadata for a given property, like the different
    4095             :  * possible values for an enum property or the limits for a range property.
    4096             :  *
    4097             :  * Blob properties are special
    4098             :  *
    4099             :  * Called by the user via ioctl.
    4100             :  *
    4101             :  * Returns:
    4102             :  * Zero on success, negative errno on failure.
    4103             :  */
    4104           0 : int drm_mode_getproperty_ioctl(struct drm_device *dev,
    4105             :                                void *data, struct drm_file *file_priv)
    4106             : {
    4107           0 :         struct drm_mode_get_property *out_resp = data;
    4108             :         struct drm_property *property;
    4109             :         int enum_count = 0;
    4110             :         int value_count = 0;
    4111             :         int ret = 0, i;
    4112             :         int copied;
    4113             :         struct drm_property_enum *prop_enum;
    4114             :         struct drm_mode_property_enum __user *enum_ptr;
    4115             :         uint64_t __user *values_ptr;
    4116             : 
    4117           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    4118           0 :                 return -EINVAL;
    4119             : 
    4120           0 :         drm_modeset_lock_all(dev);
    4121           0 :         property = drm_property_find(dev, out_resp->prop_id);
    4122           0 :         if (!property) {
    4123             :                 ret = -ENOENT;
    4124           0 :                 goto done;
    4125             :         }
    4126             : 
    4127           0 :         if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
    4128           0 :                         drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
    4129           0 :                 list_for_each_entry(prop_enum, &property->enum_list, head)
    4130           0 :                         enum_count++;
    4131             :         }
    4132             : 
    4133           0 :         value_count = property->num_values;
    4134             : 
    4135           0 :         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
    4136           0 :         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
    4137           0 :         out_resp->flags = property->flags;
    4138             : 
    4139           0 :         if ((out_resp->count_values >= value_count) && value_count) {
    4140           0 :                 values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
    4141           0 :                 for (i = 0; i < value_count; i++) {
    4142           0 :                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
    4143             :                                 ret = -EFAULT;
    4144           0 :                                 goto done;
    4145             :                         }
    4146             :                 }
    4147             :         }
    4148           0 :         out_resp->count_values = value_count;
    4149             : 
    4150           0 :         if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
    4151           0 :                         drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
    4152           0 :                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
    4153             :                         copied = 0;
    4154           0 :                         enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
    4155           0 :                         list_for_each_entry(prop_enum, &property->enum_list, head) {
    4156             : 
    4157           0 :                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
    4158             :                                         ret = -EFAULT;
    4159           0 :                                         goto done;
    4160             :                                 }
    4161             : 
    4162           0 :                                 if (copy_to_user(&enum_ptr[copied].name,
    4163           0 :                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
    4164             :                                         ret = -EFAULT;
    4165           0 :                                         goto done;
    4166             :                                 }
    4167           0 :                                 copied++;
    4168             :                         }
    4169             :                 }
    4170           0 :                 out_resp->count_enum_blobs = enum_count;
    4171           0 :         }
    4172             : 
    4173             :         /*
    4174             :          * NOTE: The idea seems to have been to use this to read all the blob
    4175             :          * property values. But nothing ever added them to the corresponding
    4176             :          * list, userspace always used the special-purpose get_blob ioctl to
    4177             :          * read the value for a blob property. It also doesn't make a lot of
    4178             :          * sense to return values here when everything else is just metadata for
    4179             :          * the property itself.
    4180             :          */
    4181           0 :         if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
    4182           0 :                 out_resp->count_enum_blobs = 0;
    4183             : done:
    4184           0 :         drm_modeset_unlock_all(dev);
    4185           0 :         return ret;
    4186           0 : }
    4187             : 
    4188             : /**
    4189             :  * drm_property_create_blob - Create new blob property
    4190             :  *
    4191             :  * Creates a new blob property for a specified DRM device, optionally
    4192             :  * copying data.
    4193             :  *
    4194             :  * @dev: DRM device to create property for
    4195             :  * @length: Length to allocate for blob data
    4196             :  * @data: If specified, copies data into blob
    4197             :  *
    4198             :  * Returns:
    4199             :  * New blob property with a single reference on success, or an ERR_PTR
    4200             :  * value on failure.
    4201             :  */
    4202             : struct drm_property_blob *
    4203           0 : drm_property_create_blob(struct drm_device *dev, size_t length,
    4204             :                          const void *data)
    4205             : {
    4206             :         struct drm_property_blob *blob;
    4207             :         int ret;
    4208             : 
    4209           0 :         if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
    4210           0 :                 return ERR_PTR(-EINVAL);
    4211             : 
    4212           0 :         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
    4213           0 :         if (!blob)
    4214           0 :                 return ERR_PTR(-ENOMEM);
    4215             : 
    4216             :         /* This must be explicitly initialised, so we can safely call list_del
    4217             :          * on it in the removal handler, even if it isn't in a file list. */
    4218           0 :         INIT_LIST_HEAD(&blob->head_file);
    4219           0 :         blob->length = length;
    4220           0 :         blob->dev = dev;
    4221             : 
    4222           0 :         if (data)
    4223           0 :                 memcpy(blob->data, data, length);
    4224             : 
    4225           0 :         mutex_lock(&dev->mode_config.blob_lock);
    4226             : 
    4227           0 :         ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
    4228           0 :         if (ret) {
    4229           0 :                 kfree(blob);
    4230           0 :                 mutex_unlock(&dev->mode_config.blob_lock);
    4231           0 :                 return ERR_PTR(-EINVAL);
    4232             :         }
    4233             : 
    4234           0 :         kref_init(&blob->refcount);
    4235             : 
    4236           0 :         list_add_tail(&blob->head_global,
    4237           0 :                       &dev->mode_config.property_blob_list);
    4238             : 
    4239           0 :         mutex_unlock(&dev->mode_config.blob_lock);
    4240             : 
    4241           0 :         return blob;
    4242           0 : }
    4243             : EXPORT_SYMBOL(drm_property_create_blob);
    4244             : 
    4245             : /**
    4246             :  * drm_property_free_blob - Blob property destructor
    4247             :  *
    4248             :  * Internal free function for blob properties; must not be used directly.
    4249             :  *
    4250             :  * @kref: Reference
    4251             :  */
    4252           0 : static void drm_property_free_blob(struct kref *kref)
    4253             : {
    4254             :         struct drm_property_blob *blob =
    4255           0 :                 container_of(kref, struct drm_property_blob, refcount);
    4256             : 
    4257           0 :         WARN_ON(!mutex_is_locked(&blob->dev->mode_config.blob_lock));
    4258             : 
    4259           0 :         list_del(&blob->head_global);
    4260           0 :         list_del(&blob->head_file);
    4261           0 :         drm_mode_object_put(blob->dev, &blob->base);
    4262             : 
    4263           0 :         kfree(blob);
    4264           0 : }
    4265             : 
    4266             : /**
    4267             :  * drm_property_unreference_blob - Unreference a blob property
    4268             :  *
    4269             :  * Drop a reference on a blob property. May free the object.
    4270             :  *
    4271             :  * @blob: Pointer to blob property
    4272             :  */
    4273           0 : void drm_property_unreference_blob(struct drm_property_blob *blob)
    4274             : {
    4275             :         struct drm_device *dev;
    4276             : 
    4277           0 :         if (!blob)
    4278           0 :                 return;
    4279             : 
    4280           0 :         dev = blob->dev;
    4281             : 
    4282             :         DRM_DEBUG("%p: blob ID: %d (%d)\n", blob, blob->base.id, atomic_read(&blob->refcount.refcount));
    4283             : 
    4284           0 :         if (kref_put_mutex(&blob->refcount, drm_property_free_blob,
    4285           0 :                            &dev->mode_config.blob_lock))
    4286           0 :                 mutex_unlock(&dev->mode_config.blob_lock);
    4287             :         else
    4288             :                 might_lock(&dev->mode_config.blob_lock);
    4289           0 : }
    4290             : EXPORT_SYMBOL(drm_property_unreference_blob);
    4291             : 
    4292             : /**
    4293             :  * drm_property_unreference_blob_locked - Unreference a blob property with blob_lock held
    4294             :  *
    4295             :  * Drop a reference on a blob property. May free the object. This must be
    4296             :  * called with blob_lock held.
    4297             :  *
    4298             :  * @blob: Pointer to blob property
    4299             :  */
    4300           0 : static void drm_property_unreference_blob_locked(struct drm_property_blob *blob)
    4301             : {
    4302           0 :         if (!blob)
    4303             :                 return;
    4304             : 
    4305             :         DRM_DEBUG("%p: blob ID: %d (%d)\n", blob, blob->base.id, atomic_read(&blob->refcount.refcount));
    4306             : 
    4307           0 :         kref_put(&blob->refcount, drm_property_free_blob);
    4308           0 : }
    4309             : 
    4310             : /**
    4311             :  * drm_property_destroy_user_blobs - destroy all blobs created by this client
    4312             :  * @dev:       DRM device
    4313             :  * @file_priv: destroy all blobs owned by this file handle
    4314             :  */
    4315           0 : void drm_property_destroy_user_blobs(struct drm_device *dev,
    4316             :                                      struct drm_file *file_priv)
    4317             : {
    4318             :         struct drm_property_blob *blob, *bt;
    4319             : 
    4320           0 :         mutex_lock(&dev->mode_config.blob_lock);
    4321             : 
    4322           0 :         list_for_each_entry_safe(blob, bt, &file_priv->blobs, head_file) {
    4323           0 :                 list_del_init(&blob->head_file);
    4324           0 :                 drm_property_unreference_blob_locked(blob);
    4325             :         }
    4326             : 
    4327           0 :         mutex_unlock(&dev->mode_config.blob_lock);
    4328           0 : }
    4329             : 
    4330             : /**
    4331             :  * drm_property_reference_blob - Take a reference on an existing property
    4332             :  *
    4333             :  * Take a new reference on an existing blob property.
    4334             :  *
    4335             :  * @blob: Pointer to blob property
    4336             :  */
    4337           0 : struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob)
    4338             : {
    4339             :         DRM_DEBUG("%p: blob ID: %d (%d)\n", blob, blob->base.id, atomic_read(&blob->refcount.refcount));
    4340           0 :         kref_get(&blob->refcount);
    4341           0 :         return blob;
    4342             : }
    4343             : EXPORT_SYMBOL(drm_property_reference_blob);
    4344             : 
    4345             : /*
    4346             :  * Like drm_property_lookup_blob, but does not return an additional reference.
    4347             :  * Must be called with blob_lock held.
    4348             :  */
    4349           0 : static struct drm_property_blob *__drm_property_lookup_blob(struct drm_device *dev,
    4350             :                                                             uint32_t id)
    4351             : {
    4352             :         struct drm_mode_object *obj = NULL;
    4353             :         struct drm_property_blob *blob;
    4354             : 
    4355           0 :         WARN_ON(!mutex_is_locked(&dev->mode_config.blob_lock));
    4356             : 
    4357           0 :         mutex_lock(&dev->mode_config.idr_mutex);
    4358           0 :         obj = idr_find(&dev->mode_config.crtc_idr, id);
    4359           0 :         if (!obj || (obj->type != DRM_MODE_OBJECT_BLOB) || (obj->id != id))
    4360           0 :                 blob = NULL;
    4361             :         else
    4362           0 :                 blob = obj_to_blob(obj);
    4363           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
    4364             : 
    4365           0 :         return blob;
    4366             : }
    4367             : 
    4368             : /**
    4369             :  * drm_property_lookup_blob - look up a blob property and take a reference
    4370             :  * @dev: drm device
    4371             :  * @id: id of the blob property
    4372             :  *
    4373             :  * If successful, this takes an additional reference to the blob property.
    4374             :  * callers need to make sure to eventually unreference the returned property
    4375             :  * again, using @drm_property_unreference_blob.
    4376             :  */
    4377           0 : struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
    4378             :                                                    uint32_t id)
    4379             : {
    4380             :         struct drm_property_blob *blob;
    4381             : 
    4382           0 :         mutex_lock(&dev->mode_config.blob_lock);
    4383           0 :         blob = __drm_property_lookup_blob(dev, id);
    4384           0 :         if (blob) {
    4385           0 :                 if (!kref_get_unless_zero(&blob->refcount))
    4386           0 :                         blob = NULL;
    4387             :         }
    4388           0 :         mutex_unlock(&dev->mode_config.blob_lock);
    4389             : 
    4390           0 :         return blob;
    4391             : }
    4392             : EXPORT_SYMBOL(drm_property_lookup_blob);
    4393             : 
    4394             : /**
    4395             :  * drm_property_replace_global_blob - atomically replace existing blob property
    4396             :  * @dev: drm device
    4397             :  * @replace: location of blob property pointer to be replaced
    4398             :  * @length: length of data for new blob, or 0 for no data
    4399             :  * @data: content for new blob, or NULL for no data
    4400             :  * @obj_holds_id: optional object for property holding blob ID
    4401             :  * @prop_holds_id: optional property holding blob ID
    4402             :  * @return 0 on success or error on failure
    4403             :  *
    4404             :  * This function will atomically replace a global property in the blob list,
    4405             :  * optionally updating a property which holds the ID of that property. It is
    4406             :  * guaranteed to be atomic: no caller will be allowed to see intermediate
    4407             :  * results, and either the entire operation will succeed and clean up the
    4408             :  * previous property, or it will fail and the state will be unchanged.
    4409             :  *
    4410             :  * If length is 0 or data is NULL, no new blob will be created, and the holding
    4411             :  * property, if specified, will be set to 0.
    4412             :  *
    4413             :  * Access to the replace pointer is assumed to be protected by the caller, e.g.
    4414             :  * by holding the relevant modesetting object lock for its parent.
    4415             :  *
    4416             :  * For example, a drm_connector has a 'PATH' property, which contains the ID
    4417             :  * of a blob property with the value of the MST path information. Calling this
    4418             :  * function with replace pointing to the connector's path_blob_ptr, length and
    4419             :  * data set for the new path information, obj_holds_id set to the connector's
    4420             :  * base object, and prop_holds_id set to the path property name, will perform
    4421             :  * a completely atomic update. The access to path_blob_ptr is protected by the
    4422             :  * caller holding a lock on the connector.
    4423             :  */
    4424           0 : static int drm_property_replace_global_blob(struct drm_device *dev,
    4425             :                                             struct drm_property_blob **replace,
    4426             :                                             size_t length,
    4427             :                                             const void *data,
    4428             :                                             struct drm_mode_object *obj_holds_id,
    4429             :                                             struct drm_property *prop_holds_id)
    4430             : {
    4431             :         struct drm_property_blob *new_blob = NULL;
    4432             :         struct drm_property_blob *old_blob = NULL;
    4433             :         int ret;
    4434             : 
    4435           0 :         WARN_ON(replace == NULL);
    4436             : 
    4437           0 :         old_blob = *replace;
    4438             : 
    4439           0 :         if (length && data) {
    4440           0 :                 new_blob = drm_property_create_blob(dev, length, data);
    4441           0 :                 if (IS_ERR(new_blob))
    4442           0 :                         return PTR_ERR(new_blob);
    4443             :         }
    4444             : 
    4445             :         /* This does not need to be synchronised with blob_lock, as the
    4446             :          * get_properties ioctl locks all modesetting objects, and
    4447             :          * obj_holds_id must be locked before calling here, so we cannot
    4448             :          * have its value out of sync with the list membership modified
    4449             :          * below under blob_lock. */
    4450           0 :         if (obj_holds_id) {
    4451           0 :                 ret = drm_object_property_set_value(obj_holds_id,
    4452             :                                                     prop_holds_id,
    4453           0 :                                                     new_blob ?
    4454           0 :                                                         new_blob->base.id : 0);
    4455           0 :                 if (ret != 0)
    4456             :                         goto err_created;
    4457             :         }
    4458             : 
    4459           0 :         drm_property_unreference_blob(old_blob);
    4460           0 :         *replace = new_blob;
    4461             : 
    4462           0 :         return 0;
    4463             : 
    4464             : err_created:
    4465           0 :         drm_property_unreference_blob(new_blob);
    4466           0 :         return ret;
    4467           0 : }
    4468             : 
    4469             : /**
    4470             :  * drm_mode_getblob_ioctl - get the contents of a blob property value
    4471             :  * @dev: DRM device
    4472             :  * @data: ioctl data
    4473             :  * @file_priv: DRM file info
    4474             :  *
    4475             :  * This function retrieves the contents of a blob property. The value stored in
    4476             :  * an object's blob property is just a normal modeset object id.
    4477             :  *
    4478             :  * Called by the user via ioctl.
    4479             :  *
    4480             :  * Returns:
    4481             :  * Zero on success, negative errno on failure.
    4482             :  */
    4483           0 : int drm_mode_getblob_ioctl(struct drm_device *dev,
    4484             :                            void *data, struct drm_file *file_priv)
    4485             : {
    4486           0 :         struct drm_mode_get_blob *out_resp = data;
    4487             :         struct drm_property_blob *blob;
    4488             :         int ret = 0;
    4489             :         void __user *blob_ptr;
    4490             : 
    4491           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    4492           0 :                 return -EINVAL;
    4493             : 
    4494           0 :         drm_modeset_lock_all(dev);
    4495           0 :         mutex_lock(&dev->mode_config.blob_lock);
    4496           0 :         blob = __drm_property_lookup_blob(dev, out_resp->blob_id);
    4497           0 :         if (!blob) {
    4498             :                 ret = -ENOENT;
    4499           0 :                 goto done;
    4500             :         }
    4501             : 
    4502           0 :         if (out_resp->length == blob->length) {
    4503           0 :                 blob_ptr = (void __user *)(unsigned long)out_resp->data;
    4504           0 :                 if (copy_to_user(blob_ptr, blob->data, blob->length)) {
    4505             :                         ret = -EFAULT;
    4506           0 :                         goto done;
    4507             :                 }
    4508             :         }
    4509           0 :         out_resp->length = blob->length;
    4510             : 
    4511             : done:
    4512           0 :         mutex_unlock(&dev->mode_config.blob_lock);
    4513           0 :         drm_modeset_unlock_all(dev);
    4514           0 :         return ret;
    4515           0 : }
    4516             : 
    4517             : /**
    4518             :  * drm_mode_createblob_ioctl - create a new blob property
    4519             :  * @dev: DRM device
    4520             :  * @data: ioctl data
    4521             :  * @file_priv: DRM file info
    4522             :  *
    4523             :  * This function creates a new blob property with user-defined values. In order
    4524             :  * to give us sensible validation and checking when creating, rather than at
    4525             :  * every potential use, we also require a type to be provided upfront.
    4526             :  *
    4527             :  * Called by the user via ioctl.
    4528             :  *
    4529             :  * Returns:
    4530             :  * Zero on success, negative errno on failure.
    4531             :  */
    4532           0 : int drm_mode_createblob_ioctl(struct drm_device *dev,
    4533             :                               void *data, struct drm_file *file_priv)
    4534             : {
    4535           0 :         struct drm_mode_create_blob *out_resp = data;
    4536             :         struct drm_property_blob *blob;
    4537             :         void __user *blob_ptr;
    4538             :         int ret = 0;
    4539             : 
    4540           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    4541           0 :                 return -EINVAL;
    4542             : 
    4543           0 :         blob = drm_property_create_blob(dev, out_resp->length, NULL);
    4544           0 :         if (IS_ERR(blob))
    4545           0 :                 return PTR_ERR(blob);
    4546             : 
    4547           0 :         blob_ptr = (void __user *)(unsigned long)out_resp->data;
    4548           0 :         if (copy_from_user(blob->data, blob_ptr, out_resp->length)) {
    4549             :                 ret = -EFAULT;
    4550             :                 goto out_blob;
    4551             :         }
    4552             : 
    4553             :         /* Dropping the lock between create_blob and our access here is safe
    4554             :          * as only the same file_priv can remove the blob; at this point, it is
    4555             :          * not associated with any file_priv. */
    4556           0 :         mutex_lock(&dev->mode_config.blob_lock);
    4557           0 :         out_resp->blob_id = blob->base.id;
    4558           0 :         list_add_tail(&blob->head_file, &file_priv->blobs);
    4559           0 :         mutex_unlock(&dev->mode_config.blob_lock);
    4560             : 
    4561           0 :         return 0;
    4562             : 
    4563             : out_blob:
    4564           0 :         drm_property_unreference_blob(blob);
    4565           0 :         return ret;
    4566           0 : }
    4567             : 
    4568             : /**
    4569             :  * drm_mode_destroyblob_ioctl - destroy a user blob property
    4570             :  * @dev: DRM device
    4571             :  * @data: ioctl data
    4572             :  * @file_priv: DRM file info
    4573             :  *
    4574             :  * Destroy an existing user-defined blob property.
    4575             :  *
    4576             :  * Called by the user via ioctl.
    4577             :  *
    4578             :  * Returns:
    4579             :  * Zero on success, negative errno on failure.
    4580             :  */
    4581           0 : int drm_mode_destroyblob_ioctl(struct drm_device *dev,
    4582             :                                void *data, struct drm_file *file_priv)
    4583             : {
    4584           0 :         struct drm_mode_destroy_blob *out_resp = data;
    4585             :         struct drm_property_blob *blob = NULL, *bt;
    4586             :         bool found = false;
    4587             :         int ret = 0;
    4588             : 
    4589           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    4590           0 :                 return -EINVAL;
    4591             : 
    4592           0 :         mutex_lock(&dev->mode_config.blob_lock);
    4593           0 :         blob = __drm_property_lookup_blob(dev, out_resp->blob_id);
    4594           0 :         if (!blob) {
    4595             :                 ret = -ENOENT;
    4596           0 :                 goto err;
    4597             :         }
    4598             : 
    4599             :         /* Ensure the property was actually created by this user. */
    4600           0 :         list_for_each_entry(bt, &file_priv->blobs, head_file) {
    4601           0 :                 if (bt == blob) {
    4602             :                         found = true;
    4603           0 :                         break;
    4604             :                 }
    4605             :         }
    4606             : 
    4607           0 :         if (!found) {
    4608             :                 ret = -EPERM;
    4609           0 :                 goto err;
    4610             :         }
    4611             : 
    4612             :         /* We must drop head_file here, because we may not be the last
    4613             :          * reference on the blob. */
    4614           0 :         list_del_init(&blob->head_file);
    4615           0 :         drm_property_unreference_blob_locked(blob);
    4616           0 :         mutex_unlock(&dev->mode_config.blob_lock);
    4617             : 
    4618           0 :         return 0;
    4619             : 
    4620             : err:
    4621           0 :         mutex_unlock(&dev->mode_config.blob_lock);
    4622           0 :         return ret;
    4623           0 : }
    4624             : 
    4625             : /**
    4626             :  * drm_mode_connector_set_path_property - set tile property on connector
    4627             :  * @connector: connector to set property on.
    4628             :  * @path: path to use for property; must not be NULL.
    4629             :  *
    4630             :  * This creates a property to expose to userspace to specify a
    4631             :  * connector path. This is mainly used for DisplayPort MST where
    4632             :  * connectors have a topology and we want to allow userspace to give
    4633             :  * them more meaningful names.
    4634             :  *
    4635             :  * Returns:
    4636             :  * Zero on success, negative errno on failure.
    4637             :  */
    4638           0 : int drm_mode_connector_set_path_property(struct drm_connector *connector,
    4639             :                                          const char *path)
    4640             : {
    4641           0 :         struct drm_device *dev = connector->dev;
    4642             :         int ret;
    4643             : 
    4644           0 :         ret = drm_property_replace_global_blob(dev,
    4645           0 :                                                &connector->path_blob_ptr,
    4646           0 :                                                strlen(path) + 1,
    4647             :                                                path,
    4648           0 :                                                &connector->base,
    4649           0 :                                                dev->mode_config.path_property);
    4650           0 :         return ret;
    4651             : }
    4652             : EXPORT_SYMBOL(drm_mode_connector_set_path_property);
    4653             : 
    4654             : /**
    4655             :  * drm_mode_connector_set_tile_property - set tile property on connector
    4656             :  * @connector: connector to set property on.
    4657             :  *
    4658             :  * This looks up the tile information for a connector, and creates a
    4659             :  * property for userspace to parse if it exists. The property is of
    4660             :  * the form of 8 integers using ':' as a separator.
    4661             :  *
    4662             :  * Returns:
    4663             :  * Zero on success, errno on failure.
    4664             :  */
    4665           0 : int drm_mode_connector_set_tile_property(struct drm_connector *connector)
    4666             : {
    4667           0 :         struct drm_device *dev = connector->dev;
    4668           0 :         char tile[256];
    4669             :         int ret;
    4670             : 
    4671           0 :         if (!connector->has_tile) {
    4672           0 :                 ret  = drm_property_replace_global_blob(dev,
    4673           0 :                                                         &connector->tile_blob_ptr,
    4674             :                                                         0,
    4675             :                                                         NULL,
    4676           0 :                                                         &connector->base,
    4677           0 :                                                         dev->mode_config.tile_property);
    4678           0 :                 return ret;
    4679             :         }
    4680             : 
    4681           0 :         snprintf(tile, 256, "%d:%d:%d:%d:%d:%d:%d:%d",
    4682           0 :                  connector->tile_group->id, connector->tile_is_single_monitor,
    4683           0 :                  connector->num_h_tile, connector->num_v_tile,
    4684           0 :                  connector->tile_h_loc, connector->tile_v_loc,
    4685           0 :                  connector->tile_h_size, connector->tile_v_size);
    4686             : 
    4687           0 :         ret = drm_property_replace_global_blob(dev,
    4688           0 :                                                &connector->tile_blob_ptr,
    4689           0 :                                                strlen(tile) + 1,
    4690             :                                                tile,
    4691           0 :                                                &connector->base,
    4692           0 :                                                dev->mode_config.tile_property);
    4693           0 :         return ret;
    4694           0 : }
    4695             : EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
    4696             : 
    4697             : /**
    4698             :  * drm_mode_connector_update_edid_property - update the edid property of a connector
    4699             :  * @connector: drm connector
    4700             :  * @edid: new value of the edid property
    4701             :  *
    4702             :  * This function creates a new blob modeset object and assigns its id to the
    4703             :  * connector's edid property.
    4704             :  *
    4705             :  * Returns:
    4706             :  * Zero on success, negative errno on failure.
    4707             :  */
    4708           0 : int drm_mode_connector_update_edid_property(struct drm_connector *connector,
    4709             :                                             const struct edid *edid)
    4710             : {
    4711           0 :         struct drm_device *dev = connector->dev;
    4712             :         size_t size = 0;
    4713             :         int ret;
    4714             : 
    4715             :         /* ignore requests to set edid when overridden */
    4716           0 :         if (connector->override_edid)
    4717           0 :                 return 0;
    4718             : 
    4719           0 :         if (edid)
    4720           0 :                 size = EDID_LENGTH * (1 + edid->extensions);
    4721             : 
    4722           0 :         ret = drm_property_replace_global_blob(dev,
    4723           0 :                                                &connector->edid_blob_ptr,
    4724             :                                                size,
    4725           0 :                                                edid,
    4726           0 :                                                &connector->base,
    4727           0 :                                                dev->mode_config.edid_property);
    4728           0 :         return ret;
    4729           0 : }
    4730             : EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
    4731             : 
    4732             : /* Some properties could refer to dynamic refcnt'd objects, or things that
    4733             :  * need special locking to handle lifetime issues (ie. to ensure the prop
    4734             :  * value doesn't become invalid part way through the property update due to
    4735             :  * race).  The value returned by reference via 'obj' should be passed back
    4736             :  * to drm_property_change_valid_put() after the property is set (and the
    4737             :  * object to which the property is attached has a chance to take it's own
    4738             :  * reference).
    4739             :  */
    4740           0 : bool drm_property_change_valid_get(struct drm_property *property,
    4741             :                                          uint64_t value, struct drm_mode_object **ref)
    4742             : {
    4743             :         int i;
    4744             : 
    4745           0 :         if (property->flags & DRM_MODE_PROP_IMMUTABLE)
    4746           0 :                 return false;
    4747             : 
    4748           0 :         *ref = NULL;
    4749             : 
    4750           0 :         if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
    4751           0 :                 if (value < property->values[0] || value > property->values[1])
    4752           0 :                         return false;
    4753           0 :                 return true;
    4754           0 :         } else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) {
    4755           0 :                 int64_t svalue = U642I64(value);
    4756             : 
    4757           0 :                 if (svalue < U642I64(property->values[0]) ||
    4758           0 :                                 svalue > U642I64(property->values[1]))
    4759           0 :                         return false;
    4760           0 :                 return true;
    4761           0 :         } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
    4762             :                 uint64_t valid_mask = 0;
    4763             : 
    4764           0 :                 for (i = 0; i < property->num_values; i++)
    4765           0 :                         valid_mask |= (1ULL << property->values[i]);
    4766           0 :                 return !(value & ~valid_mask);
    4767           0 :         } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
    4768             :                 struct drm_property_blob *blob;
    4769             : 
    4770           0 :                 if (value == 0)
    4771           0 :                         return true;
    4772             : 
    4773           0 :                 blob = drm_property_lookup_blob(property->dev, value);
    4774           0 :                 if (blob) {
    4775           0 :                         *ref = &blob->base;
    4776           0 :                         return true;
    4777             :                 } else {
    4778           0 :                         return false;
    4779             :                 }
    4780           0 :         } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
    4781             :                 /* a zero value for an object property translates to null: */
    4782           0 :                 if (value == 0)
    4783           0 :                         return true;
    4784             : 
    4785             :                 /* handle refcnt'd objects specially: */
    4786           0 :                 if (property->values[0] == DRM_MODE_OBJECT_FB) {
    4787             :                         struct drm_framebuffer *fb;
    4788           0 :                         fb = drm_framebuffer_lookup(property->dev, value);
    4789           0 :                         if (fb) {
    4790           0 :                                 *ref = &fb->base;
    4791           0 :                                 return true;
    4792             :                         } else {
    4793           0 :                                 return false;
    4794             :                         }
    4795             :                 } else {
    4796           0 :                         return _object_find(property->dev, value, property->values[0]) != NULL;
    4797             :                 }
    4798             :         }
    4799             : 
    4800           0 :         for (i = 0; i < property->num_values; i++)
    4801           0 :                 if (property->values[i] == value)
    4802           0 :                         return true;
    4803           0 :         return false;
    4804           0 : }
    4805             : 
    4806           0 : void drm_property_change_valid_put(struct drm_property *property,
    4807             :                 struct drm_mode_object *ref)
    4808             : {
    4809           0 :         if (!ref)
    4810             :                 return;
    4811             : 
    4812           0 :         if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
    4813           0 :                 if (property->values[0] == DRM_MODE_OBJECT_FB)
    4814           0 :                         drm_framebuffer_unreference(obj_to_fb(ref));
    4815           0 :         } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
    4816           0 :                 drm_property_unreference_blob(obj_to_blob(ref));
    4817           0 : }
    4818             : 
    4819             : /**
    4820             :  * drm_mode_connector_property_set_ioctl - set the current value of a connector property
    4821             :  * @dev: DRM device
    4822             :  * @data: ioctl data
    4823             :  * @file_priv: DRM file info
    4824             :  *
    4825             :  * This function sets the current value for a connectors's property. It also
    4826             :  * calls into a driver's ->set_property callback to update the hardware state
    4827             :  *
    4828             :  * Called by the user via ioctl.
    4829             :  *
    4830             :  * Returns:
    4831             :  * Zero on success, negative errno on failure.
    4832             :  */
    4833           0 : int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
    4834             :                                        void *data, struct drm_file *file_priv)
    4835             : {
    4836           0 :         struct drm_mode_connector_set_property *conn_set_prop = data;
    4837           0 :         struct drm_mode_obj_set_property obj_set_prop = {
    4838           0 :                 .value = conn_set_prop->value,
    4839           0 :                 .prop_id = conn_set_prop->prop_id,
    4840           0 :                 .obj_id = conn_set_prop->connector_id,
    4841             :                 .obj_type = DRM_MODE_OBJECT_CONNECTOR
    4842             :         };
    4843             : 
    4844             :         /* It does all the locking and checking we need */
    4845           0 :         return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv);
    4846           0 : }
    4847             : 
    4848           0 : static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
    4849             :                                            struct drm_property *property,
    4850             :                                            uint64_t value)
    4851             : {
    4852             :         int ret = -EINVAL;
    4853           0 :         struct drm_connector *connector = obj_to_connector(obj);
    4854             : 
    4855             :         /* Do DPMS ourselves */
    4856           0 :         if (property == connector->dev->mode_config.dpms_property) {
    4857             :                 ret = 0;
    4858           0 :                 if (connector->funcs->dpms)
    4859           0 :                         ret = (*connector->funcs->dpms)(connector, (int)value);
    4860             : #ifdef __OpenBSD__
    4861           0 :         } else if (property == connector->backlight_property) {
    4862             :                 ret = 0;
    4863           0 :                 connector->backlight_device->props.brightness = value;
    4864           0 :                 backlight_schedule_update_status(connector->backlight_device);
    4865             : #endif
    4866           0 :         } else if (connector->funcs->set_property)
    4867           0 :                 ret = connector->funcs->set_property(connector, property, value);
    4868             : 
    4869             :         /* store the property value if successful */
    4870           0 :         if (!ret)
    4871           0 :                 drm_object_property_set_value(&connector->base, property, value);
    4872           0 :         return ret;
    4873             : }
    4874             : 
    4875           0 : static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
    4876             :                                       struct drm_property *property,
    4877             :                                       uint64_t value)
    4878             : {
    4879             :         int ret = -EINVAL;
    4880           0 :         struct drm_crtc *crtc = obj_to_crtc(obj);
    4881             : 
    4882           0 :         if (crtc->funcs->set_property)
    4883           0 :                 ret = crtc->funcs->set_property(crtc, property, value);
    4884           0 :         if (!ret)
    4885           0 :                 drm_object_property_set_value(obj, property, value);
    4886             : 
    4887           0 :         return ret;
    4888             : }
    4889             : 
    4890             : /**
    4891             :  * drm_mode_plane_set_obj_prop - set the value of a property
    4892             :  * @plane: drm plane object to set property value for
    4893             :  * @property: property to set
    4894             :  * @value: value the property should be set to
    4895             :  *
    4896             :  * This functions sets a given property on a given plane object. This function
    4897             :  * calls the driver's ->set_property callback and changes the software state of
    4898             :  * the property if the callback succeeds.
    4899             :  *
    4900             :  * Returns:
    4901             :  * Zero on success, error code on failure.
    4902             :  */
    4903           0 : int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
    4904             :                                 struct drm_property *property,
    4905             :                                 uint64_t value)
    4906             : {
    4907             :         int ret = -EINVAL;
    4908           0 :         struct drm_mode_object *obj = &plane->base;
    4909             : 
    4910           0 :         if (plane->funcs->set_property)
    4911           0 :                 ret = plane->funcs->set_property(plane, property, value);
    4912           0 :         if (!ret)
    4913           0 :                 drm_object_property_set_value(obj, property, value);
    4914             : 
    4915           0 :         return ret;
    4916             : }
    4917             : EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
    4918             : 
    4919             : /**
    4920             :  * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
    4921             :  * @dev: DRM device
    4922             :  * @data: ioctl data
    4923             :  * @file_priv: DRM file info
    4924             :  *
    4925             :  * This function retrieves the current value for an object's property. Compared
    4926             :  * to the connector specific ioctl this one is extended to also work on crtc and
    4927             :  * plane objects.
    4928             :  *
    4929             :  * Called by the user via ioctl.
    4930             :  *
    4931             :  * Returns:
    4932             :  * Zero on success, negative errno on failure.
    4933             :  */
    4934           0 : int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
    4935             :                                       struct drm_file *file_priv)
    4936             : {
    4937           0 :         struct drm_mode_obj_get_properties *arg = data;
    4938             :         struct drm_mode_object *obj;
    4939             :         int ret = 0;
    4940             : 
    4941           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    4942           0 :                 return -EINVAL;
    4943             : 
    4944           0 :         drm_modeset_lock_all(dev);
    4945             : 
    4946           0 :         obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
    4947           0 :         if (!obj) {
    4948             :                 ret = -ENOENT;
    4949           0 :                 goto out;
    4950             :         }
    4951           0 :         if (!obj->properties) {
    4952             :                 ret = -EINVAL;
    4953           0 :                 goto out;
    4954             :         }
    4955             : 
    4956           0 :         ret = get_properties(obj, file_priv->atomic,
    4957           0 :                         (uint32_t __user *)(unsigned long)(arg->props_ptr),
    4958           0 :                         (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
    4959           0 :                         &arg->count_props);
    4960             : 
    4961             : out:
    4962           0 :         drm_modeset_unlock_all(dev);
    4963           0 :         return ret;
    4964           0 : }
    4965             : 
    4966             : /**
    4967             :  * drm_mode_obj_set_property_ioctl - set the current value of an object's property
    4968             :  * @dev: DRM device
    4969             :  * @data: ioctl data
    4970             :  * @file_priv: DRM file info
    4971             :  *
    4972             :  * This function sets the current value for an object's property. It also calls
    4973             :  * into a driver's ->set_property callback to update the hardware state.
    4974             :  * Compared to the connector specific ioctl this one is extended to also work on
    4975             :  * crtc and plane objects.
    4976             :  *
    4977             :  * Called by the user via ioctl.
    4978             :  *
    4979             :  * Returns:
    4980             :  * Zero on success, negative errno on failure.
    4981             :  */
    4982           0 : int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
    4983             :                                     struct drm_file *file_priv)
    4984             : {
    4985           0 :         struct drm_mode_obj_set_property *arg = data;
    4986             :         struct drm_mode_object *arg_obj;
    4987             :         struct drm_mode_object *prop_obj;
    4988             :         struct drm_property *property;
    4989             :         int i, ret = -EINVAL;
    4990           0 :         struct drm_mode_object *ref;
    4991             : 
    4992           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    4993           0 :                 return -EINVAL;
    4994             : 
    4995           0 :         drm_modeset_lock_all(dev);
    4996             : 
    4997           0 :         arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
    4998           0 :         if (!arg_obj) {
    4999             :                 ret = -ENOENT;
    5000           0 :                 goto out;
    5001             :         }
    5002           0 :         if (!arg_obj->properties)
    5003             :                 goto out;
    5004             : 
    5005           0 :         for (i = 0; i < arg_obj->properties->count; i++)
    5006           0 :                 if (arg_obj->properties->properties[i]->base.id == arg->prop_id)
    5007             :                         break;
    5008             : 
    5009           0 :         if (i == arg_obj->properties->count)
    5010             :                 goto out;
    5011             : 
    5012           0 :         prop_obj = drm_mode_object_find(dev, arg->prop_id,
    5013             :                                         DRM_MODE_OBJECT_PROPERTY);
    5014           0 :         if (!prop_obj) {
    5015             :                 ret = -ENOENT;
    5016           0 :                 goto out;
    5017             :         }
    5018           0 :         property = obj_to_property(prop_obj);
    5019             : 
    5020           0 :         if (!drm_property_change_valid_get(property, arg->value, &ref))
    5021             :                 goto out;
    5022             : 
    5023           0 :         switch (arg_obj->type) {
    5024             :         case DRM_MODE_OBJECT_CONNECTOR:
    5025           0 :                 ret = drm_mode_connector_set_obj_prop(arg_obj, property,
    5026           0 :                                                       arg->value);
    5027           0 :                 break;
    5028             :         case DRM_MODE_OBJECT_CRTC:
    5029           0 :                 ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
    5030           0 :                 break;
    5031             :         case DRM_MODE_OBJECT_PLANE:
    5032           0 :                 ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
    5033           0 :                                                   property, arg->value);
    5034           0 :                 break;
    5035             :         }
    5036             : 
    5037           0 :         drm_property_change_valid_put(property, ref);
    5038             : 
    5039             : out:
    5040           0 :         drm_modeset_unlock_all(dev);
    5041           0 :         return ret;
    5042           0 : }
    5043             : 
    5044             : /**
    5045             :  * drm_mode_connector_attach_encoder - attach a connector to an encoder
    5046             :  * @connector: connector to attach
    5047             :  * @encoder: encoder to attach @connector to
    5048             :  *
    5049             :  * This function links up a connector to an encoder. Note that the routing
    5050             :  * restrictions between encoders and crtcs are exposed to userspace through the
    5051             :  * possible_clones and possible_crtcs bitmasks.
    5052             :  *
    5053             :  * Returns:
    5054             :  * Zero on success, negative errno on failure.
    5055             :  */
    5056           0 : int drm_mode_connector_attach_encoder(struct drm_connector *connector,
    5057             :                                       struct drm_encoder *encoder)
    5058             : {
    5059             :         int i;
    5060             : 
    5061           0 :         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
    5062           0 :                 if (connector->encoder_ids[i] == 0) {
    5063           0 :                         connector->encoder_ids[i] = encoder->base.id;
    5064           0 :                         return 0;
    5065             :                 }
    5066             :         }
    5067           0 :         return -ENOMEM;
    5068           0 : }
    5069             : EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
    5070             : 
    5071             : /**
    5072             :  * drm_mode_crtc_set_gamma_size - set the gamma table size
    5073             :  * @crtc: CRTC to set the gamma table size for
    5074             :  * @gamma_size: size of the gamma table
    5075             :  *
    5076             :  * Drivers which support gamma tables should set this to the supported gamma
    5077             :  * table size when initializing the CRTC. Currently the drm core only supports a
    5078             :  * fixed gamma table size.
    5079             :  *
    5080             :  * Returns:
    5081             :  * Zero on success, negative errno on failure.
    5082             :  */
    5083           0 : int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
    5084             :                                  int gamma_size)
    5085             : {
    5086           0 :         crtc->gamma_size = gamma_size;
    5087             : 
    5088           0 :         crtc->gamma_store = kcalloc(gamma_size, sizeof(uint16_t) * 3,
    5089             :                                     GFP_KERNEL);
    5090           0 :         if (!crtc->gamma_store) {
    5091           0 :                 crtc->gamma_size = 0;
    5092           0 :                 return -ENOMEM;
    5093             :         }
    5094             : 
    5095           0 :         return 0;
    5096           0 : }
    5097             : EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
    5098             : 
    5099             : /**
    5100             :  * drm_mode_gamma_set_ioctl - set the gamma table
    5101             :  * @dev: DRM device
    5102             :  * @data: ioctl data
    5103             :  * @file_priv: DRM file info
    5104             :  *
    5105             :  * Set the gamma table of a CRTC to the one passed in by the user. Userspace can
    5106             :  * inquire the required gamma table size through drm_mode_gamma_get_ioctl.
    5107             :  *
    5108             :  * Called by the user via ioctl.
    5109             :  *
    5110             :  * Returns:
    5111             :  * Zero on success, negative errno on failure.
    5112             :  */
    5113           0 : int drm_mode_gamma_set_ioctl(struct drm_device *dev,
    5114             :                              void *data, struct drm_file *file_priv)
    5115             : {
    5116           0 :         struct drm_mode_crtc_lut *crtc_lut = data;
    5117             :         struct drm_crtc *crtc;
    5118             :         void *r_base, *g_base, *b_base;
    5119             :         int size;
    5120             :         int ret = 0;
    5121             : 
    5122           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    5123           0 :                 return -EINVAL;
    5124             : 
    5125           0 :         drm_modeset_lock_all(dev);
    5126           0 :         crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
    5127           0 :         if (!crtc) {
    5128             :                 ret = -ENOENT;
    5129           0 :                 goto out;
    5130             :         }
    5131             : 
    5132           0 :         if (crtc->funcs->gamma_set == NULL) {
    5133             :                 ret = -ENOSYS;
    5134           0 :                 goto out;
    5135             :         }
    5136             : 
    5137             :         /* memcpy into gamma store */
    5138           0 :         if (crtc_lut->gamma_size != crtc->gamma_size) {
    5139             :                 ret = -EINVAL;
    5140           0 :                 goto out;
    5141             :         }
    5142             : 
    5143           0 :         size = crtc_lut->gamma_size * (sizeof(uint16_t));
    5144           0 :         r_base = crtc->gamma_store;
    5145           0 :         if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
    5146             :                 ret = -EFAULT;
    5147           0 :                 goto out;
    5148             :         }
    5149             : 
    5150           0 :         g_base = r_base + size;
    5151           0 :         if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
    5152             :                 ret = -EFAULT;
    5153           0 :                 goto out;
    5154             :         }
    5155             : 
    5156           0 :         b_base = g_base + size;
    5157           0 :         if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
    5158             :                 ret = -EFAULT;
    5159           0 :                 goto out;
    5160             :         }
    5161             : 
    5162           0 :         crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
    5163             : 
    5164             : out:
    5165           0 :         drm_modeset_unlock_all(dev);
    5166           0 :         return ret;
    5167             : 
    5168           0 : }
    5169             : 
    5170             : /**
    5171             :  * drm_mode_gamma_get_ioctl - get the gamma table
    5172             :  * @dev: DRM device
    5173             :  * @data: ioctl data
    5174             :  * @file_priv: DRM file info
    5175             :  *
    5176             :  * Copy the current gamma table into the storage provided. This also provides
    5177             :  * the gamma table size the driver expects, which can be used to size the
    5178             :  * allocated storage.
    5179             :  *
    5180             :  * Called by the user via ioctl.
    5181             :  *
    5182             :  * Returns:
    5183             :  * Zero on success, negative errno on failure.
    5184             :  */
    5185           0 : int drm_mode_gamma_get_ioctl(struct drm_device *dev,
    5186             :                              void *data, struct drm_file *file_priv)
    5187             : {
    5188           0 :         struct drm_mode_crtc_lut *crtc_lut = data;
    5189             :         struct drm_crtc *crtc;
    5190             :         void *r_base, *g_base, *b_base;
    5191             :         int size;
    5192             :         int ret = 0;
    5193             : 
    5194           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    5195           0 :                 return -EINVAL;
    5196             : 
    5197           0 :         drm_modeset_lock_all(dev);
    5198           0 :         crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
    5199           0 :         if (!crtc) {
    5200             :                 ret = -ENOENT;
    5201           0 :                 goto out;
    5202             :         }
    5203             : 
    5204             :         /* memcpy into gamma store */
    5205           0 :         if (crtc_lut->gamma_size != crtc->gamma_size) {
    5206             :                 ret = -EINVAL;
    5207           0 :                 goto out;
    5208             :         }
    5209             : 
    5210           0 :         size = crtc_lut->gamma_size * (sizeof(uint16_t));
    5211           0 :         r_base = crtc->gamma_store;
    5212           0 :         if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
    5213             :                 ret = -EFAULT;
    5214           0 :                 goto out;
    5215             :         }
    5216             : 
    5217           0 :         g_base = r_base + size;
    5218           0 :         if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
    5219             :                 ret = -EFAULT;
    5220           0 :                 goto out;
    5221             :         }
    5222             : 
    5223           0 :         b_base = g_base + size;
    5224           0 :         if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
    5225             :                 ret = -EFAULT;
    5226           0 :                 goto out;
    5227             :         }
    5228             : out:
    5229           0 :         drm_modeset_unlock_all(dev);
    5230           0 :         return ret;
    5231           0 : }
    5232             : 
    5233             : /**
    5234             :  * drm_mode_page_flip_ioctl - schedule an asynchronous fb update
    5235             :  * @dev: DRM device
    5236             :  * @data: ioctl data
    5237             :  * @file_priv: DRM file info
    5238             :  *
    5239             :  * This schedules an asynchronous update on a given CRTC, called page flip.
    5240             :  * Optionally a drm event is generated to signal the completion of the event.
    5241             :  * Generic drivers cannot assume that a pageflip with changed framebuffer
    5242             :  * properties (including driver specific metadata like tiling layout) will work,
    5243             :  * but some drivers support e.g. pixel format changes through the pageflip
    5244             :  * ioctl.
    5245             :  *
    5246             :  * Called by the user via ioctl.
    5247             :  *
    5248             :  * Returns:
    5249             :  * Zero on success, negative errno on failure.
    5250             :  */
    5251           0 : int drm_mode_page_flip_ioctl(struct drm_device *dev,
    5252             :                              void *data, struct drm_file *file_priv)
    5253             : {
    5254           0 :         struct drm_mode_crtc_page_flip *page_flip = data;
    5255             :         struct drm_crtc *crtc;
    5256             :         struct drm_framebuffer *fb = NULL;
    5257             :         struct drm_pending_vblank_event *e = NULL;
    5258             :         unsigned long flags;
    5259             :         int ret = -EINVAL;
    5260             : 
    5261           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
    5262           0 :                 return -EINVAL;
    5263             : 
    5264           0 :         if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
    5265           0 :             page_flip->reserved != 0)
    5266           0 :                 return -EINVAL;
    5267             : 
    5268           0 :         if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
    5269           0 :                 return -EINVAL;
    5270             : 
    5271           0 :         crtc = drm_crtc_find(dev, page_flip->crtc_id);
    5272           0 :         if (!crtc)
    5273           0 :                 return -ENOENT;
    5274             : 
    5275           0 :         drm_modeset_lock_crtc(crtc, crtc->primary);
    5276           0 :         if (crtc->primary->fb == NULL) {
    5277             :                 /* The framebuffer is currently unbound, presumably
    5278             :                  * due to a hotplug event, that userspace has not
    5279             :                  * yet discovered.
    5280             :                  */
    5281             :                 ret = -EBUSY;
    5282           0 :                 goto out;
    5283             :         }
    5284             : 
    5285           0 :         if (crtc->funcs->page_flip == NULL)
    5286             :                 goto out;
    5287             : 
    5288           0 :         fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
    5289           0 :         if (!fb) {
    5290             :                 ret = -ENOENT;
    5291           0 :                 goto out;
    5292             :         }
    5293             : 
    5294           0 :         if (crtc->state) {
    5295           0 :                 const struct drm_plane_state *state = crtc->primary->state;
    5296             : 
    5297           0 :                 ret = check_src_coords(state->src_x, state->src_y,
    5298           0 :                                        state->src_w, state->src_h, fb);
    5299           0 :         } else {
    5300           0 :                 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb);
    5301             :         }
    5302           0 :         if (ret)
    5303             :                 goto out;
    5304             : 
    5305           0 :         if (crtc->primary->fb->pixel_format != fb->pixel_format) {
    5306             :                 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
    5307             :                 ret = -EINVAL;
    5308           0 :                 goto out;
    5309             :         }
    5310             : 
    5311           0 :         if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
    5312             :                 ret = -ENOMEM;
    5313           0 :                 spin_lock_irqsave(&dev->event_lock, flags);
    5314           0 :                 if (file_priv->event_space < sizeof(e->event)) {
    5315           0 :                         spin_unlock_irqrestore(&dev->event_lock, flags);
    5316           0 :                         goto out;
    5317             :                 }
    5318           0 :                 file_priv->event_space -= sizeof(e->event);
    5319           0 :                 spin_unlock_irqrestore(&dev->event_lock, flags);
    5320             : 
    5321           0 :                 e = kzalloc(sizeof(*e), GFP_KERNEL);
    5322           0 :                 if (e == NULL) {
    5323           0 :                         spin_lock_irqsave(&dev->event_lock, flags);
    5324           0 :                         file_priv->event_space += sizeof(e->event);
    5325           0 :                         spin_unlock_irqrestore(&dev->event_lock, flags);
    5326           0 :                         goto out;
    5327             :                 }
    5328             : 
    5329           0 :                 e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
    5330           0 :                 e->event.base.length = sizeof(e->event);
    5331           0 :                 e->event.user_data = page_flip->user_data;
    5332           0 :                 e->base.event = &e->event.base;
    5333           0 :                 e->base.file_priv = file_priv;
    5334           0 :                 e->base.destroy =
    5335             :                         (void (*) (struct drm_pending_event *)) kfree;
    5336           0 :         }
    5337             : 
    5338           0 :         crtc->primary->old_fb = crtc->primary->fb;
    5339           0 :         ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
    5340           0 :         if (ret) {
    5341           0 :                 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
    5342           0 :                         spin_lock_irqsave(&dev->event_lock, flags);
    5343           0 :                         file_priv->event_space += sizeof(e->event);
    5344           0 :                         spin_unlock_irqrestore(&dev->event_lock, flags);
    5345           0 :                         kfree(e);
    5346           0 :                 }
    5347             :                 /* Keep the old fb, don't unref it. */
    5348           0 :                 crtc->primary->old_fb = NULL;
    5349           0 :         } else {
    5350           0 :                 crtc->primary->fb = fb;
    5351             :                 /* Unref only the old framebuffer. */
    5352             :                 fb = NULL;
    5353             :         }
    5354             : 
    5355             : out:
    5356           0 :         if (fb)
    5357           0 :                 drm_framebuffer_unreference(fb);
    5358           0 :         if (crtc->primary->old_fb)
    5359           0 :                 drm_framebuffer_unreference(crtc->primary->old_fb);
    5360           0 :         crtc->primary->old_fb = NULL;
    5361           0 :         drm_modeset_unlock_crtc(crtc);
    5362             : 
    5363           0 :         return ret;
    5364           0 : }
    5365             : 
    5366             : /**
    5367             :  * drm_mode_config_reset - call ->reset callbacks
    5368             :  * @dev: drm device
    5369             :  *
    5370             :  * This functions calls all the crtc's, encoder's and connector's ->reset
    5371             :  * callback. Drivers can use this in e.g. their driver load or resume code to
    5372             :  * reset hardware and software state.
    5373             :  */
    5374           0 : void drm_mode_config_reset(struct drm_device *dev)
    5375             : {
    5376             :         struct drm_crtc *crtc;
    5377             :         struct drm_plane *plane;
    5378             :         struct drm_encoder *encoder;
    5379             :         struct drm_connector *connector;
    5380             : 
    5381           0 :         drm_for_each_plane(plane, dev)
    5382           0 :                 if (plane->funcs->reset)
    5383           0 :                         plane->funcs->reset(plane);
    5384             : 
    5385           0 :         drm_for_each_crtc(crtc, dev)
    5386           0 :                 if (crtc->funcs->reset)
    5387           0 :                         crtc->funcs->reset(crtc);
    5388             : 
    5389           0 :         drm_for_each_encoder(encoder, dev)
    5390           0 :                 if (encoder->funcs->reset)
    5391           0 :                         encoder->funcs->reset(encoder);
    5392             : 
    5393           0 :         mutex_lock(&dev->mode_config.mutex);
    5394           0 :         drm_for_each_connector(connector, dev)
    5395           0 :                 if (connector->funcs->reset)
    5396           0 :                         connector->funcs->reset(connector);
    5397           0 :         mutex_unlock(&dev->mode_config.mutex);
    5398           0 : }
    5399             : EXPORT_SYMBOL(drm_mode_config_reset);
    5400             : 
    5401             : /**
    5402             :  * drm_mode_create_dumb_ioctl - create a dumb backing storage buffer
    5403             :  * @dev: DRM device
    5404             :  * @data: ioctl data
    5405             :  * @file_priv: DRM file info
    5406             :  *
    5407             :  * This creates a new dumb buffer in the driver's backing storage manager (GEM,
    5408             :  * TTM or something else entirely) and returns the resulting buffer handle. This
    5409             :  * handle can then be wrapped up into a framebuffer modeset object.
    5410             :  *
    5411             :  * Note that userspace is not allowed to use such objects for render
    5412             :  * acceleration - drivers must create their own private ioctls for such a use
    5413             :  * case.
    5414             :  *
    5415             :  * Called by the user via ioctl.
    5416             :  *
    5417             :  * Returns:
    5418             :  * Zero on success, negative errno on failure.
    5419             :  */
    5420           0 : int drm_mode_create_dumb_ioctl(struct drm_device *dev,
    5421             :                                void *data, struct drm_file *file_priv)
    5422             : {
    5423           0 :         struct drm_mode_create_dumb *args = data;
    5424             :         u32 cpp, stride, size;
    5425             : 
    5426           0 :         if (!dev->driver->dumb_create)
    5427           0 :                 return -ENOSYS;
    5428           0 :         if (!args->width || !args->height || !args->bpp)
    5429           0 :                 return -EINVAL;
    5430             : 
    5431             :         /* overflow checks for 32bit size calculations */
    5432             :         /* NOTE: DIV_ROUND_UP() can overflow */
    5433           0 :         cpp = DIV_ROUND_UP(args->bpp, 8);
    5434           0 :         if (!cpp || cpp > 0xffffffffU / args->width)
    5435           0 :                 return -EINVAL;
    5436           0 :         stride = cpp * args->width;
    5437           0 :         if (args->height > 0xffffffffU / stride)
    5438           0 :                 return -EINVAL;
    5439             : 
    5440             :         /* test for wrap-around */
    5441           0 :         size = args->height * stride;
    5442           0 :         if (PAGE_ALIGN(size) == 0)
    5443           0 :                 return -EINVAL;
    5444             : 
    5445             :         /*
    5446             :          * handle, pitch and size are output parameters. Zero them out to
    5447             :          * prevent drivers from accidentally using uninitialized data. Since
    5448             :          * not all existing userspace is clearing these fields properly we
    5449             :          * cannot reject IOCTL with garbage in them.
    5450             :          */
    5451           0 :         args->handle = 0;
    5452           0 :         args->pitch = 0;
    5453           0 :         args->size = 0;
    5454             : 
    5455           0 :         return dev->driver->dumb_create(file_priv, dev, args);
    5456           0 : }
    5457             : 
    5458             : /**
    5459             :  * drm_mode_mmap_dumb_ioctl - create an mmap offset for a dumb backing storage buffer
    5460             :  * @dev: DRM device
    5461             :  * @data: ioctl data
    5462             :  * @file_priv: DRM file info
    5463             :  *
    5464             :  * Allocate an offset in the drm device node's address space to be able to
    5465             :  * memory map a dumb buffer.
    5466             :  *
    5467             :  * Called by the user via ioctl.
    5468             :  *
    5469             :  * Returns:
    5470             :  * Zero on success, negative errno on failure.
    5471             :  */
    5472           0 : int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
    5473             :                              void *data, struct drm_file *file_priv)
    5474             : {
    5475           0 :         struct drm_mode_map_dumb *args = data;
    5476             : 
    5477             :         /* call driver ioctl to get mmap offset */
    5478           0 :         if (!dev->driver->dumb_map_offset)
    5479           0 :                 return -ENOSYS;
    5480             : 
    5481           0 :         return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
    5482           0 : }
    5483             : 
    5484             : /**
    5485             :  * drm_mode_destroy_dumb_ioctl - destroy a dumb backing strage buffer
    5486             :  * @dev: DRM device
    5487             :  * @data: ioctl data
    5488             :  * @file_priv: DRM file info
    5489             :  *
    5490             :  * This destroys the userspace handle for the given dumb backing storage buffer.
    5491             :  * Since buffer objects must be reference counted in the kernel a buffer object
    5492             :  * won't be immediately freed if a framebuffer modeset object still uses it.
    5493             :  *
    5494             :  * Called by the user via ioctl.
    5495             :  *
    5496             :  * Returns:
    5497             :  * Zero on success, negative errno on failure.
    5498             :  */
    5499           0 : int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
    5500             :                                 void *data, struct drm_file *file_priv)
    5501             : {
    5502           0 :         struct drm_mode_destroy_dumb *args = data;
    5503             : 
    5504           0 :         if (!dev->driver->dumb_destroy)
    5505           0 :                 return -ENOSYS;
    5506             : 
    5507           0 :         return dev->driver->dumb_destroy(file_priv, dev, args->handle);
    5508           0 : }
    5509             : 
    5510             : /**
    5511             :  * drm_fb_get_bpp_depth - get the bpp/depth values for format
    5512             :  * @format: pixel format (DRM_FORMAT_*)
    5513             :  * @depth: storage for the depth value
    5514             :  * @bpp: storage for the bpp value
    5515             :  *
    5516             :  * This only supports RGB formats here for compat with code that doesn't use
    5517             :  * pixel formats directly yet.
    5518             :  */
    5519           0 : void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
    5520             :                           int *bpp)
    5521             : {
    5522           0 :         switch (format) {
    5523             :         case DRM_FORMAT_C8:
    5524             :         case DRM_FORMAT_RGB332:
    5525             :         case DRM_FORMAT_BGR233:
    5526           0 :                 *depth = 8;
    5527           0 :                 *bpp = 8;
    5528           0 :                 break;
    5529             :         case DRM_FORMAT_XRGB1555:
    5530             :         case DRM_FORMAT_XBGR1555:
    5531             :         case DRM_FORMAT_RGBX5551:
    5532             :         case DRM_FORMAT_BGRX5551:
    5533             :         case DRM_FORMAT_ARGB1555:
    5534             :         case DRM_FORMAT_ABGR1555:
    5535             :         case DRM_FORMAT_RGBA5551:
    5536             :         case DRM_FORMAT_BGRA5551:
    5537           0 :                 *depth = 15;
    5538           0 :                 *bpp = 16;
    5539           0 :                 break;
    5540             :         case DRM_FORMAT_RGB565:
    5541             :         case DRM_FORMAT_BGR565:
    5542           0 :                 *depth = 16;
    5543           0 :                 *bpp = 16;
    5544           0 :                 break;
    5545             :         case DRM_FORMAT_RGB888:
    5546             :         case DRM_FORMAT_BGR888:
    5547           0 :                 *depth = 24;
    5548           0 :                 *bpp = 24;
    5549           0 :                 break;
    5550             :         case DRM_FORMAT_XRGB8888:
    5551             :         case DRM_FORMAT_XBGR8888:
    5552             :         case DRM_FORMAT_RGBX8888:
    5553             :         case DRM_FORMAT_BGRX8888:
    5554           0 :                 *depth = 24;
    5555           0 :                 *bpp = 32;
    5556           0 :                 break;
    5557             :         case DRM_FORMAT_XRGB2101010:
    5558             :         case DRM_FORMAT_XBGR2101010:
    5559             :         case DRM_FORMAT_RGBX1010102:
    5560             :         case DRM_FORMAT_BGRX1010102:
    5561             :         case DRM_FORMAT_ARGB2101010:
    5562             :         case DRM_FORMAT_ABGR2101010:
    5563             :         case DRM_FORMAT_RGBA1010102:
    5564             :         case DRM_FORMAT_BGRA1010102:
    5565           0 :                 *depth = 30;
    5566           0 :                 *bpp = 32;
    5567           0 :                 break;
    5568             :         case DRM_FORMAT_ARGB8888:
    5569             :         case DRM_FORMAT_ABGR8888:
    5570             :         case DRM_FORMAT_RGBA8888:
    5571             :         case DRM_FORMAT_BGRA8888:
    5572           0 :                 *depth = 32;
    5573           0 :                 *bpp = 32;
    5574           0 :                 break;
    5575             :         default:
    5576             :                 DRM_DEBUG_KMS("unsupported pixel format %s\n",
    5577             :                               drm_get_format_name(format));
    5578           0 :                 *depth = 0;
    5579           0 :                 *bpp = 0;
    5580           0 :                 break;
    5581             :         }
    5582           0 : }
    5583             : EXPORT_SYMBOL(drm_fb_get_bpp_depth);
    5584             : 
    5585             : /**
    5586             :  * drm_format_num_planes - get the number of planes for format
    5587             :  * @format: pixel format (DRM_FORMAT_*)
    5588             :  *
    5589             :  * Returns:
    5590             :  * The number of planes used by the specified pixel format.
    5591             :  */
    5592           0 : int drm_format_num_planes(uint32_t format)
    5593             : {
    5594           0 :         switch (format) {
    5595             :         case DRM_FORMAT_YUV410:
    5596             :         case DRM_FORMAT_YVU410:
    5597             :         case DRM_FORMAT_YUV411:
    5598             :         case DRM_FORMAT_YVU411:
    5599             :         case DRM_FORMAT_YUV420:
    5600             :         case DRM_FORMAT_YVU420:
    5601             :         case DRM_FORMAT_YUV422:
    5602             :         case DRM_FORMAT_YVU422:
    5603             :         case DRM_FORMAT_YUV444:
    5604             :         case DRM_FORMAT_YVU444:
    5605           0 :                 return 3;
    5606             :         case DRM_FORMAT_NV12:
    5607             :         case DRM_FORMAT_NV21:
    5608             :         case DRM_FORMAT_NV16:
    5609             :         case DRM_FORMAT_NV61:
    5610             :         case DRM_FORMAT_NV24:
    5611             :         case DRM_FORMAT_NV42:
    5612           0 :                 return 2;
    5613             :         default:
    5614           0 :                 return 1;
    5615             :         }
    5616           0 : }
    5617             : EXPORT_SYMBOL(drm_format_num_planes);
    5618             : 
    5619             : /**
    5620             :  * drm_format_plane_cpp - determine the bytes per pixel value
    5621             :  * @format: pixel format (DRM_FORMAT_*)
    5622             :  * @plane: plane index
    5623             :  *
    5624             :  * Returns:
    5625             :  * The bytes per pixel value for the specified plane.
    5626             :  */
    5627           0 : int drm_format_plane_cpp(uint32_t format, int plane)
    5628             : {
    5629           0 :         unsigned int depth;
    5630           0 :         int bpp;
    5631             : 
    5632           0 :         if (plane >= drm_format_num_planes(format))
    5633           0 :                 return 0;
    5634             : 
    5635           0 :         switch (format) {
    5636             :         case DRM_FORMAT_YUYV:
    5637             :         case DRM_FORMAT_YVYU:
    5638             :         case DRM_FORMAT_UYVY:
    5639             :         case DRM_FORMAT_VYUY:
    5640           0 :                 return 2;
    5641             :         case DRM_FORMAT_NV12:
    5642             :         case DRM_FORMAT_NV21:
    5643             :         case DRM_FORMAT_NV16:
    5644             :         case DRM_FORMAT_NV61:
    5645             :         case DRM_FORMAT_NV24:
    5646             :         case DRM_FORMAT_NV42:
    5647           0 :                 return plane ? 2 : 1;
    5648             :         case DRM_FORMAT_YUV410:
    5649             :         case DRM_FORMAT_YVU410:
    5650             :         case DRM_FORMAT_YUV411:
    5651             :         case DRM_FORMAT_YVU411:
    5652             :         case DRM_FORMAT_YUV420:
    5653             :         case DRM_FORMAT_YVU420:
    5654             :         case DRM_FORMAT_YUV422:
    5655             :         case DRM_FORMAT_YVU422:
    5656             :         case DRM_FORMAT_YUV444:
    5657             :         case DRM_FORMAT_YVU444:
    5658           0 :                 return 1;
    5659             :         default:
    5660           0 :                 drm_fb_get_bpp_depth(format, &depth, &bpp);
    5661           0 :                 return bpp >> 3;
    5662             :         }
    5663           0 : }
    5664             : EXPORT_SYMBOL(drm_format_plane_cpp);
    5665             : 
    5666             : /**
    5667             :  * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
    5668             :  * @format: pixel format (DRM_FORMAT_*)
    5669             :  *
    5670             :  * Returns:
    5671             :  * The horizontal chroma subsampling factor for the
    5672             :  * specified pixel format.
    5673             :  */
    5674           0 : int drm_format_horz_chroma_subsampling(uint32_t format)
    5675             : {
    5676           0 :         switch (format) {
    5677             :         case DRM_FORMAT_YUV411:
    5678             :         case DRM_FORMAT_YVU411:
    5679             :         case DRM_FORMAT_YUV410:
    5680             :         case DRM_FORMAT_YVU410:
    5681           0 :                 return 4;
    5682             :         case DRM_FORMAT_YUYV:
    5683             :         case DRM_FORMAT_YVYU:
    5684             :         case DRM_FORMAT_UYVY:
    5685             :         case DRM_FORMAT_VYUY:
    5686             :         case DRM_FORMAT_NV12:
    5687             :         case DRM_FORMAT_NV21:
    5688             :         case DRM_FORMAT_NV16:
    5689             :         case DRM_FORMAT_NV61:
    5690             :         case DRM_FORMAT_YUV422:
    5691             :         case DRM_FORMAT_YVU422:
    5692             :         case DRM_FORMAT_YUV420:
    5693             :         case DRM_FORMAT_YVU420:
    5694           0 :                 return 2;
    5695             :         default:
    5696           0 :                 return 1;
    5697             :         }
    5698           0 : }
    5699             : EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
    5700             : 
    5701             : /**
    5702             :  * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
    5703             :  * @format: pixel format (DRM_FORMAT_*)
    5704             :  *
    5705             :  * Returns:
    5706             :  * The vertical chroma subsampling factor for the
    5707             :  * specified pixel format.
    5708             :  */
    5709           0 : int drm_format_vert_chroma_subsampling(uint32_t format)
    5710             : {
    5711           0 :         switch (format) {
    5712             :         case DRM_FORMAT_YUV410:
    5713             :         case DRM_FORMAT_YVU410:
    5714           0 :                 return 4;
    5715             :         case DRM_FORMAT_YUV420:
    5716             :         case DRM_FORMAT_YVU420:
    5717             :         case DRM_FORMAT_NV12:
    5718             :         case DRM_FORMAT_NV21:
    5719           0 :                 return 2;
    5720             :         default:
    5721           0 :                 return 1;
    5722             :         }
    5723           0 : }
    5724             : EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
    5725             : 
    5726             : /**
    5727             :  * drm_rotation_simplify() - Try to simplify the rotation
    5728             :  * @rotation: Rotation to be simplified
    5729             :  * @supported_rotations: Supported rotations
    5730             :  *
    5731             :  * Attempt to simplify the rotation to a form that is supported.
    5732             :  * Eg. if the hardware supports everything except DRM_REFLECT_X
    5733             :  * one could call this function like this:
    5734             :  *
    5735             :  * drm_rotation_simplify(rotation, BIT(DRM_ROTATE_0) |
    5736             :  *                       BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_180) |
    5737             :  *                       BIT(DRM_ROTATE_270) | BIT(DRM_REFLECT_Y));
    5738             :  *
    5739             :  * to eliminate the DRM_ROTATE_X flag. Depending on what kind of
    5740             :  * transforms the hardware supports, this function may not
    5741             :  * be able to produce a supported transform, so the caller should
    5742             :  * check the result afterwards.
    5743             :  */
    5744           0 : unsigned int drm_rotation_simplify(unsigned int rotation,
    5745             :                                    unsigned int supported_rotations)
    5746             : {
    5747           0 :         if (rotation & ~supported_rotations) {
    5748           0 :                 rotation ^= BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y);
    5749           0 :                 rotation = (rotation & DRM_REFLECT_MASK) |
    5750           0 :                            BIT((ffs(rotation & DRM_ROTATE_MASK) + 1) % 4);
    5751           0 :         }
    5752             : 
    5753           0 :         return rotation;
    5754             : }
    5755             : EXPORT_SYMBOL(drm_rotation_simplify);
    5756             : 
    5757             : /**
    5758             :  * drm_mode_config_init - initialize DRM mode_configuration structure
    5759             :  * @dev: DRM device
    5760             :  *
    5761             :  * Initialize @dev's mode_config structure, used for tracking the graphics
    5762             :  * configuration of @dev.
    5763             :  *
    5764             :  * Since this initializes the modeset locks, no locking is possible. Which is no
    5765             :  * problem, since this should happen single threaded at init time. It is the
    5766             :  * driver's problem to ensure this guarantee.
    5767             :  *
    5768             :  */
    5769           0 : void drm_mode_config_init(struct drm_device *dev)
    5770             : {
    5771           0 :         rw_init(&dev->mode_config.mutex, "mcrwl");
    5772           0 :         drm_modeset_lock_init(&dev->mode_config.connection_mutex);
    5773           0 :         rw_init(&dev->mode_config.idr_mutex, "idrlk");
    5774           0 :         rw_init(&dev->mode_config.fb_lock, "fblk");
    5775           0 :         rw_init(&dev->mode_config.blob_lock, "mcblk");
    5776           0 :         INIT_LIST_HEAD(&dev->mode_config.fb_list);
    5777           0 :         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
    5778           0 :         INIT_LIST_HEAD(&dev->mode_config.connector_list);
    5779           0 :         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
    5780           0 :         INIT_LIST_HEAD(&dev->mode_config.property_list);
    5781           0 :         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
    5782           0 :         INIT_LIST_HEAD(&dev->mode_config.plane_list);
    5783           0 :         idr_init(&dev->mode_config.crtc_idr);
    5784           0 :         idr_init(&dev->mode_config.tile_idr);
    5785             : 
    5786           0 :         drm_modeset_lock_all(dev);
    5787           0 :         drm_mode_create_standard_properties(dev);
    5788           0 :         drm_modeset_unlock_all(dev);
    5789             : 
    5790             :         /* Just to be sure */
    5791           0 :         dev->mode_config.num_fb = 0;
    5792           0 :         dev->mode_config.num_connector = 0;
    5793           0 :         dev->mode_config.num_crtc = 0;
    5794           0 :         dev->mode_config.num_encoder = 0;
    5795           0 :         dev->mode_config.num_overlay_plane = 0;
    5796           0 :         dev->mode_config.num_total_plane = 0;
    5797           0 : }
    5798             : EXPORT_SYMBOL(drm_mode_config_init);
    5799             : 
    5800             : /**
    5801             :  * drm_mode_config_cleanup - free up DRM mode_config info
    5802             :  * @dev: DRM device
    5803             :  *
    5804             :  * Free up all the connectors and CRTCs associated with this DRM device, then
    5805             :  * free up the framebuffers and associated buffer objects.
    5806             :  *
    5807             :  * Note that since this /should/ happen single-threaded at driver/device
    5808             :  * teardown time, no locking is required. It's the driver's job to ensure that
    5809             :  * this guarantee actually holds true.
    5810             :  *
    5811             :  * FIXME: cleanup any dangling user buffer objects too
    5812             :  */
    5813           0 : void drm_mode_config_cleanup(struct drm_device *dev)
    5814             : {
    5815             :         struct drm_connector *connector, *ot;
    5816             :         struct drm_crtc *crtc, *ct;
    5817             :         struct drm_encoder *encoder, *enct;
    5818             :         struct drm_framebuffer *fb, *fbt;
    5819             :         struct drm_property *property, *pt;
    5820             :         struct drm_property_blob *blob, *bt;
    5821             :         struct drm_plane *plane, *plt;
    5822             : 
    5823           0 :         list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
    5824             :                                  head) {
    5825           0 :                 encoder->funcs->destroy(encoder);
    5826             :         }
    5827             : 
    5828           0 :         list_for_each_entry_safe(connector, ot,
    5829             :                                  &dev->mode_config.connector_list, head) {
    5830           0 :                 connector->funcs->destroy(connector);
    5831             :         }
    5832             : 
    5833           0 :         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
    5834             :                                  head) {
    5835           0 :                 drm_property_destroy(dev, property);
    5836             :         }
    5837             : 
    5838           0 :         list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
    5839             :                                  head_global) {
    5840           0 :                 drm_property_unreference_blob(blob);
    5841             :         }
    5842             : 
    5843             :         /*
    5844             :          * Single-threaded teardown context, so it's not required to grab the
    5845             :          * fb_lock to protect against concurrent fb_list access. Contrary, it
    5846             :          * would actually deadlock with the drm_framebuffer_cleanup function.
    5847             :          *
    5848             :          * Also, if there are any framebuffers left, that's a driver leak now,
    5849             :          * so politely WARN about this.
    5850             :          */
    5851           0 :         WARN_ON(!list_empty(&dev->mode_config.fb_list));
    5852           0 :         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
    5853           0 :                 drm_framebuffer_free(&fb->refcount);
    5854             :         }
    5855             : 
    5856           0 :         list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
    5857             :                                  head) {
    5858           0 :                 plane->funcs->destroy(plane);
    5859             :         }
    5860             : 
    5861           0 :         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
    5862           0 :                 crtc->funcs->destroy(crtc);
    5863             :         }
    5864             : 
    5865           0 :         idr_destroy(&dev->mode_config.tile_idr);
    5866           0 :         idr_destroy(&dev->mode_config.crtc_idr);
    5867           0 :         drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
    5868           0 : }
    5869             : EXPORT_SYMBOL(drm_mode_config_cleanup);
    5870             : 
    5871           0 : struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
    5872             :                                                        unsigned int supported_rotations)
    5873             : {
    5874             :         static const struct drm_prop_enum_list props[] = {
    5875             :                 { DRM_ROTATE_0,   "rotate-0" },
    5876             :                 { DRM_ROTATE_90,  "rotate-90" },
    5877             :                 { DRM_ROTATE_180, "rotate-180" },
    5878             :                 { DRM_ROTATE_270, "rotate-270" },
    5879             :                 { DRM_REFLECT_X,  "reflect-x" },
    5880             :                 { DRM_REFLECT_Y,  "reflect-y" },
    5881             :         };
    5882             : 
    5883           0 :         return drm_property_create_bitmask(dev, 0, "rotation",
    5884             :                                            props, ARRAY_SIZE(props),
    5885           0 :                                            supported_rotations);
    5886             : }
    5887             : EXPORT_SYMBOL(drm_mode_create_rotation_property);
    5888             : 
    5889             : /**
    5890             :  * DOC: Tile group
    5891             :  *
    5892             :  * Tile groups are used to represent tiled monitors with a unique
    5893             :  * integer identifier. Tiled monitors using DisplayID v1.3 have
    5894             :  * a unique 8-byte handle, we store this in a tile group, so we
    5895             :  * have a common identifier for all tiles in a monitor group.
    5896             :  */
    5897           0 : static void drm_tile_group_free(struct kref *kref)
    5898             : {
    5899           0 :         struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
    5900           0 :         struct drm_device *dev = tg->dev;
    5901           0 :         mutex_lock(&dev->mode_config.idr_mutex);
    5902           0 :         idr_remove(&dev->mode_config.tile_idr, tg->id);
    5903           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
    5904           0 :         kfree(tg);
    5905           0 : }
    5906             : 
    5907             : /**
    5908             :  * drm_mode_put_tile_group - drop a reference to a tile group.
    5909             :  * @dev: DRM device
    5910             :  * @tg: tile group to drop reference to.
    5911             :  *
    5912             :  * drop reference to tile group and free if 0.
    5913             :  */
    5914           0 : void drm_mode_put_tile_group(struct drm_device *dev,
    5915             :                              struct drm_tile_group *tg)
    5916             : {
    5917           0 :         kref_put(&tg->refcount, drm_tile_group_free);
    5918           0 : }
    5919             : 
    5920             : /**
    5921             :  * drm_mode_get_tile_group - get a reference to an existing tile group
    5922             :  * @dev: DRM device
    5923             :  * @topology: 8-bytes unique per monitor.
    5924             :  *
    5925             :  * Use the unique bytes to get a reference to an existing tile group.
    5926             :  *
    5927             :  * RETURNS:
    5928             :  * tile group or NULL if not found.
    5929             :  */
    5930           0 : struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
    5931             :                                                char topology[8])
    5932             : {
    5933             :         struct drm_tile_group *tg;
    5934           0 :         int id;
    5935           0 :         mutex_lock(&dev->mode_config.idr_mutex);
    5936           0 :         idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
    5937           0 :                 if (!memcmp(tg->group_data, topology, 8)) {
    5938           0 :                         if (!kref_get_unless_zero(&tg->refcount))
    5939           0 :                                 tg = NULL;
    5940           0 :                         mutex_unlock(&dev->mode_config.idr_mutex);
    5941           0 :                         return tg;
    5942             :                 }
    5943             :         }
    5944           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
    5945           0 :         return NULL;
    5946           0 : }
    5947             : EXPORT_SYMBOL(drm_mode_get_tile_group);
    5948             : 
    5949             : /**
    5950             :  * drm_mode_create_tile_group - create a tile group from a displayid description
    5951             :  * @dev: DRM device
    5952             :  * @topology: 8-bytes unique per monitor.
    5953             :  *
    5954             :  * Create a tile group for the unique monitor, and get a unique
    5955             :  * identifier for the tile group.
    5956             :  *
    5957             :  * RETURNS:
    5958             :  * new tile group or error.
    5959             :  */
    5960           0 : struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
    5961             :                                                   char topology[8])
    5962             : {
    5963             :         struct drm_tile_group *tg;
    5964             :         int ret;
    5965             : 
    5966           0 :         tg = kzalloc(sizeof(*tg), GFP_KERNEL);
    5967           0 :         if (!tg)
    5968           0 :                 return ERR_PTR(-ENOMEM);
    5969             : 
    5970           0 :         kref_init(&tg->refcount);
    5971           0 :         memcpy(tg->group_data, topology, 8);
    5972           0 :         tg->dev = dev;
    5973             : 
    5974           0 :         mutex_lock(&dev->mode_config.idr_mutex);
    5975           0 :         ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
    5976           0 :         if (ret >= 0) {
    5977           0 :                 tg->id = ret;
    5978           0 :         } else {
    5979           0 :                 kfree(tg);
    5980           0 :                 tg = ERR_PTR(ret);
    5981             :         }
    5982             : 
    5983           0 :         mutex_unlock(&dev->mode_config.idr_mutex);
    5984           0 :         return tg;
    5985           0 : }
    5986             : EXPORT_SYMBOL(drm_mode_create_tile_group);

Generated by: LCOV version 1.13