Sat Jun 27 13:39:06 2020 UTC ()
prop_dictionary_get_cstring -> prop_dictionary_get_string


(jmcneill)
diff -r1.16 -r1.17 src/sys/external/bsd/drm2/dist/drm/drm_crtc.c

cvs diff -r1.16 -r1.17 src/sys/external/bsd/drm2/dist/drm/drm_crtc.c (switch to unified diff)

--- src/sys/external/bsd/drm2/dist/drm/drm_crtc.c 2020/02/14 14:34:57 1.16
+++ src/sys/external/bsd/drm2/dist/drm/drm_crtc.c 2020/06/27 13:39:05 1.17
@@ -1,1833 +1,1834 @@ @@ -1,1833 +1,1834 @@
1/* $NetBSD: drm_crtc.c,v 1.16 2020/02/14 14:34:57 maya Exp $ */ 1/* $NetBSD: drm_crtc.c,v 1.17 2020/06/27 13:39:05 jmcneill Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006-2008 Intel Corporation 4 * Copyright (c) 2006-2008 Intel Corporation
5 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 5 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
6 * Copyright (c) 2008 Red Hat Inc. 6 * Copyright (c) 2008 Red Hat Inc.
7 * 7 *
8 * DRM core CRTC related functions 8 * DRM core CRTC related functions
9 * 9 *
10 * Permission to use, copy, modify, distribute, and sell this software and its 10 * Permission to use, copy, modify, distribute, and sell this software and its
11 * documentation for any purpose is hereby granted without fee, provided that 11 * documentation for any purpose is hereby granted without fee, provided that
12 * the above copyright notice appear in all copies and that both that copyright 12 * the above copyright notice appear in all copies and that both that copyright
13 * notice and this permission notice appear in supporting documentation, and 13 * notice and this permission notice appear in supporting documentation, and
14 * that the name of the copyright holders not be used in advertising or 14 * that the name of the copyright holders not be used in advertising or
15 * publicity pertaining to distribution of the software without specific, 15 * publicity pertaining to distribution of the software without specific,
16 * written prior permission. The copyright holders make no representations 16 * written prior permission. The copyright holders make no representations
17 * about the suitability of this software for any purpose. It is provided "as 17 * about the suitability of this software for any purpose. It is provided "as
18 * is" without express or implied warranty. 18 * is" without express or implied warranty.
19 * 19 *
20 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 20 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 21 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
22 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 22 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
23 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 23 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
24 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 24 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
25 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 25 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26 * OF THIS SOFTWARE. 26 * OF THIS SOFTWARE.
27 * 27 *
28 * Authors: 28 * Authors:
29 * Keith Packard 29 * Keith Packard
30 * Eric Anholt <eric@anholt.net> 30 * Eric Anholt <eric@anholt.net>
31 * Dave Airlie <airlied@linux.ie> 31 * Dave Airlie <airlied@linux.ie>
32 * Jesse Barnes <jesse.barnes@intel.com> 32 * Jesse Barnes <jesse.barnes@intel.com>
33 */ 33 */
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: drm_crtc.c,v 1.16 2020/02/14 14:34:57 maya Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: drm_crtc.c,v 1.17 2020/06/27 13:39:05 jmcneill Exp $");
36 36
37#include <linux/ctype.h> 37#include <linux/ctype.h>
38#include <linux/list.h> 38#include <linux/list.h>
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/export.h> 40#include <linux/export.h>
41#include <drm/drmP.h> 41#include <drm/drmP.h>
42#include <drm/drm_crtc.h> 42#include <drm/drm_crtc.h>
43#include <drm/drm_edid.h> 43#include <drm/drm_edid.h>
44#include <drm/drm_fourcc.h> 44#include <drm/drm_fourcc.h>
45#include <drm/drm_modeset_lock.h> 45#include <drm/drm_modeset_lock.h>
46#include <drm/drm_atomic.h> 46#include <drm/drm_atomic.h>
47 47
48#include "drm_crtc_internal.h" 48#include "drm_crtc_internal.h"
49#include "drm_internal.h" 49#include "drm_internal.h"
50 50
51#include <linux/nbsd-namespace.h> 51#include <linux/nbsd-namespace.h>
52 52
53static struct drm_framebuffer * 53static struct drm_framebuffer *
54internal_framebuffer_create(struct drm_device *dev, 54internal_framebuffer_create(struct drm_device *dev,
55 struct drm_mode_fb_cmd2 *r, 55 struct drm_mode_fb_cmd2 *r,
56 struct drm_file *file_priv); 56 struct drm_file *file_priv);
57 57
58/* Avoid boilerplate. I'm tired of typing. */ 58/* Avoid boilerplate. I'm tired of typing. */
59#define DRM_ENUM_NAME_FN(fnname, list) \ 59#define DRM_ENUM_NAME_FN(fnname, list) \
60 const char *fnname(int val) \ 60 const char *fnname(int val) \
61 { \ 61 { \
62 int i; \ 62 int i; \
63 for (i = 0; i < ARRAY_SIZE(list); i++) { \ 63 for (i = 0; i < ARRAY_SIZE(list); i++) { \
64 if (list[i].type == val) \ 64 if (list[i].type == val) \
65 return list[i].name; \ 65 return list[i].name; \
66 } \ 66 } \
67 return "(unknown)"; \ 67 return "(unknown)"; \
68 } 68 }
69 69
70/* 70/*
71 * Global properties 71 * Global properties
72 */ 72 */
73static const struct drm_prop_enum_list drm_dpms_enum_list[] = { 73static const struct drm_prop_enum_list drm_dpms_enum_list[] = {
74 { DRM_MODE_DPMS_ON, "On" }, 74 { DRM_MODE_DPMS_ON, "On" },
75 { DRM_MODE_DPMS_STANDBY, "Standby" }, 75 { DRM_MODE_DPMS_STANDBY, "Standby" },
76 { DRM_MODE_DPMS_SUSPEND, "Suspend" }, 76 { DRM_MODE_DPMS_SUSPEND, "Suspend" },
77 { DRM_MODE_DPMS_OFF, "Off" } 77 { DRM_MODE_DPMS_OFF, "Off" }
78}; 78};
79 79
80DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) 80DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
81 81
82static const struct drm_prop_enum_list drm_plane_type_enum_list[] = { 82static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
83 { DRM_PLANE_TYPE_OVERLAY, "Overlay" }, 83 { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
84 { DRM_PLANE_TYPE_PRIMARY, "Primary" }, 84 { DRM_PLANE_TYPE_PRIMARY, "Primary" },
85 { DRM_PLANE_TYPE_CURSOR, "Cursor" }, 85 { DRM_PLANE_TYPE_CURSOR, "Cursor" },
86}; 86};
87 87
88/* 88/*
89 * Optional properties 89 * Optional properties
90 */ 90 */
91static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = { 91static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = {
92 { DRM_MODE_SCALE_NONE, "None" }, 92 { DRM_MODE_SCALE_NONE, "None" },
93 { DRM_MODE_SCALE_FULLSCREEN, "Full" }, 93 { DRM_MODE_SCALE_FULLSCREEN, "Full" },
94 { DRM_MODE_SCALE_CENTER, "Center" }, 94 { DRM_MODE_SCALE_CENTER, "Center" },
95 { DRM_MODE_SCALE_ASPECT, "Full aspect" }, 95 { DRM_MODE_SCALE_ASPECT, "Full aspect" },
96}; 96};
97 97
98static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = { 98static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
99 { DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" }, 99 { DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" },
100 { DRM_MODE_PICTURE_ASPECT_4_3, "4:3" }, 100 { DRM_MODE_PICTURE_ASPECT_4_3, "4:3" },
101 { DRM_MODE_PICTURE_ASPECT_16_9, "16:9" }, 101 { DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
102}; 102};
103 103
104/* 104/*
105 * Non-global properties, but "required" for certain connectors. 105 * Non-global properties, but "required" for certain connectors.
106 */ 106 */
107static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = { 107static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
108 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 108 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
109 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 109 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
110 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 110 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
111}; 111};
112 112
113DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) 113DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
114 114
115static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = { 115static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {
116 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 116 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
117 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 117 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
118 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 118 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
119}; 119};
120 120
121DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, 121DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
122 drm_dvi_i_subconnector_enum_list) 122 drm_dvi_i_subconnector_enum_list)
123 123
124static const struct drm_prop_enum_list drm_tv_select_enum_list[] = { 124static const struct drm_prop_enum_list drm_tv_select_enum_list[] = {
125 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 125 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
126 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 126 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
127 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 127 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
128 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 128 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
129 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ 129 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
130}; 130};
131 131
132DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) 132DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
133 133
134static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = { 134static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
135 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 135 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
136 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 136 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
137 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 137 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
138 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 138 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
139 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ 139 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
140}; 140};
141 141
142DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, 142DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
143 drm_tv_subconnector_enum_list) 143 drm_tv_subconnector_enum_list)
144 144
145static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = { 145static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
146 { DRM_MODE_DIRTY_OFF, "Off" }, 146 { DRM_MODE_DIRTY_OFF, "Off" },
147 { DRM_MODE_DIRTY_ON, "On" }, 147 { DRM_MODE_DIRTY_ON, "On" },
148 { DRM_MODE_DIRTY_ANNOTATE, "Annotate" }, 148 { DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
149}; 149};
150 150
151struct drm_conn_prop_enum_list { 151struct drm_conn_prop_enum_list {
152 int type; 152 int type;
153 const char *name; 153 const char *name;
154 struct ida ida; 154 struct ida ida;
155}; 155};
156 156
157/* 157/*
158 * Connector and encoder types. 158 * Connector and encoder types.
159 */ 159 */
160static struct drm_conn_prop_enum_list drm_connector_enum_list[] = { 160static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {
161 { DRM_MODE_CONNECTOR_Unknown, "Unknown" }, 161 { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
162 { DRM_MODE_CONNECTOR_VGA, "VGA" }, 162 { DRM_MODE_CONNECTOR_VGA, "VGA" },
163 { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, 163 { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
164 { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, 164 { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
165 { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, 165 { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
166 { DRM_MODE_CONNECTOR_Composite, "Composite" }, 166 { DRM_MODE_CONNECTOR_Composite, "Composite" },
167 { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" }, 167 { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
168 { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, 168 { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
169 { DRM_MODE_CONNECTOR_Component, "Component" }, 169 { DRM_MODE_CONNECTOR_Component, "Component" },
170 { DRM_MODE_CONNECTOR_9PinDIN, "DIN" }, 170 { DRM_MODE_CONNECTOR_9PinDIN, "DIN" },
171 { DRM_MODE_CONNECTOR_DisplayPort, "DP" }, 171 { DRM_MODE_CONNECTOR_DisplayPort, "DP" },
172 { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, 172 { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
173 { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, 173 { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
174 { DRM_MODE_CONNECTOR_TV, "TV" }, 174 { DRM_MODE_CONNECTOR_TV, "TV" },
175 { DRM_MODE_CONNECTOR_eDP, "eDP" }, 175 { DRM_MODE_CONNECTOR_eDP, "eDP" },
176 { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, 176 { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
177 { DRM_MODE_CONNECTOR_DSI, "DSI" }, 177 { DRM_MODE_CONNECTOR_DSI, "DSI" },
178}; 178};
179 179
180static const struct drm_prop_enum_list drm_encoder_enum_list[] = { 180static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
181 { DRM_MODE_ENCODER_NONE, "None" }, 181 { DRM_MODE_ENCODER_NONE, "None" },
182 { DRM_MODE_ENCODER_DAC, "DAC" }, 182 { DRM_MODE_ENCODER_DAC, "DAC" },
183 { DRM_MODE_ENCODER_TMDS, "TMDS" }, 183 { DRM_MODE_ENCODER_TMDS, "TMDS" },
184 { DRM_MODE_ENCODER_LVDS, "LVDS" }, 184 { DRM_MODE_ENCODER_LVDS, "LVDS" },
185 { DRM_MODE_ENCODER_TVDAC, "TV" }, 185 { DRM_MODE_ENCODER_TVDAC, "TV" },
186 { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, 186 { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
187 { DRM_MODE_ENCODER_DSI, "DSI" }, 187 { DRM_MODE_ENCODER_DSI, "DSI" },
188 { DRM_MODE_ENCODER_DPMST, "DP MST" }, 188 { DRM_MODE_ENCODER_DPMST, "DP MST" },
189}; 189};
190 190
191static const struct drm_prop_enum_list drm_subpixel_enum_list[] = { 191static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
192 { SubPixelUnknown, "Unknown" }, 192 { SubPixelUnknown, "Unknown" },
193 { SubPixelHorizontalRGB, "Horizontal RGB" }, 193 { SubPixelHorizontalRGB, "Horizontal RGB" },
194 { SubPixelHorizontalBGR, "Horizontal BGR" }, 194 { SubPixelHorizontalBGR, "Horizontal BGR" },
195 { SubPixelVerticalRGB, "Vertical RGB" }, 195 { SubPixelVerticalRGB, "Vertical RGB" },
196 { SubPixelVerticalBGR, "Vertical BGR" }, 196 { SubPixelVerticalBGR, "Vertical BGR" },
197 { SubPixelNone, "None" }, 197 { SubPixelNone, "None" },
198}; 198};
199 199
200void drm_connector_ida_init(void) 200void drm_connector_ida_init(void)
201{ 201{
202 int i; 202 int i;
203 203
204 for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) 204 for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
205 ida_init(&drm_connector_enum_list[i].ida); 205 ida_init(&drm_connector_enum_list[i].ida);
206} 206}
207 207
208void drm_connector_ida_destroy(void) 208void drm_connector_ida_destroy(void)
209{ 209{
210 int i; 210 int i;
211 211
212 for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) 212 for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
213 ida_destroy(&drm_connector_enum_list[i].ida); 213 ida_destroy(&drm_connector_enum_list[i].ida);
214} 214}
215 215
216/** 216/**
217 * drm_get_connector_status_name - return a string for connector status 217 * drm_get_connector_status_name - return a string for connector status
218 * @status: connector status to compute name of 218 * @status: connector status to compute name of
219 * 219 *
220 * In contrast to the other drm_get_*_name functions this one here returns a 220 * In contrast to the other drm_get_*_name functions this one here returns a
221 * const pointer and hence is threadsafe. 221 * const pointer and hence is threadsafe.
222 */ 222 */
223const char *drm_get_connector_status_name(enum drm_connector_status status) 223const char *drm_get_connector_status_name(enum drm_connector_status status)
224{ 224{
225 if (status == connector_status_connected) 225 if (status == connector_status_connected)
226 return "connected"; 226 return "connected";
227 else if (status == connector_status_disconnected) 227 else if (status == connector_status_disconnected)
228 return "disconnected"; 228 return "disconnected";
229 else 229 else
230 return "unknown"; 230 return "unknown";
231} 231}
232EXPORT_SYMBOL(drm_get_connector_status_name); 232EXPORT_SYMBOL(drm_get_connector_status_name);
233 233
234/** 234/**
235 * drm_get_subpixel_order_name - return a string for a given subpixel enum 235 * drm_get_subpixel_order_name - return a string for a given subpixel enum
236 * @order: enum of subpixel_order 236 * @order: enum of subpixel_order
237 * 237 *
238 * Note you could abuse this and return something out of bounds, but that 238 * Note you could abuse this and return something out of bounds, but that
239 * would be a caller error. No unscrubbed user data should make it here. 239 * would be a caller error. No unscrubbed user data should make it here.
240 */ 240 */
241const char *drm_get_subpixel_order_name(enum subpixel_order order) 241const char *drm_get_subpixel_order_name(enum subpixel_order order)
242{ 242{
243 return drm_subpixel_enum_list[order].name; 243 return drm_subpixel_enum_list[order].name;
244} 244}
245EXPORT_SYMBOL(drm_get_subpixel_order_name); 245EXPORT_SYMBOL(drm_get_subpixel_order_name);
246 246
247static char printable_char(int c) 247static char printable_char(int c)
248{ 248{
249 return isascii(c) && isprint(c) ? c : '?'; 249 return isascii(c) && isprint(c) ? c : '?';
250} 250}
251 251
252/** 252/**
253 * drm_get_format_name - return a string for drm fourcc format 253 * drm_get_format_name - return a string for drm fourcc format
254 * @format: format to compute name of 254 * @format: format to compute name of
255 * 255 *
256 * Note that the buffer used by this function is globally shared and owned by 256 * Note that the buffer used by this function is globally shared and owned by
257 * the function itself. 257 * the function itself.
258 * 258 *
259 * FIXME: This isn't really multithreading safe. 259 * FIXME: This isn't really multithreading safe.
260 */ 260 */
261const char *drm_get_format_name(uint32_t format) 261const char *drm_get_format_name(uint32_t format)
262{ 262{
263 static char buf[32]; 263 static char buf[32];
264 264
265 snprintf(buf, sizeof(buf), 265 snprintf(buf, sizeof(buf),
266 "%c%c%c%c %s-endian (0x%08x)", 266 "%c%c%c%c %s-endian (0x%08x)",
267 printable_char(format & 0xff), 267 printable_char(format & 0xff),
268 printable_char((format >> 8) & 0xff), 268 printable_char((format >> 8) & 0xff),
269 printable_char((format >> 16) & 0xff), 269 printable_char((format >> 16) & 0xff),
270 printable_char((format >> 24) & 0x7f), 270 printable_char((format >> 24) & 0x7f),
271 format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", 271 format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
272 format); 272 format);
273 273
274 return buf; 274 return buf;
275} 275}
276EXPORT_SYMBOL(drm_get_format_name); 276EXPORT_SYMBOL(drm_get_format_name);
277 277
278/* 278/*
279 * Internal function to assign a slot in the object idr and optionally 279 * Internal function to assign a slot in the object idr and optionally
280 * register the object into the idr. 280 * register the object into the idr.
281 */ 281 */
282static int drm_mode_object_get_reg(struct drm_device *dev, 282static int drm_mode_object_get_reg(struct drm_device *dev,
283 struct drm_mode_object *obj, 283 struct drm_mode_object *obj,
284 uint32_t obj_type, 284 uint32_t obj_type,
285 bool register_obj) 285 bool register_obj)
286{ 286{
287 int ret; 287 int ret;
288 288
289 idr_preload(GFP_KERNEL); 289 idr_preload(GFP_KERNEL);
290 mutex_lock(&dev->mode_config.idr_mutex); 290 mutex_lock(&dev->mode_config.idr_mutex);
291 ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL); 291 ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL);
292 if (ret >= 0) { 292 if (ret >= 0) {
293 /* 293 /*
294 * Set up the object linking under the protection of the idr 294 * Set up the object linking under the protection of the idr
295 * lock so that other users can't see inconsistent state. 295 * lock so that other users can't see inconsistent state.
296 */ 296 */
297 obj->id = ret; 297 obj->id = ret;
298 obj->type = obj_type; 298 obj->type = obj_type;
299 } 299 }
300 mutex_unlock(&dev->mode_config.idr_mutex); 300 mutex_unlock(&dev->mode_config.idr_mutex);
301 idr_preload_end(); 301 idr_preload_end();
302 302
303 return ret < 0 ? ret : 0; 303 return ret < 0 ? ret : 0;
304} 304}
305 305
306/** 306/**
307 * drm_mode_object_get - allocate a new modeset identifier 307 * drm_mode_object_get - allocate a new modeset identifier
308 * @dev: DRM device 308 * @dev: DRM device
309 * @obj: object pointer, used to generate unique ID 309 * @obj: object pointer, used to generate unique ID
310 * @obj_type: object type 310 * @obj_type: object type
311 * 311 *
312 * Create a unique identifier based on @ptr in @dev's identifier space. Used 312 * Create a unique identifier based on @ptr in @dev's identifier space. Used
313 * for tracking modes, CRTCs and connectors. Note that despite the _get postfix 313 * for tracking modes, CRTCs and connectors. Note that despite the _get postfix
314 * modeset identifiers are _not_ reference counted. Hence don't use this for 314 * modeset identifiers are _not_ reference counted. Hence don't use this for
315 * reference counted modeset objects like framebuffers. 315 * reference counted modeset objects like framebuffers.
316 * 316 *
317 * Returns: 317 * Returns:
318 * Zero on success, error code on failure. 318 * Zero on success, error code on failure.
319 */ 319 */
320int drm_mode_object_get(struct drm_device *dev, 320int drm_mode_object_get(struct drm_device *dev,
321 struct drm_mode_object *obj, uint32_t obj_type) 321 struct drm_mode_object *obj, uint32_t obj_type)
322{ 322{
323 return drm_mode_object_get_reg(dev, obj, obj_type, true); 323 return drm_mode_object_get_reg(dev, obj, obj_type, true);
324} 324}
325 325
326static void drm_mode_object_register(struct drm_device *dev, 326static void drm_mode_object_register(struct drm_device *dev,
327 struct drm_mode_object *obj) 327 struct drm_mode_object *obj)
328{ 328{
329 mutex_lock(&dev->mode_config.idr_mutex); 329 mutex_lock(&dev->mode_config.idr_mutex);
330 idr_replace(&dev->mode_config.crtc_idr, obj, obj->id); 330 idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
331 mutex_unlock(&dev->mode_config.idr_mutex); 331 mutex_unlock(&dev->mode_config.idr_mutex);
332} 332}
333 333
334/** 334/**
335 * drm_mode_object_put - free a modeset identifer 335 * drm_mode_object_put - free a modeset identifer
336 * @dev: DRM device 336 * @dev: DRM device
337 * @object: object to free 337 * @object: object to free
338 * 338 *
339 * Free @id from @dev's unique identifier pool. Note that despite the _get 339 * Free @id from @dev's unique identifier pool. Note that despite the _get
340 * postfix modeset identifiers are _not_ reference counted. Hence don't use this 340 * postfix modeset identifiers are _not_ reference counted. Hence don't use this
341 * for reference counted modeset objects like framebuffers. 341 * for reference counted modeset objects like framebuffers.
342 */ 342 */
343void drm_mode_object_put(struct drm_device *dev, 343void drm_mode_object_put(struct drm_device *dev,
344 struct drm_mode_object *object) 344 struct drm_mode_object *object)
345{ 345{
346 mutex_lock(&dev->mode_config.idr_mutex); 346 mutex_lock(&dev->mode_config.idr_mutex);
347 idr_remove(&dev->mode_config.crtc_idr, object->id); 347 idr_remove(&dev->mode_config.crtc_idr, object->id);
348 mutex_unlock(&dev->mode_config.idr_mutex); 348 mutex_unlock(&dev->mode_config.idr_mutex);
349} 349}
350 350
351static struct drm_mode_object *_object_find(struct drm_device *dev, 351static struct drm_mode_object *_object_find(struct drm_device *dev,
352 uint32_t id, uint32_t type) 352 uint32_t id, uint32_t type)
353{ 353{
354 struct drm_mode_object *obj = NULL; 354 struct drm_mode_object *obj = NULL;
355 355
356 mutex_lock(&dev->mode_config.idr_mutex); 356 mutex_lock(&dev->mode_config.idr_mutex);
357 obj = idr_find(&dev->mode_config.crtc_idr, id); 357 obj = idr_find(&dev->mode_config.crtc_idr, id);
358 if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type) 358 if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
359 obj = NULL; 359 obj = NULL;
360 if (obj && obj->id != id) 360 if (obj && obj->id != id)
361 obj = NULL; 361 obj = NULL;
362 /* don't leak out unref'd fb's */ 362 /* don't leak out unref'd fb's */
363 if (obj && 363 if (obj &&
364 (obj->type == DRM_MODE_OBJECT_FB || 364 (obj->type == DRM_MODE_OBJECT_FB ||
365 obj->type == DRM_MODE_OBJECT_BLOB)) 365 obj->type == DRM_MODE_OBJECT_BLOB))
366 obj = NULL; 366 obj = NULL;
367 mutex_unlock(&dev->mode_config.idr_mutex); 367 mutex_unlock(&dev->mode_config.idr_mutex);
368 368
369 return obj; 369 return obj;
370} 370}
371 371
372/** 372/**
373 * drm_mode_object_find - look up a drm object with static lifetime 373 * drm_mode_object_find - look up a drm object with static lifetime
374 * @dev: drm device 374 * @dev: drm device
375 * @id: id of the mode object 375 * @id: id of the mode object
376 * @type: type of the mode object 376 * @type: type of the mode object
377 * 377 *
378 * Note that framebuffers cannot be looked up with this functions - since those 378 * Note that framebuffers cannot be looked up with this functions - since those
379 * are reference counted, they need special treatment. Even with 379 * are reference counted, they need special treatment. Even with
380 * DRM_MODE_OBJECT_ANY (although that will simply return NULL 380 * DRM_MODE_OBJECT_ANY (although that will simply return NULL
381 * rather than WARN_ON()). 381 * rather than WARN_ON()).
382 */ 382 */
383struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, 383struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
384 uint32_t id, uint32_t type) 384 uint32_t id, uint32_t type)
385{ 385{
386 struct drm_mode_object *obj = NULL; 386 struct drm_mode_object *obj = NULL;
387 387
388 /* Framebuffers are reference counted and need their own lookup 388 /* Framebuffers are reference counted and need their own lookup
389 * function.*/ 389 * function.*/
390 WARN_ON(type == DRM_MODE_OBJECT_FB || type == DRM_MODE_OBJECT_BLOB); 390 WARN_ON(type == DRM_MODE_OBJECT_FB || type == DRM_MODE_OBJECT_BLOB);
391 obj = _object_find(dev, id, type); 391 obj = _object_find(dev, id, type);
392 return obj; 392 return obj;
393} 393}
394EXPORT_SYMBOL(drm_mode_object_find); 394EXPORT_SYMBOL(drm_mode_object_find);
395 395
396/** 396/**
397 * drm_framebuffer_init - initialize a framebuffer 397 * drm_framebuffer_init - initialize a framebuffer
398 * @dev: DRM device 398 * @dev: DRM device
399 * @fb: framebuffer to be initialized 399 * @fb: framebuffer to be initialized
400 * @funcs: ... with these functions 400 * @funcs: ... with these functions
401 * 401 *
402 * Allocates an ID for the framebuffer's parent mode object, sets its mode 402 * Allocates an ID for the framebuffer's parent mode object, sets its mode
403 * functions & device file and adds it to the master fd list. 403 * functions & device file and adds it to the master fd list.
404 * 404 *
405 * IMPORTANT: 405 * IMPORTANT:
406 * This functions publishes the fb and makes it available for concurrent access 406 * This functions publishes the fb and makes it available for concurrent access
407 * by other users. Which means by this point the fb _must_ be fully set up - 407 * by other users. Which means by this point the fb _must_ be fully set up -
408 * since all the fb attributes are invariant over its lifetime, no further 408 * since all the fb attributes are invariant over its lifetime, no further
409 * locking but only correct reference counting is required. 409 * locking but only correct reference counting is required.
410 * 410 *
411 * Returns: 411 * Returns:
412 * Zero on success, error code on failure. 412 * Zero on success, error code on failure.
413 */ 413 */
414int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, 414int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
415 const struct drm_framebuffer_funcs *funcs) 415 const struct drm_framebuffer_funcs *funcs)
416{ 416{
417 int ret; 417 int ret;
418 418
419 mutex_lock(&dev->mode_config.fb_lock); 419 mutex_lock(&dev->mode_config.fb_lock);
420 kref_init(&fb->refcount); 420 kref_init(&fb->refcount);
421 INIT_LIST_HEAD(&fb->filp_head); 421 INIT_LIST_HEAD(&fb->filp_head);
422 fb->dev = dev; 422 fb->dev = dev;
423 fb->funcs = funcs; 423 fb->funcs = funcs;
424 424
425 ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); 425 ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
426 if (ret) 426 if (ret)
427 goto out; 427 goto out;
428 428
429 dev->mode_config.num_fb++; 429 dev->mode_config.num_fb++;
430 list_add(&fb->head, &dev->mode_config.fb_list); 430 list_add(&fb->head, &dev->mode_config.fb_list);
431out: 431out:
432 mutex_unlock(&dev->mode_config.fb_lock); 432 mutex_unlock(&dev->mode_config.fb_lock);
433 433
434 return ret; 434 return ret;
435} 435}
436EXPORT_SYMBOL(drm_framebuffer_init); 436EXPORT_SYMBOL(drm_framebuffer_init);
437 437
438/* dev->mode_config.fb_lock must be held! */ 438/* dev->mode_config.fb_lock must be held! */
439static void __drm_framebuffer_unregister(struct drm_device *dev, 439static void __drm_framebuffer_unregister(struct drm_device *dev,
440 struct drm_framebuffer *fb) 440 struct drm_framebuffer *fb)
441{ 441{
442 mutex_lock(&dev->mode_config.idr_mutex); 442 mutex_lock(&dev->mode_config.idr_mutex);
443 idr_remove(&dev->mode_config.crtc_idr, fb->base.id); 443 idr_remove(&dev->mode_config.crtc_idr, fb->base.id);
444 mutex_unlock(&dev->mode_config.idr_mutex); 444 mutex_unlock(&dev->mode_config.idr_mutex);
445 445
446 fb->base.id = 0; 446 fb->base.id = 0;
447} 447}
448 448
449static void drm_framebuffer_free(struct kref *kref) 449static void drm_framebuffer_free(struct kref *kref)
450{ 450{
451 struct drm_framebuffer *fb = 451 struct drm_framebuffer *fb =
452 container_of(kref, struct drm_framebuffer, refcount); 452 container_of(kref, struct drm_framebuffer, refcount);
453 struct drm_device *dev = fb->dev; 453 struct drm_device *dev = fb->dev;
454 454
455 /* 455 /*
456 * The lookup idr holds a weak reference, which has not necessarily been 456 * The lookup idr holds a weak reference, which has not necessarily been
457 * removed at this point. Check for that. 457 * removed at this point. Check for that.
458 */ 458 */
459 mutex_lock(&dev->mode_config.fb_lock); 459 mutex_lock(&dev->mode_config.fb_lock);
460 if (fb->base.id) { 460 if (fb->base.id) {
461 /* Mark fb as reaped and drop idr ref. */ 461 /* Mark fb as reaped and drop idr ref. */
462 __drm_framebuffer_unregister(dev, fb); 462 __drm_framebuffer_unregister(dev, fb);
463 } 463 }
464 mutex_unlock(&dev->mode_config.fb_lock); 464 mutex_unlock(&dev->mode_config.fb_lock);
465 465
466 fb->funcs->destroy(fb); 466 fb->funcs->destroy(fb);
467} 467}
468 468
469static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev, 469static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev,
470 uint32_t id) 470 uint32_t id)
471{ 471{
472 struct drm_mode_object *obj = NULL; 472 struct drm_mode_object *obj = NULL;
473 struct drm_framebuffer *fb; 473 struct drm_framebuffer *fb;
474 474
475 mutex_lock(&dev->mode_config.idr_mutex); 475 mutex_lock(&dev->mode_config.idr_mutex);
476 obj = idr_find(&dev->mode_config.crtc_idr, id); 476 obj = idr_find(&dev->mode_config.crtc_idr, id);
477 if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id)) 477 if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id))
478 fb = NULL; 478 fb = NULL;
479 else 479 else
480 fb = obj_to_fb(obj); 480 fb = obj_to_fb(obj);
481 mutex_unlock(&dev->mode_config.idr_mutex); 481 mutex_unlock(&dev->mode_config.idr_mutex);
482 482
483 return fb; 483 return fb;
484} 484}
485 485
486/** 486/**
487 * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference 487 * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
488 * @dev: drm device 488 * @dev: drm device
489 * @id: id of the fb object 489 * @id: id of the fb object
490 * 490 *
491 * If successful, this grabs an additional reference to the framebuffer - 491 * If successful, this grabs an additional reference to the framebuffer -
492 * callers need to make sure to eventually unreference the returned framebuffer 492 * callers need to make sure to eventually unreference the returned framebuffer
493 * again, using @drm_framebuffer_unreference. 493 * again, using @drm_framebuffer_unreference.
494 */ 494 */
495struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, 495struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
496 uint32_t id) 496 uint32_t id)
497{ 497{
498 struct drm_framebuffer *fb; 498 struct drm_framebuffer *fb;
499 499
500 mutex_lock(&dev->mode_config.fb_lock); 500 mutex_lock(&dev->mode_config.fb_lock);
501 fb = __drm_framebuffer_lookup(dev, id); 501 fb = __drm_framebuffer_lookup(dev, id);
502 if (fb) { 502 if (fb) {
503 if (!kref_get_unless_zero(&fb->refcount)) 503 if (!kref_get_unless_zero(&fb->refcount))
504 fb = NULL; 504 fb = NULL;
505 } 505 }
506 mutex_unlock(&dev->mode_config.fb_lock); 506 mutex_unlock(&dev->mode_config.fb_lock);
507 507
508 return fb; 508 return fb;
509} 509}
510EXPORT_SYMBOL(drm_framebuffer_lookup); 510EXPORT_SYMBOL(drm_framebuffer_lookup);
511 511
512/** 512/**
513 * drm_framebuffer_unreference - unref a framebuffer 513 * drm_framebuffer_unreference - unref a framebuffer
514 * @fb: framebuffer to unref 514 * @fb: framebuffer to unref
515 * 515 *
516 * This functions decrements the fb's refcount and frees it if it drops to zero. 516 * This functions decrements the fb's refcount and frees it if it drops to zero.
517 */ 517 */
518void drm_framebuffer_unreference(struct drm_framebuffer *fb) 518void drm_framebuffer_unreference(struct drm_framebuffer *fb)
519{ 519{
520 DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, fb->refcount.kr_count); 520 DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, fb->refcount.kr_count);
521 kref_put(&fb->refcount, drm_framebuffer_free); 521 kref_put(&fb->refcount, drm_framebuffer_free);
522} 522}
523EXPORT_SYMBOL(drm_framebuffer_unreference); 523EXPORT_SYMBOL(drm_framebuffer_unreference);
524 524
525/** 525/**
526 * drm_framebuffer_reference - incr the fb refcnt 526 * drm_framebuffer_reference - incr the fb refcnt
527 * @fb: framebuffer 527 * @fb: framebuffer
528 * 528 *
529 * This functions increments the fb's refcount. 529 * This functions increments the fb's refcount.
530 */ 530 */
531void drm_framebuffer_reference(struct drm_framebuffer *fb) 531void drm_framebuffer_reference(struct drm_framebuffer *fb)
532{ 532{
533 DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, fb->refcount.kr_count); 533 DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, fb->refcount.kr_count);
534 kref_get(&fb->refcount); 534 kref_get(&fb->refcount);
535} 535}
536EXPORT_SYMBOL(drm_framebuffer_reference); 536EXPORT_SYMBOL(drm_framebuffer_reference);
537 537
538/** 538/**
539 * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr 539 * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
540 * @fb: fb to unregister 540 * @fb: fb to unregister
541 * 541 *
542 * Drivers need to call this when cleaning up driver-private framebuffers, e.g. 542 * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
543 * those used for fbdev. Note that the caller must hold a reference of it's own, 543 * those used for fbdev. Note that the caller must hold a reference of it's own,
544 * i.e. the object may not be destroyed through this call (since it'll lead to a 544 * i.e. the object may not be destroyed through this call (since it'll lead to a
545 * locking inversion). 545 * locking inversion).
546 */ 546 */
547void drm_framebuffer_unregister_private(struct drm_framebuffer *fb) 547void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
548{ 548{
549 struct drm_device *dev; 549 struct drm_device *dev;
550 550
551 if (!fb) 551 if (!fb)
552 return; 552 return;
553 553
554 dev = fb->dev; 554 dev = fb->dev;
555 555
556 mutex_lock(&dev->mode_config.fb_lock); 556 mutex_lock(&dev->mode_config.fb_lock);
557 /* Mark fb as reaped and drop idr ref. */ 557 /* Mark fb as reaped and drop idr ref. */
558 __drm_framebuffer_unregister(dev, fb); 558 __drm_framebuffer_unregister(dev, fb);
559 mutex_unlock(&dev->mode_config.fb_lock); 559 mutex_unlock(&dev->mode_config.fb_lock);
560} 560}
561EXPORT_SYMBOL(drm_framebuffer_unregister_private); 561EXPORT_SYMBOL(drm_framebuffer_unregister_private);
562 562
563/** 563/**
564 * drm_framebuffer_cleanup - remove a framebuffer object 564 * drm_framebuffer_cleanup - remove a framebuffer object
565 * @fb: framebuffer to remove 565 * @fb: framebuffer to remove
566 * 566 *
567 * Cleanup framebuffer. This function is intended to be used from the drivers 567 * Cleanup framebuffer. This function is intended to be used from the drivers
568 * ->destroy callback. It can also be used to clean up driver private 568 * ->destroy callback. It can also be used to clean up driver private
569 * framebuffers embedded into a larger structure. 569 * framebuffers embedded into a larger structure.
570 * 570 *
571 * Note that this function does not remove the fb from active usuage - if it is 571 * Note that this function does not remove the fb from active usuage - if it is
572 * still used anywhere, hilarity can ensue since userspace could call getfb on 572 * still used anywhere, hilarity can ensue since userspace could call getfb on
573 * the id and get back -EINVAL. Obviously no concern at driver unload time. 573 * the id and get back -EINVAL. Obviously no concern at driver unload time.
574 * 574 *
575 * Also, the framebuffer will not be removed from the lookup idr - for 575 * Also, the framebuffer will not be removed from the lookup idr - for
576 * user-created framebuffers this will happen in in the rmfb ioctl. For 576 * user-created framebuffers this will happen in in the rmfb ioctl. For
577 * driver-private objects (e.g. for fbdev) drivers need to explicitly call 577 * driver-private objects (e.g. for fbdev) drivers need to explicitly call
578 * drm_framebuffer_unregister_private. 578 * drm_framebuffer_unregister_private.
579 */ 579 */
580void drm_framebuffer_cleanup(struct drm_framebuffer *fb) 580void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
581{ 581{
582 struct drm_device *dev = fb->dev; 582 struct drm_device *dev = fb->dev;
583 583
584 mutex_lock(&dev->mode_config.fb_lock); 584 mutex_lock(&dev->mode_config.fb_lock);
585 list_del(&fb->head); 585 list_del(&fb->head);
586 dev->mode_config.num_fb--; 586 dev->mode_config.num_fb--;
587 mutex_unlock(&dev->mode_config.fb_lock); 587 mutex_unlock(&dev->mode_config.fb_lock);
588} 588}
589EXPORT_SYMBOL(drm_framebuffer_cleanup); 589EXPORT_SYMBOL(drm_framebuffer_cleanup);
590 590
591/** 591/**
592 * drm_framebuffer_remove - remove and unreference a framebuffer object 592 * drm_framebuffer_remove - remove and unreference a framebuffer object
593 * @fb: framebuffer to remove 593 * @fb: framebuffer to remove
594 * 594 *
595 * Scans all the CRTCs and planes in @dev's mode_config. If they're 595 * Scans all the CRTCs and planes in @dev's mode_config. If they're
596 * using @fb, removes it, setting it to NULL. Then drops the reference to the 596 * using @fb, removes it, setting it to NULL. Then drops the reference to the
597 * passed-in framebuffer. Might take the modeset locks. 597 * passed-in framebuffer. Might take the modeset locks.
598 * 598 *
599 * Note that this function optimizes the cleanup away if the caller holds the 599 * Note that this function optimizes the cleanup away if the caller holds the
600 * last reference to the framebuffer. It is also guaranteed to not take the 600 * last reference to the framebuffer. It is also guaranteed to not take the
601 * modeset locks in this case. 601 * modeset locks in this case.
602 */ 602 */
603void drm_framebuffer_remove(struct drm_framebuffer *fb) 603void drm_framebuffer_remove(struct drm_framebuffer *fb)
604{ 604{
605 struct drm_device *dev; 605 struct drm_device *dev;
606 struct drm_crtc *crtc; 606 struct drm_crtc *crtc;
607 struct drm_plane *plane; 607 struct drm_plane *plane;
608 struct drm_mode_set set; 608 struct drm_mode_set set;
609 int ret; 609 int ret;
610 610
611 if (!fb) 611 if (!fb)
612 return; 612 return;
613 613
614 dev = fb->dev; 614 dev = fb->dev;
615 615
616 WARN_ON(!list_empty(&fb->filp_head)); 616 WARN_ON(!list_empty(&fb->filp_head));
617 617
618 /* 618 /*
619 * drm ABI mandates that we remove any deleted framebuffers from active 619 * drm ABI mandates that we remove any deleted framebuffers from active
620 * useage. But since most sane clients only remove framebuffers they no 620 * useage. But since most sane clients only remove framebuffers they no
621 * longer need, try to optimize this away. 621 * longer need, try to optimize this away.
622 * 622 *
623 * Since we're holding a reference ourselves, observing a refcount of 1 623 * Since we're holding a reference ourselves, observing a refcount of 1
624 * means that we're the last holder and can skip it. Also, the refcount 624 * means that we're the last holder and can skip it. Also, the refcount
625 * can never increase from 1 again, so we don't need any barriers or 625 * can never increase from 1 again, so we don't need any barriers or
626 * locks. 626 * locks.
627 * 627 *
628 * Note that userspace could try to race with use and instate a new 628 * Note that userspace could try to race with use and instate a new
629 * usage _after_ we've cleared all current ones. End result will be an 629 * usage _after_ we've cleared all current ones. End result will be an
630 * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot 630 * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
631 * in this manner. 631 * in this manner.
632 */ 632 */
633 if (!kref_exclusive_p(&fb->refcount)) { 633 if (!kref_exclusive_p(&fb->refcount)) {
634 drm_modeset_lock_all(dev); 634 drm_modeset_lock_all(dev);
635 /* remove from any CRTC */ 635 /* remove from any CRTC */
636 drm_for_each_crtc(crtc, dev) { 636 drm_for_each_crtc(crtc, dev) {
637 if (crtc->primary->fb == fb) { 637 if (crtc->primary->fb == fb) {
638 /* should turn off the crtc */ 638 /* should turn off the crtc */
639 memset(&set, 0, sizeof(struct drm_mode_set)); 639 memset(&set, 0, sizeof(struct drm_mode_set));
640 set.crtc = crtc; 640 set.crtc = crtc;
641 set.fb = NULL; 641 set.fb = NULL;
642 ret = drm_mode_set_config_internal(&set); 642 ret = drm_mode_set_config_internal(&set);
643 if (ret) 643 if (ret)
644 DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); 644 DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
645 } 645 }
646 } 646 }
647 647
648 drm_for_each_plane(plane, dev) { 648 drm_for_each_plane(plane, dev) {
649 if (plane->fb == fb) 649 if (plane->fb == fb)
650 drm_plane_force_disable(plane); 650 drm_plane_force_disable(plane);
651 } 651 }
652 drm_modeset_unlock_all(dev); 652 drm_modeset_unlock_all(dev);
653 } 653 }
654 654
655 drm_framebuffer_unreference(fb); 655 drm_framebuffer_unreference(fb);
656} 656}
657EXPORT_SYMBOL(drm_framebuffer_remove); 657EXPORT_SYMBOL(drm_framebuffer_remove);
658 658
659DEFINE_WW_CLASS(crtc_ww_class); 659DEFINE_WW_CLASS(crtc_ww_class);
660 660
661/** 661/**
662 * drm_crtc_init_with_planes - Initialise a new CRTC object with 662 * drm_crtc_init_with_planes - Initialise a new CRTC object with
663 * specified primary and cursor planes. 663 * specified primary and cursor planes.
664 * @dev: DRM device 664 * @dev: DRM device
665 * @crtc: CRTC object to init 665 * @crtc: CRTC object to init
666 * @primary: Primary plane for CRTC 666 * @primary: Primary plane for CRTC
667 * @cursor: Cursor plane for CRTC 667 * @cursor: Cursor plane for CRTC
668 * @funcs: callbacks for the new CRTC 668 * @funcs: callbacks for the new CRTC
669 * 669 *
670 * Inits a new object created as base part of a driver crtc object. 670 * Inits a new object created as base part of a driver crtc object.
671 * 671 *
672 * Returns: 672 * Returns:
673 * Zero on success, error code on failure. 673 * Zero on success, error code on failure.
674 */ 674 */
675int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, 675int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
676 struct drm_plane *primary, 676 struct drm_plane *primary,
677 struct drm_plane *cursor, 677 struct drm_plane *cursor,
678 const struct drm_crtc_funcs *funcs) 678 const struct drm_crtc_funcs *funcs)
679{ 679{
680 struct drm_mode_config *config = &dev->mode_config; 680 struct drm_mode_config *config = &dev->mode_config;
681 int ret; 681 int ret;
682 682
683 WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY); 683 WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
684 WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR); 684 WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
685 685
686 crtc->dev = dev; 686 crtc->dev = dev;
687 crtc->funcs = funcs; 687 crtc->funcs = funcs;
688 688
689 drm_modeset_lock_init(&crtc->mutex); 689 drm_modeset_lock_init(&crtc->mutex);
690 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); 690 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
691 if (ret) 691 if (ret)
692 return ret; 692 return ret;
693 693
694 crtc->base.properties = &crtc->properties; 694 crtc->base.properties = &crtc->properties;
695 695
696 list_add_tail(&crtc->head, &config->crtc_list); 696 list_add_tail(&crtc->head, &config->crtc_list);
697 config->num_crtc++; 697 config->num_crtc++;
698 698
699 crtc->primary = primary; 699 crtc->primary = primary;
700 crtc->cursor = cursor; 700 crtc->cursor = cursor;
701 if (primary) 701 if (primary)
702 primary->possible_crtcs = 1 << drm_crtc_index(crtc); 702 primary->possible_crtcs = 1 << drm_crtc_index(crtc);
703 if (cursor) 703 if (cursor)
704 cursor->possible_crtcs = 1 << drm_crtc_index(crtc); 704 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
705 705
706 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { 706 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
707 drm_object_attach_property(&crtc->base, config->prop_active, 0); 707 drm_object_attach_property(&crtc->base, config->prop_active, 0);
708 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0); 708 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
709 } 709 }
710 710
711 return 0; 711 return 0;
712} 712}
713EXPORT_SYMBOL(drm_crtc_init_with_planes); 713EXPORT_SYMBOL(drm_crtc_init_with_planes);
714 714
715/** 715/**
716 * drm_crtc_cleanup - Clean up the core crtc usage 716 * drm_crtc_cleanup - Clean up the core crtc usage
717 * @crtc: CRTC to cleanup 717 * @crtc: CRTC to cleanup
718 * 718 *
719 * This function cleans up @crtc and removes it from the DRM mode setting 719 * This function cleans up @crtc and removes it from the DRM mode setting
720 * core. Note that the function does *not* free the crtc structure itself, 720 * core. Note that the function does *not* free the crtc structure itself,
721 * this is the responsibility of the caller. 721 * this is the responsibility of the caller.
722 */ 722 */
723void drm_crtc_cleanup(struct drm_crtc *crtc) 723void drm_crtc_cleanup(struct drm_crtc *crtc)
724{ 724{
725 struct drm_device *dev = crtc->dev; 725 struct drm_device *dev = crtc->dev;
726 726
727 kfree(crtc->gamma_store); 727 kfree(crtc->gamma_store);
728 crtc->gamma_store = NULL; 728 crtc->gamma_store = NULL;
729 729
730 drm_modeset_lock_fini(&crtc->mutex); 730 drm_modeset_lock_fini(&crtc->mutex);
731 731
732 drm_mode_object_put(dev, &crtc->base); 732 drm_mode_object_put(dev, &crtc->base);
733 list_del(&crtc->head); 733 list_del(&crtc->head);
734 dev->mode_config.num_crtc--; 734 dev->mode_config.num_crtc--;
735 735
736 WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state); 736 WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
737 if (crtc->state && crtc->funcs->atomic_destroy_state) 737 if (crtc->state && crtc->funcs->atomic_destroy_state)
738 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 738 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
739 739
740 memset(crtc, 0, sizeof(*crtc)); 740 memset(crtc, 0, sizeof(*crtc));
741} 741}
742EXPORT_SYMBOL(drm_crtc_cleanup); 742EXPORT_SYMBOL(drm_crtc_cleanup);
743 743
744/** 744/**
745 * drm_crtc_index - find the index of a registered CRTC 745 * drm_crtc_index - find the index of a registered CRTC
746 * @crtc: CRTC to find index for 746 * @crtc: CRTC to find index for
747 * 747 *
748 * Given a registered CRTC, return the index of that CRTC within a DRM 748 * Given a registered CRTC, return the index of that CRTC within a DRM
749 * device's list of CRTCs. 749 * device's list of CRTCs.
750 */ 750 */
751unsigned int drm_crtc_index(struct drm_crtc *crtc) 751unsigned int drm_crtc_index(struct drm_crtc *crtc)
752{ 752{
753 unsigned int index = 0; 753 unsigned int index = 0;
754 struct drm_crtc *tmp; 754 struct drm_crtc *tmp;
755 755
756 drm_for_each_crtc(tmp, crtc->dev) { 756 drm_for_each_crtc(tmp, crtc->dev) {
757 if (tmp == crtc) 757 if (tmp == crtc)
758 return index; 758 return index;
759 759
760 index++; 760 index++;
761 } 761 }
762 762
763 BUG(); 763 BUG();
764} 764}
765EXPORT_SYMBOL(drm_crtc_index); 765EXPORT_SYMBOL(drm_crtc_index);
766 766
767/* 767/*
768 * drm_mode_remove - remove and free a mode 768 * drm_mode_remove - remove and free a mode
769 * @connector: connector list to modify 769 * @connector: connector list to modify
770 * @mode: mode to remove 770 * @mode: mode to remove
771 * 771 *
772 * Remove @mode from @connector's mode list, then free it. 772 * Remove @mode from @connector's mode list, then free it.
773 */ 773 */
774static void drm_mode_remove(struct drm_connector *connector, 774static void drm_mode_remove(struct drm_connector *connector,
775 struct drm_display_mode *mode) 775 struct drm_display_mode *mode)
776{ 776{
777 list_del(&mode->head); 777 list_del(&mode->head);
778 drm_mode_destroy(connector->dev, mode); 778 drm_mode_destroy(connector->dev, mode);
779} 779}
780 780
781/** 781/**
782 * drm_display_info_set_bus_formats - set the supported bus formats 782 * drm_display_info_set_bus_formats - set the supported bus formats
783 * @info: display info to store bus formats in 783 * @info: display info to store bus formats in
784 * @formats: array containing the supported bus formats 784 * @formats: array containing the supported bus formats
785 * @num_formats: the number of entries in the fmts array 785 * @num_formats: the number of entries in the fmts array
786 * 786 *
787 * Store the supported bus formats in display info structure. 787 * Store the supported bus formats in display info structure.
788 * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for 788 * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for
789 * a full list of available formats. 789 * a full list of available formats.
790 */ 790 */
791int drm_display_info_set_bus_formats(struct drm_display_info *info, 791int drm_display_info_set_bus_formats(struct drm_display_info *info,
792 const u32 *formats, 792 const u32 *formats,
793 unsigned int num_formats) 793 unsigned int num_formats)
794{ 794{
795 u32 *fmts = NULL; 795 u32 *fmts = NULL;
796 796
797 if (!formats && num_formats) 797 if (!formats && num_formats)
798 return -EINVAL; 798 return -EINVAL;
799 799
800 if (formats && num_formats) { 800 if (formats && num_formats) {
801 fmts = kmemdup(formats, sizeof(*formats) * num_formats, 801 fmts = kmemdup(formats, sizeof(*formats) * num_formats,
802 GFP_KERNEL); 802 GFP_KERNEL);
803 if (!fmts) 803 if (!fmts)
804 return -ENOMEM; 804 return -ENOMEM;
805 } 805 }
806 806
807 kfree(info->bus_formats); 807 kfree(info->bus_formats);
808 info->bus_formats = fmts; 808 info->bus_formats = fmts;
809 info->num_bus_formats = num_formats; 809 info->num_bus_formats = num_formats;
810 810
811 return 0; 811 return 0;
812} 812}
813EXPORT_SYMBOL(drm_display_info_set_bus_formats); 813EXPORT_SYMBOL(drm_display_info_set_bus_formats);
814 814
815/** 815/**
816 * drm_connector_get_cmdline_mode - reads the user's cmdline mode 816 * drm_connector_get_cmdline_mode - reads the user's cmdline mode
817 * @connector: connector to quwery 817 * @connector: connector to quwery
818 * 818 *
819 * The kernel supports per-connector configration of its consoles through 819 * The kernel supports per-connector configration of its consoles through
820 * use of the video= parameter. This function parses that option and 820 * use of the video= parameter. This function parses that option and
821 * extracts the user's specified mode (or enable/disable status) for a 821 * extracts the user's specified mode (or enable/disable status) for a
822 * particular connector. This is typically only used during the early fbdev 822 * particular connector. This is typically only used during the early fbdev
823 * setup. 823 * setup.
824 */ 824 */
825static void drm_connector_get_cmdline_mode(struct drm_connector *connector) 825static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
826{ 826{
827 struct drm_cmdline_mode *mode = &connector->cmdline_mode; 827 struct drm_cmdline_mode *mode = &connector->cmdline_mode;
828 char *option = NULL; 
829 828
830#ifdef __NetBSD__ 829#ifdef __NetBSD__
 830 const char *option;
831 prop_dictionary_t prop = device_properties(connector->dev->dev); 831 prop_dictionary_t prop = device_properties(connector->dev->dev);
832 if (!prop_dictionary_get_cstring(prop, connector->name, &option)) 832 if (!prop_dictionary_get_string(prop, connector->name, &option))
833 return; 833 return;
834#else 834#else
 835 char *option = NULL;
835 if (fb_get_options(connector->name, &option)) 836 if (fb_get_options(connector->name, &option))
836 return; 837 return;
837#endif 838#endif
838 839
839 if (!drm_mode_parse_command_line_for_connector(option, 840 if (!drm_mode_parse_command_line_for_connector(option,
840 connector, 841 connector,
841 mode)) 842 mode))
842 return; 843 return;
843 844
844 if (mode->force) { 845 if (mode->force) {
845 const char *s; 846 const char *s;
846 847
847 switch (mode->force) { 848 switch (mode->force) {
848 case DRM_FORCE_OFF: 849 case DRM_FORCE_OFF:
849 s = "OFF"; 850 s = "OFF";
850 break; 851 break;
851 case DRM_FORCE_ON_DIGITAL: 852 case DRM_FORCE_ON_DIGITAL:
852 s = "ON - dig"; 853 s = "ON - dig";
853 break; 854 break;
854 default: 855 default:
855 case DRM_FORCE_ON: 856 case DRM_FORCE_ON:
856 s = "ON"; 857 s = "ON";
857 break; 858 break;
858 } 859 }
859 860
860 DRM_INFO("forcing %s connector %s\n", connector->name, s); 861 DRM_INFO("forcing %s connector %s\n", connector->name, s);
861 connector->force = mode->force; 862 connector->force = mode->force;
862 } 863 }
863 864
864 DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", 865 DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
865 connector->name, 866 connector->name,
866 mode->xres, mode->yres, 867 mode->xres, mode->yres,
867 mode->refresh_specified ? mode->refresh : 60, 868 mode->refresh_specified ? mode->refresh : 60,
868 mode->rb ? " reduced blanking" : "", 869 mode->rb ? " reduced blanking" : "",
869 mode->margins ? " with margins" : "", 870 mode->margins ? " with margins" : "",
870 mode->interlace ? " interlaced" : ""); 871 mode->interlace ? " interlaced" : "");
871} 872}
872 873
873/** 874/**
874 * drm_connector_init - Init a preallocated connector 875 * drm_connector_init - Init a preallocated connector
875 * @dev: DRM device 876 * @dev: DRM device
876 * @connector: the connector to init 877 * @connector: the connector to init
877 * @funcs: callbacks for this connector 878 * @funcs: callbacks for this connector
878 * @connector_type: user visible type of the connector 879 * @connector_type: user visible type of the connector
879 * 880 *
880 * Initialises a preallocated connector. Connectors should be 881 * Initialises a preallocated connector. Connectors should be
881 * subclassed as part of driver connector objects. 882 * subclassed as part of driver connector objects.
882 * 883 *
883 * Returns: 884 * Returns:
884 * Zero on success, error code on failure. 885 * Zero on success, error code on failure.
885 */ 886 */
886int drm_connector_init(struct drm_device *dev, 887int drm_connector_init(struct drm_device *dev,
887 struct drm_connector *connector, 888 struct drm_connector *connector,
888 const struct drm_connector_funcs *funcs, 889 const struct drm_connector_funcs *funcs,
889 int connector_type) 890 int connector_type)
890{ 891{
891 struct drm_mode_config *config = &dev->mode_config; 892 struct drm_mode_config *config = &dev->mode_config;
892 int ret; 893 int ret;
893 struct ida *connector_ida = 894 struct ida *connector_ida =
894 &drm_connector_enum_list[connector_type].ida; 895 &drm_connector_enum_list[connector_type].ida;
895 896
896 drm_modeset_lock_all(dev); 897 drm_modeset_lock_all(dev);
897 898
898 ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false); 899 ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false);
899 if (ret) 900 if (ret)
900 goto out_unlock; 901 goto out_unlock;
901 902
902 connector->base.properties = &connector->properties; 903 connector->base.properties = &connector->properties;
903 connector->dev = dev; 904 connector->dev = dev;
904 connector->kdev = dev->dev; 905 connector->kdev = dev->dev;
905 connector->funcs = funcs; 906 connector->funcs = funcs;
906 connector->connector_type = connector_type; 907 connector->connector_type = connector_type;
907 connector->connector_type_id = 908 connector->connector_type_id =
908 ida_simple_get(connector_ida, 1, 0, GFP_KERNEL); 909 ida_simple_get(connector_ida, 1, 0, GFP_KERNEL);
909 if (connector->connector_type_id < 0) { 910 if (connector->connector_type_id < 0) {
910 ret = connector->connector_type_id; 911 ret = connector->connector_type_id;
911 goto out_put; 912 goto out_put;
912 } 913 }
913 connector->name = 914 connector->name =
914 kasprintf(GFP_KERNEL, "%s-%d", 915 kasprintf(GFP_KERNEL, "%s-%d",
915 drm_connector_enum_list[connector_type].name, 916 drm_connector_enum_list[connector_type].name,
916 connector->connector_type_id); 917 connector->connector_type_id);
917 if (!connector->name) { 918 if (!connector->name) {
918 ret = -ENOMEM; 919 ret = -ENOMEM;
919 goto out_put; 920 goto out_put;
920 } 921 }
921 922
922 INIT_LIST_HEAD(&connector->probed_modes); 923 INIT_LIST_HEAD(&connector->probed_modes);
923 INIT_LIST_HEAD(&connector->modes); 924 INIT_LIST_HEAD(&connector->modes);
924 connector->edid_blob_ptr = NULL; 925 connector->edid_blob_ptr = NULL;
925 connector->status = connector_status_unknown; 926 connector->status = connector_status_unknown;
926 927
927 drm_connector_get_cmdline_mode(connector); 928 drm_connector_get_cmdline_mode(connector);
928 929
929 /* We should add connectors at the end to avoid upsetting the connector 930 /* We should add connectors at the end to avoid upsetting the connector
930 * index too much. */ 931 * index too much. */
931 list_add_tail(&connector->head, &config->connector_list); 932 list_add_tail(&connector->head, &config->connector_list);
932 config->num_connector++; 933 config->num_connector++;
933 934
934 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) 935 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
935 drm_object_attach_property(&connector->base, 936 drm_object_attach_property(&connector->base,
936 config->edid_property, 937 config->edid_property,
937 0); 938 0);
938 939
939 drm_object_attach_property(&connector->base, 940 drm_object_attach_property(&connector->base,
940 config->dpms_property, 0); 941 config->dpms_property, 0);
941 942
942 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { 943 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
943 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0); 944 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
944 } 945 }
945 946
946 connector->debugfs_entry = NULL; 947 connector->debugfs_entry = NULL;
947 948
948out_put: 949out_put:
949 if (ret) 950 if (ret)
950 drm_mode_object_put(dev, &connector->base); 951 drm_mode_object_put(dev, &connector->base);
951 952
952out_unlock: 953out_unlock:
953 drm_modeset_unlock_all(dev); 954 drm_modeset_unlock_all(dev);
954 955
955 return ret; 956 return ret;
956} 957}
957EXPORT_SYMBOL(drm_connector_init); 958EXPORT_SYMBOL(drm_connector_init);
958 959
959/** 960/**
960 * drm_connector_cleanup - cleans up an initialised connector 961 * drm_connector_cleanup - cleans up an initialised connector
961 * @connector: connector to cleanup 962 * @connector: connector to cleanup
962 * 963 *
963 * Cleans up the connector but doesn't free the object. 964 * Cleans up the connector but doesn't free the object.
964 */ 965 */
965void drm_connector_cleanup(struct drm_connector *connector) 966void drm_connector_cleanup(struct drm_connector *connector)
966{ 967{
967 struct drm_device *dev = connector->dev; 968 struct drm_device *dev = connector->dev;
968 struct drm_display_mode *mode, *t; 969 struct drm_display_mode *mode, *t;
969 970
970 if (connector->tile_group) { 971 if (connector->tile_group) {
971 drm_mode_put_tile_group(dev, connector->tile_group); 972 drm_mode_put_tile_group(dev, connector->tile_group);
972 connector->tile_group = NULL; 973 connector->tile_group = NULL;
973 } 974 }
974 975
975 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) 976 list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
976 drm_mode_remove(connector, mode); 977 drm_mode_remove(connector, mode);
977 978
978 list_for_each_entry_safe(mode, t, &connector->modes, head) 979 list_for_each_entry_safe(mode, t, &connector->modes, head)
979 drm_mode_remove(connector, mode); 980 drm_mode_remove(connector, mode);
980 981
981 ida_remove(&drm_connector_enum_list[connector->connector_type].ida, 982 ida_remove(&drm_connector_enum_list[connector->connector_type].ida,
982 connector->connector_type_id); 983 connector->connector_type_id);
983 984
984 kfree(connector->display_info.bus_formats); 985 kfree(connector->display_info.bus_formats);
985 drm_mode_object_put(dev, &connector->base); 986 drm_mode_object_put(dev, &connector->base);
986 kfree(connector->name); 987 kfree(connector->name);
987 connector->name = NULL; 988 connector->name = NULL;
988 list_del(&connector->head); 989 list_del(&connector->head);
989 dev->mode_config.num_connector--; 990 dev->mode_config.num_connector--;
990 991
991 WARN_ON(connector->state && !connector->funcs->atomic_destroy_state); 992 WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);
992 if (connector->state && connector->funcs->atomic_destroy_state) 993 if (connector->state && connector->funcs->atomic_destroy_state)
993 connector->funcs->atomic_destroy_state(connector, 994 connector->funcs->atomic_destroy_state(connector,
994 connector->state); 995 connector->state);
995 996
996 memset(connector, 0, sizeof(*connector)); 997 memset(connector, 0, sizeof(*connector));
997} 998}
998EXPORT_SYMBOL(drm_connector_cleanup); 999EXPORT_SYMBOL(drm_connector_cleanup);
999 1000
1000/** 1001/**
1001 * drm_connector_index - find the index of a registered connector 1002 * drm_connector_index - find the index of a registered connector
1002 * @connector: connector to find index for 1003 * @connector: connector to find index for
1003 * 1004 *
1004 * Given a registered connector, return the index of that connector within a DRM 1005 * Given a registered connector, return the index of that connector within a DRM
1005 * device's list of connectors. 1006 * device's list of connectors.
1006 */ 1007 */
1007unsigned int drm_connector_index(struct drm_connector *connector) 1008unsigned int drm_connector_index(struct drm_connector *connector)
1008{ 1009{
1009 unsigned int index = 0; 1010 unsigned int index = 0;
1010 struct drm_connector *tmp; 1011 struct drm_connector *tmp;
1011 struct drm_mode_config *config = &connector->dev->mode_config; 1012 struct drm_mode_config *config = &connector->dev->mode_config;
1012 1013
1013 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); 1014 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
1014 1015
1015 drm_for_each_connector(tmp, connector->dev) { 1016 drm_for_each_connector(tmp, connector->dev) {
1016 if (tmp == connector) 1017 if (tmp == connector)
1017 return index; 1018 return index;
1018 1019
1019 index++; 1020 index++;
1020 } 1021 }
1021 1022
1022 BUG(); 1023 BUG();
1023} 1024}
1024EXPORT_SYMBOL(drm_connector_index); 1025EXPORT_SYMBOL(drm_connector_index);
1025 1026
1026/** 1027/**
1027 * drm_connector_register - register a connector 1028 * drm_connector_register - register a connector
1028 * @connector: the connector to register 1029 * @connector: the connector to register
1029 * 1030 *
1030 * Register userspace interfaces for a connector 1031 * Register userspace interfaces for a connector
1031 * 1032 *
1032 * Returns: 1033 * Returns:
1033 * Zero on success, error code on failure. 1034 * Zero on success, error code on failure.
1034 */ 1035 */
1035int drm_connector_register(struct drm_connector *connector) 1036int drm_connector_register(struct drm_connector *connector)
1036{ 1037{
1037#ifndef __NetBSD__ /* XXX sysfs, debugfs */ 1038#ifndef __NetBSD__ /* XXX sysfs, debugfs */
1038 int ret; 1039 int ret;
1039#endif 1040#endif
1040 1041
1041 drm_mode_object_register(connector->dev, &connector->base); 1042 drm_mode_object_register(connector->dev, &connector->base);
1042 1043
1043#ifndef __NetBSD__ /* XXX sysfs, debugfs */ 1044#ifndef __NetBSD__ /* XXX sysfs, debugfs */
1044 ret = drm_sysfs_connector_add(connector); 1045 ret = drm_sysfs_connector_add(connector);
1045 if (ret) 1046 if (ret)
1046 return ret; 1047 return ret;
1047 1048
1048 ret = drm_debugfs_connector_add(connector); 1049 ret = drm_debugfs_connector_add(connector);
1049 if (ret) { 1050 if (ret) {
1050 drm_sysfs_connector_remove(connector); 1051 drm_sysfs_connector_remove(connector);
1051 return ret; 1052 return ret;
1052 } 1053 }
1053#endif 1054#endif
1054 1055
1055 return 0; 1056 return 0;
1056} 1057}
1057EXPORT_SYMBOL(drm_connector_register); 1058EXPORT_SYMBOL(drm_connector_register);
1058 1059
1059/** 1060/**
1060 * drm_connector_unregister - unregister a connector 1061 * drm_connector_unregister - unregister a connector
1061 * @connector: the connector to unregister 1062 * @connector: the connector to unregister
1062 * 1063 *
1063 * Unregister userspace interfaces for a connector 1064 * Unregister userspace interfaces for a connector
1064 */ 1065 */
1065void drm_connector_unregister(struct drm_connector *connector) 1066void drm_connector_unregister(struct drm_connector *connector)
1066{ 1067{
1067#ifndef __NetBSD__ /* XXX sysfs, debugfs */ 1068#ifndef __NetBSD__ /* XXX sysfs, debugfs */
1068 drm_sysfs_connector_remove(connector); 1069 drm_sysfs_connector_remove(connector);
1069 drm_debugfs_connector_remove(connector); 1070 drm_debugfs_connector_remove(connector);
1070#endif 1071#endif
1071} 1072}
1072EXPORT_SYMBOL(drm_connector_unregister); 1073EXPORT_SYMBOL(drm_connector_unregister);
1073 1074
1074 1075
1075/** 1076/**
1076 * drm_connector_unplug_all - unregister connector userspace interfaces 1077 * drm_connector_unplug_all - unregister connector userspace interfaces
1077 * @dev: drm device 1078 * @dev: drm device
1078 * 1079 *
1079 * This function unregisters all connector userspace interfaces in sysfs. Should 1080 * This function unregisters all connector userspace interfaces in sysfs. Should
1080 * be call when the device is disconnected, e.g. from an usb driver's 1081 * be call when the device is disconnected, e.g. from an usb driver's
1081 * ->disconnect callback. 1082 * ->disconnect callback.
1082 */ 1083 */
1083void drm_connector_unplug_all(struct drm_device *dev) 1084void drm_connector_unplug_all(struct drm_device *dev)
1084{ 1085{
1085 struct drm_connector *connector; 1086 struct drm_connector *connector;
1086 1087
1087 /* FIXME: taking the mode config mutex ends up in a clash with sysfs */ 1088 /* FIXME: taking the mode config mutex ends up in a clash with sysfs */
1088 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 1089 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
1089 drm_connector_unregister(connector); 1090 drm_connector_unregister(connector);
1090 1091
1091} 1092}
1092EXPORT_SYMBOL(drm_connector_unplug_all); 1093EXPORT_SYMBOL(drm_connector_unplug_all);
1093 1094
1094/** 1095/**
1095 * drm_encoder_init - Init a preallocated encoder 1096 * drm_encoder_init - Init a preallocated encoder
1096 * @dev: drm device 1097 * @dev: drm device
1097 * @encoder: the encoder to init 1098 * @encoder: the encoder to init
1098 * @funcs: callbacks for this encoder 1099 * @funcs: callbacks for this encoder
1099 * @encoder_type: user visible type of the encoder 1100 * @encoder_type: user visible type of the encoder
1100 * 1101 *
1101 * Initialises a preallocated encoder. Encoder should be 1102 * Initialises a preallocated encoder. Encoder should be
1102 * subclassed as part of driver encoder objects. 1103 * subclassed as part of driver encoder objects.
1103 * 1104 *
1104 * Returns: 1105 * Returns:
1105 * Zero on success, error code on failure. 1106 * Zero on success, error code on failure.
1106 */ 1107 */
1107int drm_encoder_init(struct drm_device *dev, 1108int drm_encoder_init(struct drm_device *dev,
1108 struct drm_encoder *encoder, 1109 struct drm_encoder *encoder,
1109 const struct drm_encoder_funcs *funcs, 1110 const struct drm_encoder_funcs *funcs,
1110 int encoder_type) 1111 int encoder_type)
1111{ 1112{
1112 int ret; 1113 int ret;
1113 1114
1114 drm_modeset_lock_all(dev); 1115 drm_modeset_lock_all(dev);
1115 1116
1116 ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); 1117 ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
1117 if (ret) 1118 if (ret)
1118 goto out_unlock; 1119 goto out_unlock;
1119 1120
1120 encoder->dev = dev; 1121 encoder->dev = dev;
1121 encoder->encoder_type = encoder_type; 1122 encoder->encoder_type = encoder_type;
1122 encoder->funcs = funcs; 1123 encoder->funcs = funcs;
1123 encoder->name = kasprintf(GFP_KERNEL, "%s-%d", 1124 encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
1124 drm_encoder_enum_list[encoder_type].name, 1125 drm_encoder_enum_list[encoder_type].name,
1125 encoder->base.id); 1126 encoder->base.id);
1126 if (!encoder->name) { 1127 if (!encoder->name) {
1127 ret = -ENOMEM; 1128 ret = -ENOMEM;
1128 goto out_put; 1129 goto out_put;
1129 } 1130 }
1130 1131
1131 list_add_tail(&encoder->head, &dev->mode_config.encoder_list); 1132 list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
1132 dev->mode_config.num_encoder++; 1133 dev->mode_config.num_encoder++;
1133 1134
1134out_put: 1135out_put:
1135 if (ret) 1136 if (ret)
1136 drm_mode_object_put(dev, &encoder->base); 1137 drm_mode_object_put(dev, &encoder->base);
1137 1138
1138out_unlock: 1139out_unlock:
1139 drm_modeset_unlock_all(dev); 1140 drm_modeset_unlock_all(dev);
1140 1141
1141 return ret; 1142 return ret;
1142} 1143}
1143EXPORT_SYMBOL(drm_encoder_init); 1144EXPORT_SYMBOL(drm_encoder_init);
1144 1145
1145/** 1146/**
1146 * drm_encoder_cleanup - cleans up an initialised encoder 1147 * drm_encoder_cleanup - cleans up an initialised encoder
1147 * @encoder: encoder to cleanup 1148 * @encoder: encoder to cleanup
1148 * 1149 *
1149 * Cleans up the encoder but doesn't free the object. 1150 * Cleans up the encoder but doesn't free the object.
1150 */ 1151 */
1151void drm_encoder_cleanup(struct drm_encoder *encoder) 1152void drm_encoder_cleanup(struct drm_encoder *encoder)
1152{ 1153{
1153 struct drm_device *dev = encoder->dev; 1154 struct drm_device *dev = encoder->dev;
1154 1155
1155 drm_modeset_lock_all(dev); 1156 drm_modeset_lock_all(dev);
1156 drm_mode_object_put(dev, &encoder->base); 1157 drm_mode_object_put(dev, &encoder->base);
1157 kfree(encoder->name); 1158 kfree(encoder->name);
1158 list_del(&encoder->head); 1159 list_del(&encoder->head);
1159 dev->mode_config.num_encoder--; 1160 dev->mode_config.num_encoder--;
1160 drm_modeset_unlock_all(dev); 1161 drm_modeset_unlock_all(dev);
1161 1162
1162 memset(encoder, 0, sizeof(*encoder)); 1163 memset(encoder, 0, sizeof(*encoder));
1163} 1164}
1164EXPORT_SYMBOL(drm_encoder_cleanup); 1165EXPORT_SYMBOL(drm_encoder_cleanup);
1165 1166
1166/** 1167/**
1167 * drm_universal_plane_init - Initialize a new universal plane object 1168 * drm_universal_plane_init - Initialize a new universal plane object
1168 * @dev: DRM device 1169 * @dev: DRM device
1169 * @plane: plane object to init 1170 * @plane: plane object to init
1170 * @possible_crtcs: bitmask of possible CRTCs 1171 * @possible_crtcs: bitmask of possible CRTCs
1171 * @funcs: callbacks for the new plane 1172 * @funcs: callbacks for the new plane
1172 * @formats: array of supported formats (%DRM_FORMAT_*) 1173 * @formats: array of supported formats (%DRM_FORMAT_*)
1173 * @format_count: number of elements in @formats 1174 * @format_count: number of elements in @formats
1174 * @type: type of plane (overlay, primary, cursor) 1175 * @type: type of plane (overlay, primary, cursor)
1175 * 1176 *
1176 * Initializes a plane object of type @type. 1177 * Initializes a plane object of type @type.
1177 * 1178 *
1178 * Returns: 1179 * Returns:
1179 * Zero on success, error code on failure. 1180 * Zero on success, error code on failure.
1180 */ 1181 */
1181int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, 1182int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1182 unsigned long possible_crtcs, 1183 unsigned long possible_crtcs,
1183 const struct drm_plane_funcs *funcs, 1184 const struct drm_plane_funcs *funcs,
1184 const uint32_t *formats, unsigned int format_count, 1185 const uint32_t *formats, unsigned int format_count,
1185 enum drm_plane_type type) 1186 enum drm_plane_type type)
1186{ 1187{
1187 struct drm_mode_config *config = &dev->mode_config; 1188 struct drm_mode_config *config = &dev->mode_config;
1188 int ret; 1189 int ret;
1189 1190
1190 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 1191 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
1191 if (ret) 1192 if (ret)
1192 return ret; 1193 return ret;
1193 1194
1194 drm_modeset_lock_init(&plane->mutex); 1195 drm_modeset_lock_init(&plane->mutex);
1195 1196
1196 plane->base.properties = &plane->properties; 1197 plane->base.properties = &plane->properties;
1197 plane->dev = dev; 1198 plane->dev = dev;
1198 plane->funcs = funcs; 1199 plane->funcs = funcs;
1199 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t), 1200 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
1200 GFP_KERNEL); 1201 GFP_KERNEL);
1201 if (!plane->format_types) { 1202 if (!plane->format_types) {
1202 DRM_DEBUG_KMS("out of memory when allocating plane\n"); 1203 DRM_DEBUG_KMS("out of memory when allocating plane\n");
1203 drm_mode_object_put(dev, &plane->base); 1204 drm_mode_object_put(dev, &plane->base);
1204 return -ENOMEM; 1205 return -ENOMEM;
1205 } 1206 }
1206 1207
1207 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); 1208 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
1208 plane->format_count = format_count; 1209 plane->format_count = format_count;
1209 plane->possible_crtcs = possible_crtcs; 1210 plane->possible_crtcs = possible_crtcs;
1210 plane->type = type; 1211 plane->type = type;
1211 1212
1212 list_add_tail(&plane->head, &config->plane_list); 1213 list_add_tail(&plane->head, &config->plane_list);
1213 config->num_total_plane++; 1214 config->num_total_plane++;
1214 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1215 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1215 config->num_overlay_plane++; 1216 config->num_overlay_plane++;
1216 1217
1217 drm_object_attach_property(&plane->base, 1218 drm_object_attach_property(&plane->base,
1218 config->plane_type_property, 1219 config->plane_type_property,
1219 plane->type); 1220 plane->type);
1220 1221
1221 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { 1222 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
1222 drm_object_attach_property(&plane->base, config->prop_fb_id, 0); 1223 drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
1223 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0); 1224 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
1224 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0); 1225 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
1225 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0); 1226 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
1226 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0); 1227 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
1227 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0); 1228 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
1228 drm_object_attach_property(&plane->base, config->prop_src_x, 0); 1229 drm_object_attach_property(&plane->base, config->prop_src_x, 0);
1229 drm_object_attach_property(&plane->base, config->prop_src_y, 0); 1230 drm_object_attach_property(&plane->base, config->prop_src_y, 0);
1230 drm_object_attach_property(&plane->base, config->prop_src_w, 0); 1231 drm_object_attach_property(&plane->base, config->prop_src_w, 0);
1231 drm_object_attach_property(&plane->base, config->prop_src_h, 0); 1232 drm_object_attach_property(&plane->base, config->prop_src_h, 0);
1232 } 1233 }
1233 1234
1234 return 0; 1235 return 0;
1235} 1236}
1236EXPORT_SYMBOL(drm_universal_plane_init); 1237EXPORT_SYMBOL(drm_universal_plane_init);
1237 1238
1238/** 1239/**
1239 * drm_plane_init - Initialize a legacy plane 1240 * drm_plane_init - Initialize a legacy plane
1240 * @dev: DRM device 1241 * @dev: DRM device
1241 * @plane: plane object to init 1242 * @plane: plane object to init
1242 * @possible_crtcs: bitmask of possible CRTCs 1243 * @possible_crtcs: bitmask of possible CRTCs
1243 * @funcs: callbacks for the new plane 1244 * @funcs: callbacks for the new plane
1244 * @formats: array of supported formats (%DRM_FORMAT_*) 1245 * @formats: array of supported formats (%DRM_FORMAT_*)
1245 * @format_count: number of elements in @formats 1246 * @format_count: number of elements in @formats
1246 * @is_primary: plane type (primary vs overlay) 1247 * @is_primary: plane type (primary vs overlay)
1247 * 1248 *
1248 * Legacy API to initialize a DRM plane. 1249 * Legacy API to initialize a DRM plane.
1249 * 1250 *
1250 * New drivers should call drm_universal_plane_init() instead. 1251 * New drivers should call drm_universal_plane_init() instead.
1251 * 1252 *
1252 * Returns: 1253 * Returns:
1253 * Zero on success, error code on failure. 1254 * Zero on success, error code on failure.
1254 */ 1255 */
1255int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, 1256int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
1256 unsigned long possible_crtcs, 1257 unsigned long possible_crtcs,
1257 const struct drm_plane_funcs *funcs, 1258 const struct drm_plane_funcs *funcs,
1258 const uint32_t *formats, unsigned int format_count, 1259 const uint32_t *formats, unsigned int format_count,
1259 bool is_primary) 1260 bool is_primary)
1260{ 1261{
1261 enum drm_plane_type type; 1262 enum drm_plane_type type;
1262 1263
1263 type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 1264 type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
1264 return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 1265 return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
1265 formats, format_count, type); 1266 formats, format_count, type);
1266} 1267}
1267EXPORT_SYMBOL(drm_plane_init); 1268EXPORT_SYMBOL(drm_plane_init);
1268 1269
1269/** 1270/**
1270 * drm_plane_cleanup - Clean up the core plane usage 1271 * drm_plane_cleanup - Clean up the core plane usage
1271 * @plane: plane to cleanup 1272 * @plane: plane to cleanup
1272 * 1273 *
1273 * This function cleans up @plane and removes it from the DRM mode setting 1274 * This function cleans up @plane and removes it from the DRM mode setting
1274 * core. Note that the function does *not* free the plane structure itself, 1275 * core. Note that the function does *not* free the plane structure itself,
1275 * this is the responsibility of the caller. 1276 * this is the responsibility of the caller.
1276 */ 1277 */
1277void drm_plane_cleanup(struct drm_plane *plane) 1278void drm_plane_cleanup(struct drm_plane *plane)
1278{ 1279{
1279 struct drm_device *dev = plane->dev; 1280 struct drm_device *dev = plane->dev;
1280 1281
1281 drm_modeset_lock_all(dev); 1282 drm_modeset_lock_all(dev);
1282 kfree(plane->format_types); 1283 kfree(plane->format_types);
1283 drm_mode_object_put(dev, &plane->base); 1284 drm_mode_object_put(dev, &plane->base);
1284 1285
1285 BUG_ON(list_empty(&plane->head)); 1286 BUG_ON(list_empty(&plane->head));
1286 1287
1287 list_del(&plane->head); 1288 list_del(&plane->head);
1288 dev->mode_config.num_total_plane--; 1289 dev->mode_config.num_total_plane--;
1289 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1290 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1290 dev->mode_config.num_overlay_plane--; 1291 dev->mode_config.num_overlay_plane--;
1291 drm_modeset_unlock_all(dev); 1292 drm_modeset_unlock_all(dev);
1292 1293
1293 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); 1294 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
1294 if (plane->state && plane->funcs->atomic_destroy_state) 1295 if (plane->state && plane->funcs->atomic_destroy_state)
1295 plane->funcs->atomic_destroy_state(plane, plane->state); 1296 plane->funcs->atomic_destroy_state(plane, plane->state);
1296 drm_modeset_lock_fini(&plane->mutex); 1297 drm_modeset_lock_fini(&plane->mutex);
1297 1298
1298 memset(plane, 0, sizeof(*plane)); 1299 memset(plane, 0, sizeof(*plane));
1299} 1300}
1300EXPORT_SYMBOL(drm_plane_cleanup); 1301EXPORT_SYMBOL(drm_plane_cleanup);
1301 1302
1302/** 1303/**
1303 * drm_plane_index - find the index of a registered plane 1304 * drm_plane_index - find the index of a registered plane
1304 * @plane: plane to find index for 1305 * @plane: plane to find index for
1305 * 1306 *
1306 * Given a registered plane, return the index of that CRTC within a DRM 1307 * Given a registered plane, return the index of that CRTC within a DRM
1307 * device's list of planes. 1308 * device's list of planes.
1308 */ 1309 */
1309unsigned int drm_plane_index(struct drm_plane *plane) 1310unsigned int drm_plane_index(struct drm_plane *plane)
1310{ 1311{
1311 unsigned int index = 0; 1312 unsigned int index = 0;
1312 struct drm_plane *tmp; 1313 struct drm_plane *tmp;
1313 1314
1314 drm_for_each_plane(tmp, plane->dev) { 1315 drm_for_each_plane(tmp, plane->dev) {
1315 if (tmp == plane) 1316 if (tmp == plane)
1316 return index; 1317 return index;
1317 1318
1318 index++; 1319 index++;
1319 } 1320 }
1320 1321
1321 BUG(); 1322 BUG();
1322} 1323}
1323EXPORT_SYMBOL(drm_plane_index); 1324EXPORT_SYMBOL(drm_plane_index);
1324 1325
1325/** 1326/**
1326 * drm_plane_from_index - find the registered plane at an index 1327 * drm_plane_from_index - find the registered plane at an index
1327 * @dev: DRM device 1328 * @dev: DRM device
1328 * @idx: index of registered plane to find for 1329 * @idx: index of registered plane to find for
1329 * 1330 *
1330 * Given a plane index, return the registered plane from DRM device's 1331 * Given a plane index, return the registered plane from DRM device's
1331 * list of planes with matching index. 1332 * list of planes with matching index.
1332 */ 1333 */
1333struct drm_plane * 1334struct drm_plane *
1334drm_plane_from_index(struct drm_device *dev, int idx) 1335drm_plane_from_index(struct drm_device *dev, int idx)
1335{ 1336{
1336 struct drm_plane *plane; 1337 struct drm_plane *plane;
1337 unsigned int i = 0; 1338 unsigned int i = 0;
1338 1339
1339 drm_for_each_plane(plane, dev) { 1340 drm_for_each_plane(plane, dev) {
1340 if (i == idx) 1341 if (i == idx)
1341 return plane; 1342 return plane;
1342 i++; 1343 i++;
1343 } 1344 }
1344 return NULL; 1345 return NULL;
1345} 1346}
1346EXPORT_SYMBOL(drm_plane_from_index); 1347EXPORT_SYMBOL(drm_plane_from_index);
1347 1348
1348/** 1349/**
1349 * drm_plane_force_disable - Forcibly disable a plane 1350 * drm_plane_force_disable - Forcibly disable a plane
1350 * @plane: plane to disable 1351 * @plane: plane to disable
1351 * 1352 *
1352 * Forces the plane to be disabled. 1353 * Forces the plane to be disabled.
1353 * 1354 *
1354 * Used when the plane's current framebuffer is destroyed, 1355 * Used when the plane's current framebuffer is destroyed,
1355 * and when restoring fbdev mode. 1356 * and when restoring fbdev mode.
1356 */ 1357 */
1357void drm_plane_force_disable(struct drm_plane *plane) 1358void drm_plane_force_disable(struct drm_plane *plane)
1358{ 1359{
1359 int ret; 1360 int ret;
1360 1361
1361 if (!plane->fb) 1362 if (!plane->fb)
1362 return; 1363 return;
1363 1364
1364 plane->old_fb = plane->fb; 1365 plane->old_fb = plane->fb;
1365 ret = plane->funcs->disable_plane(plane); 1366 ret = plane->funcs->disable_plane(plane);
1366 if (ret) { 1367 if (ret) {
1367 DRM_ERROR("failed to disable plane with busy fb\n"); 1368 DRM_ERROR("failed to disable plane with busy fb\n");
1368 plane->old_fb = NULL; 1369 plane->old_fb = NULL;
1369 return; 1370 return;
1370 } 1371 }
1371 /* disconnect the plane from the fb and crtc: */ 1372 /* disconnect the plane from the fb and crtc: */
1372 drm_framebuffer_unreference(plane->old_fb); 1373 drm_framebuffer_unreference(plane->old_fb);
1373 plane->old_fb = NULL; 1374 plane->old_fb = NULL;
1374 plane->fb = NULL; 1375 plane->fb = NULL;
1375 plane->crtc = NULL; 1376 plane->crtc = NULL;
1376} 1377}
1377EXPORT_SYMBOL(drm_plane_force_disable); 1378EXPORT_SYMBOL(drm_plane_force_disable);
1378 1379
1379static int drm_mode_create_standard_properties(struct drm_device *dev) 1380static int drm_mode_create_standard_properties(struct drm_device *dev)
1380{ 1381{
1381 struct drm_property *prop; 1382 struct drm_property *prop;
1382 1383
1383 /* 1384 /*
1384 * Standard properties (apply to all connectors) 1385 * Standard properties (apply to all connectors)
1385 */ 1386 */
1386 prop = drm_property_create(dev, DRM_MODE_PROP_BLOB | 1387 prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
1387 DRM_MODE_PROP_IMMUTABLE, 1388 DRM_MODE_PROP_IMMUTABLE,
1388 "EDID", 0); 1389 "EDID", 0);
1389 if (!prop) 1390 if (!prop)
1390 return -ENOMEM; 1391 return -ENOMEM;
1391 dev->mode_config.edid_property = prop; 1392 dev->mode_config.edid_property = prop;
1392 1393
1393 prop = drm_property_create_enum(dev, 0, 1394 prop = drm_property_create_enum(dev, 0,
1394 "DPMS", drm_dpms_enum_list, 1395 "DPMS", drm_dpms_enum_list,
1395 ARRAY_SIZE(drm_dpms_enum_list)); 1396 ARRAY_SIZE(drm_dpms_enum_list));
1396 if (!prop) 1397 if (!prop)
1397 return -ENOMEM; 1398 return -ENOMEM;
1398 dev->mode_config.dpms_property = prop; 1399 dev->mode_config.dpms_property = prop;
1399 1400
1400 prop = drm_property_create(dev, 1401 prop = drm_property_create(dev,
1401 DRM_MODE_PROP_BLOB | 1402 DRM_MODE_PROP_BLOB |
1402 DRM_MODE_PROP_IMMUTABLE, 1403 DRM_MODE_PROP_IMMUTABLE,
1403 "PATH", 0); 1404 "PATH", 0);
1404 if (!prop) 1405 if (!prop)
1405 return -ENOMEM; 1406 return -ENOMEM;
1406 dev->mode_config.path_property = prop; 1407 dev->mode_config.path_property = prop;
1407 1408
1408 prop = drm_property_create(dev, 1409 prop = drm_property_create(dev,
1409 DRM_MODE_PROP_BLOB | 1410 DRM_MODE_PROP_BLOB |
1410 DRM_MODE_PROP_IMMUTABLE, 1411 DRM_MODE_PROP_IMMUTABLE,
1411 "TILE", 0); 1412 "TILE", 0);
1412 if (!prop) 1413 if (!prop)
1413 return -ENOMEM; 1414 return -ENOMEM;
1414 dev->mode_config.tile_property = prop; 1415 dev->mode_config.tile_property = prop;
1415 1416
1416 prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 1417 prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1417 "type", drm_plane_type_enum_list, 1418 "type", drm_plane_type_enum_list,
1418 ARRAY_SIZE(drm_plane_type_enum_list)); 1419 ARRAY_SIZE(drm_plane_type_enum_list));
1419 if (!prop) 1420 if (!prop)
1420 return -ENOMEM; 1421 return -ENOMEM;
1421 dev->mode_config.plane_type_property = prop; 1422 dev->mode_config.plane_type_property = prop;
1422 1423
1423 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 1424 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1424 "SRC_X", 0, UINT_MAX); 1425 "SRC_X", 0, UINT_MAX);
1425 if (!prop) 1426 if (!prop)
1426 return -ENOMEM; 1427 return -ENOMEM;
1427 dev->mode_config.prop_src_x = prop; 1428 dev->mode_config.prop_src_x = prop;
1428 1429
1429 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 1430 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1430 "SRC_Y", 0, UINT_MAX); 1431 "SRC_Y", 0, UINT_MAX);
1431 if (!prop) 1432 if (!prop)
1432 return -ENOMEM; 1433 return -ENOMEM;
1433 dev->mode_config.prop_src_y = prop; 1434 dev->mode_config.prop_src_y = prop;
1434 1435
1435 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 1436 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1436 "SRC_W", 0, UINT_MAX); 1437 "SRC_W", 0, UINT_MAX);
1437 if (!prop) 1438 if (!prop)
1438 return -ENOMEM; 1439 return -ENOMEM;
1439 dev->mode_config.prop_src_w = prop; 1440 dev->mode_config.prop_src_w = prop;
1440 1441
1441 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 1442 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1442 "SRC_H", 0, UINT_MAX); 1443 "SRC_H", 0, UINT_MAX);
1443 if (!prop) 1444 if (!prop)
1444 return -ENOMEM; 1445 return -ENOMEM;
1445 dev->mode_config.prop_src_h = prop; 1446 dev->mode_config.prop_src_h = prop;
1446 1447
1447 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC, 1448 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1448 "CRTC_X", INT_MIN, INT_MAX); 1449 "CRTC_X", INT_MIN, INT_MAX);
1449 if (!prop) 1450 if (!prop)
1450 return -ENOMEM; 1451 return -ENOMEM;
1451 dev->mode_config.prop_crtc_x = prop; 1452 dev->mode_config.prop_crtc_x = prop;
1452 1453
1453 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC, 1454 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1454 "CRTC_Y", INT_MIN, INT_MAX); 1455 "CRTC_Y", INT_MIN, INT_MAX);
1455 if (!prop) 1456 if (!prop)
1456 return -ENOMEM; 1457 return -ENOMEM;
1457 dev->mode_config.prop_crtc_y = prop; 1458 dev->mode_config.prop_crtc_y = prop;
1458 1459
1459 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 1460 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1460 "CRTC_W", 0, INT_MAX); 1461 "CRTC_W", 0, INT_MAX);
1461 if (!prop) 1462 if (!prop)
1462 return -ENOMEM; 1463 return -ENOMEM;
1463 dev->mode_config.prop_crtc_w = prop; 1464 dev->mode_config.prop_crtc_w = prop;
1464 1465
1465 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 1466 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1466 "CRTC_H", 0, INT_MAX); 1467 "CRTC_H", 0, INT_MAX);
1467 if (!prop) 1468 if (!prop)
1468 return -ENOMEM; 1469 return -ENOMEM;
1469 dev->mode_config.prop_crtc_h = prop; 1470 dev->mode_config.prop_crtc_h = prop;
1470 1471
1471 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC, 1472 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1472 "FB_ID", DRM_MODE_OBJECT_FB); 1473 "FB_ID", DRM_MODE_OBJECT_FB);
1473 if (!prop) 1474 if (!prop)
1474 return -ENOMEM; 1475 return -ENOMEM;
1475 dev->mode_config.prop_fb_id = prop; 1476 dev->mode_config.prop_fb_id = prop;
1476 1477
1477 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC, 1478 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1478 "CRTC_ID", DRM_MODE_OBJECT_CRTC); 1479 "CRTC_ID", DRM_MODE_OBJECT_CRTC);
1479 if (!prop) 1480 if (!prop)
1480 return -ENOMEM; 1481 return -ENOMEM;
1481 dev->mode_config.prop_crtc_id = prop; 1482 dev->mode_config.prop_crtc_id = prop;
1482 1483
1483 prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC, 1484 prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
1484 "ACTIVE"); 1485 "ACTIVE");
1485 if (!prop) 1486 if (!prop)
1486 return -ENOMEM; 1487 return -ENOMEM;
1487 dev->mode_config.prop_active = prop; 1488 dev->mode_config.prop_active = prop;
1488 1489
1489 prop = drm_property_create(dev, 1490 prop = drm_property_create(dev,
1490 DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB, 1491 DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
1491 "MODE_ID", 0); 1492 "MODE_ID", 0);
1492 if (!prop) 1493 if (!prop)
1493 return -ENOMEM; 1494 return -ENOMEM;
1494 dev->mode_config.prop_mode_id = prop; 1495 dev->mode_config.prop_mode_id = prop;
1495 1496
1496 return 0; 1497 return 0;
1497} 1498}
1498 1499
1499/** 1500/**
1500 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties 1501 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
1501 * @dev: DRM device 1502 * @dev: DRM device
1502 * 1503 *
1503 * Called by a driver the first time a DVI-I connector is made. 1504 * Called by a driver the first time a DVI-I connector is made.
1504 */ 1505 */
1505int drm_mode_create_dvi_i_properties(struct drm_device *dev) 1506int drm_mode_create_dvi_i_properties(struct drm_device *dev)
1506{ 1507{
1507 struct drm_property *dvi_i_selector; 1508 struct drm_property *dvi_i_selector;
1508 struct drm_property *dvi_i_subconnector; 1509 struct drm_property *dvi_i_subconnector;
1509 1510
1510 if (dev->mode_config.dvi_i_select_subconnector_property) 1511 if (dev->mode_config.dvi_i_select_subconnector_property)
1511 return 0; 1512 return 0;
1512 1513
1513 dvi_i_selector = 1514 dvi_i_selector =
1514 drm_property_create_enum(dev, 0, 1515 drm_property_create_enum(dev, 0,
1515 "select subconnector", 1516 "select subconnector",
1516 drm_dvi_i_select_enum_list, 1517 drm_dvi_i_select_enum_list,
1517 ARRAY_SIZE(drm_dvi_i_select_enum_list)); 1518 ARRAY_SIZE(drm_dvi_i_select_enum_list));
1518 dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; 1519 dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
1519 1520
1520 dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 1521 dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1521 "subconnector", 1522 "subconnector",
1522 drm_dvi_i_subconnector_enum_list, 1523 drm_dvi_i_subconnector_enum_list,
1523 ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); 1524 ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
1524 dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; 1525 dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
1525 1526
1526 return 0; 1527 return 0;
1527} 1528}
1528EXPORT_SYMBOL(drm_mode_create_dvi_i_properties); 1529EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
1529 1530
1530/** 1531/**
1531 * drm_create_tv_properties - create TV specific connector properties 1532 * drm_create_tv_properties - create TV specific connector properties
1532 * @dev: DRM device 1533 * @dev: DRM device
1533 * @num_modes: number of different TV formats (modes) supported 1534 * @num_modes: number of different TV formats (modes) supported
1534 * @modes: array of pointers to strings containing name of each format 1535 * @modes: array of pointers to strings containing name of each format
1535 * 1536 *
1536 * Called by a driver's TV initialization routine, this function creates 1537 * Called by a driver's TV initialization routine, this function creates
1537 * the TV specific connector properties for a given device. Caller is 1538 * the TV specific connector properties for a given device. Caller is
1538 * responsible for allocating a list of format names and passing them to 1539 * responsible for allocating a list of format names and passing them to
1539 * this routine. 1540 * this routine.
1540 */ 1541 */
1541int drm_mode_create_tv_properties(struct drm_device *dev, 1542int drm_mode_create_tv_properties(struct drm_device *dev,
1542 unsigned int num_modes, 1543 unsigned int num_modes,
1543 const char * const modes[]) 1544 const char * const modes[])
1544{ 1545{
1545 struct drm_property *tv_selector; 1546 struct drm_property *tv_selector;
1546 struct drm_property *tv_subconnector; 1547 struct drm_property *tv_subconnector;
1547 unsigned int i; 1548 unsigned int i;
1548 1549
1549 if (dev->mode_config.tv_select_subconnector_property) 1550 if (dev->mode_config.tv_select_subconnector_property)
1550 return 0; 1551 return 0;
1551 1552
1552 /* 1553 /*
1553 * Basic connector properties 1554 * Basic connector properties
1554 */ 1555 */
1555 tv_selector = drm_property_create_enum(dev, 0, 1556 tv_selector = drm_property_create_enum(dev, 0,
1556 "select subconnector", 1557 "select subconnector",
1557 drm_tv_select_enum_list, 1558 drm_tv_select_enum_list,
1558 ARRAY_SIZE(drm_tv_select_enum_list)); 1559 ARRAY_SIZE(drm_tv_select_enum_list));
1559 if (!tv_selector) 1560 if (!tv_selector)
1560 goto nomem; 1561 goto nomem;
1561 1562
1562 dev->mode_config.tv_select_subconnector_property = tv_selector; 1563 dev->mode_config.tv_select_subconnector_property = tv_selector;
1563 1564
1564 tv_subconnector = 1565 tv_subconnector =
1565 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 1566 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1566 "subconnector", 1567 "subconnector",
1567 drm_tv_subconnector_enum_list, 1568 drm_tv_subconnector_enum_list,
1568 ARRAY_SIZE(drm_tv_subconnector_enum_list)); 1569 ARRAY_SIZE(drm_tv_subconnector_enum_list));
1569 if (!tv_subconnector) 1570 if (!tv_subconnector)
1570 goto nomem; 1571 goto nomem;
1571 dev->mode_config.tv_subconnector_property = tv_subconnector; 1572 dev->mode_config.tv_subconnector_property = tv_subconnector;
1572 1573
1573 /* 1574 /*
1574 * Other, TV specific properties: margins & TV modes. 1575 * Other, TV specific properties: margins & TV modes.
1575 */ 1576 */
1576 dev->mode_config.tv_left_margin_property = 1577 dev->mode_config.tv_left_margin_property =
1577 drm_property_create_range(dev, 0, "left margin", 0, 100); 1578 drm_property_create_range(dev, 0, "left margin", 0, 100);
1578 if (!dev->mode_config.tv_left_margin_property) 1579 if (!dev->mode_config.tv_left_margin_property)
1579 goto nomem; 1580 goto nomem;
1580 1581
1581 dev->mode_config.tv_right_margin_property = 1582 dev->mode_config.tv_right_margin_property =
1582 drm_property_create_range(dev, 0, "right margin", 0, 100); 1583 drm_property_create_range(dev, 0, "right margin", 0, 100);
1583 if (!dev->mode_config.tv_right_margin_property) 1584 if (!dev->mode_config.tv_right_margin_property)
1584 goto nomem; 1585 goto nomem;
1585 1586
1586 dev->mode_config.tv_top_margin_property = 1587 dev->mode_config.tv_top_margin_property =
1587 drm_property_create_range(dev, 0, "top margin", 0, 100); 1588 drm_property_create_range(dev, 0, "top margin", 0, 100);
1588 if (!dev->mode_config.tv_top_margin_property) 1589 if (!dev->mode_config.tv_top_margin_property)
1589 goto nomem; 1590 goto nomem;
1590 1591
1591 dev->mode_config.tv_bottom_margin_property = 1592 dev->mode_config.tv_bottom_margin_property =
1592 drm_property_create_range(dev, 0, "bottom margin", 0, 100); 1593 drm_property_create_range(dev, 0, "bottom margin", 0, 100);
1593 if (!dev->mode_config.tv_bottom_margin_property) 1594 if (!dev->mode_config.tv_bottom_margin_property)
1594 goto nomem; 1595 goto nomem;
1595 1596
1596 dev->mode_config.tv_mode_property = 1597 dev->mode_config.tv_mode_property =
1597 drm_property_create(dev, DRM_MODE_PROP_ENUM, 1598 drm_property_create(dev, DRM_MODE_PROP_ENUM,
1598 "mode", num_modes); 1599 "mode", num_modes);
1599 if (!dev->mode_config.tv_mode_property) 1600 if (!dev->mode_config.tv_mode_property)
1600 goto nomem; 1601 goto nomem;
1601 1602
1602 for (i = 0; i < num_modes; i++) 1603 for (i = 0; i < num_modes; i++)
1603 drm_property_add_enum(dev->mode_config.tv_mode_property, i, 1604 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
1604 i, modes[i]); 1605 i, modes[i]);
1605 1606
1606 dev->mode_config.tv_brightness_property = 1607 dev->mode_config.tv_brightness_property =
1607 drm_property_create_range(dev, 0, "brightness", 0, 100); 1608 drm_property_create_range(dev, 0, "brightness", 0, 100);
1608 if (!dev->mode_config.tv_brightness_property) 1609 if (!dev->mode_config.tv_brightness_property)
1609 goto nomem; 1610 goto nomem;
1610 1611
1611 dev->mode_config.tv_contrast_property = 1612 dev->mode_config.tv_contrast_property =
1612 drm_property_create_range(dev, 0, "contrast", 0, 100); 1613 drm_property_create_range(dev, 0, "contrast", 0, 100);
1613 if (!dev->mode_config.tv_contrast_property) 1614 if (!dev->mode_config.tv_contrast_property)
1614 goto nomem; 1615 goto nomem;
1615 1616
1616 dev->mode_config.tv_flicker_reduction_property = 1617 dev->mode_config.tv_flicker_reduction_property =
1617 drm_property_create_range(dev, 0, "flicker reduction", 0, 100); 1618 drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
1618 if (!dev->mode_config.tv_flicker_reduction_property) 1619 if (!dev->mode_config.tv_flicker_reduction_property)
1619 goto nomem; 1620 goto nomem;
1620 1621
1621 dev->mode_config.tv_overscan_property = 1622 dev->mode_config.tv_overscan_property =
1622 drm_property_create_range(dev, 0, "overscan", 0, 100); 1623 drm_property_create_range(dev, 0, "overscan", 0, 100);
1623 if (!dev->mode_config.tv_overscan_property) 1624 if (!dev->mode_config.tv_overscan_property)
1624 goto nomem; 1625 goto nomem;
1625 1626
1626 dev->mode_config.tv_saturation_property = 1627 dev->mode_config.tv_saturation_property =
1627 drm_property_create_range(dev, 0, "saturation", 0, 100); 1628 drm_property_create_range(dev, 0, "saturation", 0, 100);
1628 if (!dev->mode_config.tv_saturation_property) 1629 if (!dev->mode_config.tv_saturation_property)
1629 goto nomem; 1630 goto nomem;
1630 1631
1631 dev->mode_config.tv_hue_property = 1632 dev->mode_config.tv_hue_property =
1632 drm_property_create_range(dev, 0, "hue", 0, 100); 1633 drm_property_create_range(dev, 0, "hue", 0, 100);
1633 if (!dev->mode_config.tv_hue_property) 1634 if (!dev->mode_config.tv_hue_property)
1634 goto nomem; 1635 goto nomem;
1635 1636
1636 return 0; 1637 return 0;
1637nomem: 1638nomem:
1638 return -ENOMEM; 1639 return -ENOMEM;
1639} 1640}
1640EXPORT_SYMBOL(drm_mode_create_tv_properties); 1641EXPORT_SYMBOL(drm_mode_create_tv_properties);
1641 1642
1642/** 1643/**
1643 * drm_mode_create_scaling_mode_property - create scaling mode property 1644 * drm_mode_create_scaling_mode_property - create scaling mode property
1644 * @dev: DRM device 1645 * @dev: DRM device
1645 * 1646 *
1646 * Called by a driver the first time it's needed, must be attached to desired 1647 * Called by a driver the first time it's needed, must be attached to desired
1647 * connectors. 1648 * connectors.
1648 */ 1649 */
1649int drm_mode_create_scaling_mode_property(struct drm_device *dev) 1650int drm_mode_create_scaling_mode_property(struct drm_device *dev)
1650{ 1651{
1651 struct drm_property *scaling_mode; 1652 struct drm_property *scaling_mode;
1652 1653
1653 if (dev->mode_config.scaling_mode_property) 1654 if (dev->mode_config.scaling_mode_property)
1654 return 0; 1655 return 0;
1655 1656
1656 scaling_mode = 1657 scaling_mode =
1657 drm_property_create_enum(dev, 0, "scaling mode", 1658 drm_property_create_enum(dev, 0, "scaling mode",
1658 drm_scaling_mode_enum_list, 1659 drm_scaling_mode_enum_list,
1659 ARRAY_SIZE(drm_scaling_mode_enum_list)); 1660 ARRAY_SIZE(drm_scaling_mode_enum_list));
1660 1661
1661 dev->mode_config.scaling_mode_property = scaling_mode; 1662 dev->mode_config.scaling_mode_property = scaling_mode;
1662 1663
1663 return 0; 1664 return 0;
1664} 1665}
1665EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); 1666EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
1666 1667
1667/** 1668/**
1668 * drm_mode_create_aspect_ratio_property - create aspect ratio property 1669 * drm_mode_create_aspect_ratio_property - create aspect ratio property
1669 * @dev: DRM device 1670 * @dev: DRM device
1670 * 1671 *
1671 * Called by a driver the first time it's needed, must be attached to desired 1672 * Called by a driver the first time it's needed, must be attached to desired
1672 * connectors. 1673 * connectors.
1673 * 1674 *
1674 * Returns: 1675 * Returns:
1675 * Zero on success, negative errno on failure. 1676 * Zero on success, negative errno on failure.
1676 */ 1677 */
1677int drm_mode_create_aspect_ratio_property(struct drm_device *dev) 1678int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
1678{ 1679{
1679 if (dev->mode_config.aspect_ratio_property) 1680 if (dev->mode_config.aspect_ratio_property)
1680 return 0; 1681 return 0;
1681 1682
1682 dev->mode_config.aspect_ratio_property = 1683 dev->mode_config.aspect_ratio_property =
1683 drm_property_create_enum(dev, 0, "aspect ratio", 1684 drm_property_create_enum(dev, 0, "aspect ratio",
1684 drm_aspect_ratio_enum_list, 1685 drm_aspect_ratio_enum_list,
1685 ARRAY_SIZE(drm_aspect_ratio_enum_list)); 1686 ARRAY_SIZE(drm_aspect_ratio_enum_list));
1686 1687
1687 if (dev->mode_config.aspect_ratio_property == NULL) 1688 if (dev->mode_config.aspect_ratio_property == NULL)
1688 return -ENOMEM; 1689 return -ENOMEM;
1689 1690
1690 return 0; 1691 return 0;
1691} 1692}
1692EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property); 1693EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
1693 1694
1694/** 1695/**
1695 * drm_mode_create_dirty_property - create dirty property 1696 * drm_mode_create_dirty_property - create dirty property
1696 * @dev: DRM device 1697 * @dev: DRM device
1697 * 1698 *
1698 * Called by a driver the first time it's needed, must be attached to desired 1699 * Called by a driver the first time it's needed, must be attached to desired
1699 * connectors. 1700 * connectors.
1700 */ 1701 */
1701int drm_mode_create_dirty_info_property(struct drm_device *dev) 1702int drm_mode_create_dirty_info_property(struct drm_device *dev)
1702{ 1703{
1703 struct drm_property *dirty_info; 1704 struct drm_property *dirty_info;
1704 1705
1705 if (dev->mode_config.dirty_info_property) 1706 if (dev->mode_config.dirty_info_property)
1706 return 0; 1707 return 0;
1707 1708
1708 dirty_info = 1709 dirty_info =
1709 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 1710 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1710 "dirty", 1711 "dirty",
1711 drm_dirty_info_enum_list, 1712 drm_dirty_info_enum_list,
1712 ARRAY_SIZE(drm_dirty_info_enum_list)); 1713 ARRAY_SIZE(drm_dirty_info_enum_list));
1713 dev->mode_config.dirty_info_property = dirty_info; 1714 dev->mode_config.dirty_info_property = dirty_info;
1714 1715
1715 return 0; 1716 return 0;
1716} 1717}
1717EXPORT_SYMBOL(drm_mode_create_dirty_info_property); 1718EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1718 1719
1719/** 1720/**
1720 * drm_mode_create_suggested_offset_properties - create suggests offset properties 1721 * drm_mode_create_suggested_offset_properties - create suggests offset properties
1721 * @dev: DRM device 1722 * @dev: DRM device
1722 * 1723 *
1723 * Create the the suggested x/y offset property for connectors. 1724 * Create the the suggested x/y offset property for connectors.
1724 */ 1725 */
1725int drm_mode_create_suggested_offset_properties(struct drm_device *dev) 1726int drm_mode_create_suggested_offset_properties(struct drm_device *dev)
1726{ 1727{
1727 if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property) 1728 if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property)
1728 return 0; 1729 return 0;
1729 1730
1730 dev->mode_config.suggested_x_property = 1731 dev->mode_config.suggested_x_property =
1731 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff); 1732 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff);
1732 1733
1733 dev->mode_config.suggested_y_property = 1734 dev->mode_config.suggested_y_property =
1734 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff); 1735 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff);
1735 1736
1736 if (dev->mode_config.suggested_x_property == NULL || 1737 if (dev->mode_config.suggested_x_property == NULL ||
1737 dev->mode_config.suggested_y_property == NULL) 1738 dev->mode_config.suggested_y_property == NULL)
1738 return -ENOMEM; 1739 return -ENOMEM;
1739 return 0; 1740 return 0;
1740} 1741}
1741EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties); 1742EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
1742 1743
1743/** 1744/**
1744 * drm_mode_getresources - get graphics configuration 1745 * drm_mode_getresources - get graphics configuration
1745 * @dev: drm device for the ioctl 1746 * @dev: drm device for the ioctl
1746 * @data: data pointer for the ioctl 1747 * @data: data pointer for the ioctl
1747 * @file_priv: drm file for the ioctl call 1748 * @file_priv: drm file for the ioctl call
1748 * 1749 *
1749 * Construct a set of configuration description structures and return 1750 * Construct a set of configuration description structures and return
1750 * them to the user, including CRTC, connector and framebuffer configuration. 1751 * them to the user, including CRTC, connector and framebuffer configuration.
1751 * 1752 *
1752 * Called by the user via ioctl. 1753 * Called by the user via ioctl.
1753 * 1754 *
1754 * Returns: 1755 * Returns:
1755 * Zero on success, negative errno on failure. 1756 * Zero on success, negative errno on failure.
1756 */ 1757 */
1757int drm_mode_getresources(struct drm_device *dev, void *data, 1758int drm_mode_getresources(struct drm_device *dev, void *data,
1758 struct drm_file *file_priv) 1759 struct drm_file *file_priv)
1759{ 1760{
1760 struct drm_mode_card_res *card_res = data; 1761 struct drm_mode_card_res *card_res = data;
1761 struct list_head *lh; 1762 struct list_head *lh;
1762 struct drm_framebuffer *fb; 1763 struct drm_framebuffer *fb;
1763 struct drm_connector *connector; 1764 struct drm_connector *connector;
1764 struct drm_crtc *crtc; 1765 struct drm_crtc *crtc;
1765 struct drm_encoder *encoder; 1766 struct drm_encoder *encoder;
1766 int ret = 0; 1767 int ret = 0;
1767 int connector_count = 0; 1768 int connector_count = 0;
1768 int crtc_count = 0; 1769 int crtc_count = 0;
1769 int fb_count = 0; 1770 int fb_count = 0;
1770 int encoder_count = 0; 1771 int encoder_count = 0;
1771 int copied = 0; 1772 int copied = 0;
1772 uint32_t __user *fb_id; 1773 uint32_t __user *fb_id;
1773 uint32_t __user *crtc_id; 1774 uint32_t __user *crtc_id;
1774 uint32_t __user *connector_id; 1775 uint32_t __user *connector_id;
1775 uint32_t __user *encoder_id; 1776 uint32_t __user *encoder_id;
1776 1777
1777 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1778 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1778 return -EINVAL; 1779 return -EINVAL;
1779 1780
1780 1781
1781 mutex_lock(&file_priv->fbs_lock); 1782 mutex_lock(&file_priv->fbs_lock);
1782 /* 1783 /*
1783 * For the non-control nodes we need to limit the list of resources 1784 * For the non-control nodes we need to limit the list of resources
1784 * by IDs in the group list for this node 1785 * by IDs in the group list for this node
1785 */ 1786 */
1786 list_for_each(lh, &file_priv->fbs) 1787 list_for_each(lh, &file_priv->fbs)
1787 fb_count++; 1788 fb_count++;
1788 1789
1789 /* handle this in 4 parts */ 1790 /* handle this in 4 parts */
1790 /* FBs */ 1791 /* FBs */
1791 if (card_res->count_fbs >= fb_count) { 1792 if (card_res->count_fbs >= fb_count) {
1792 copied = 0; 1793 copied = 0;
1793 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; 1794 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1794 list_for_each_entry(fb, &file_priv->fbs, filp_head) { 1795 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
1795 if (put_user(fb->base.id, fb_id + copied)) { 1796 if (put_user(fb->base.id, fb_id + copied)) {
1796 mutex_unlock(&file_priv->fbs_lock); 1797 mutex_unlock(&file_priv->fbs_lock);
1797 return -EFAULT; 1798 return -EFAULT;
1798 } 1799 }
1799 copied++; 1800 copied++;
1800 } 1801 }
1801 } 1802 }
1802 card_res->count_fbs = fb_count; 1803 card_res->count_fbs = fb_count;
1803 mutex_unlock(&file_priv->fbs_lock); 1804 mutex_unlock(&file_priv->fbs_lock);
1804 1805
1805 /* mode_config.mutex protects the connector list against e.g. DP MST 1806 /* mode_config.mutex protects the connector list against e.g. DP MST
1806 * connector hot-adding. CRTC/Plane lists are invariant. */ 1807 * connector hot-adding. CRTC/Plane lists are invariant. */
1807 mutex_lock(&dev->mode_config.mutex); 1808 mutex_lock(&dev->mode_config.mutex);
1808 drm_for_each_crtc(crtc, dev) 1809 drm_for_each_crtc(crtc, dev)
1809 crtc_count++; 1810 crtc_count++;
1810 1811
1811 drm_for_each_connector(connector, dev) 1812 drm_for_each_connector(connector, dev)
1812 connector_count++; 1813 connector_count++;
1813 1814
1814 drm_for_each_encoder(encoder, dev) 1815 drm_for_each_encoder(encoder, dev)
1815 encoder_count++; 1816 encoder_count++;
1816 1817
1817 card_res->max_height = dev->mode_config.max_height; 1818 card_res->max_height = dev->mode_config.max_height;
1818 card_res->min_height = dev->mode_config.min_height; 1819 card_res->min_height = dev->mode_config.min_height;
1819 card_res->max_width = dev->mode_config.max_width; 1820 card_res->max_width = dev->mode_config.max_width;
1820 card_res->min_width = dev->mode_config.min_width; 1821 card_res->min_width = dev->mode_config.min_width;
1821 1822
1822 /* CRTCs */ 1823 /* CRTCs */
1823 if (card_res->count_crtcs >= crtc_count) { 1824 if (card_res->count_crtcs >= crtc_count) {
1824 copied = 0; 1825 copied = 0;
1825 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; 1826 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1826 drm_for_each_crtc(crtc, dev) { 1827 drm_for_each_crtc(crtc, dev) {
1827 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); 1828 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1828 if (put_user(crtc->base.id, crtc_id + copied)) { 1829 if (put_user(crtc->base.id, crtc_id + copied)) {
1829 ret = -EFAULT; 1830 ret = -EFAULT;
1830 goto out; 1831 goto out;
1831 } 1832 }
1832 copied++; 1833 copied++;
1833 } 1834 }