aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c581
1 files changed, 400 insertions, 181 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e79c8d3700d8..5213da499d39 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -683,7 +683,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
683 drm_modeset_lock_init(&crtc->mutex); 683 drm_modeset_lock_init(&crtc->mutex);
684 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); 684 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
685 if (ret) 685 if (ret)
686 goto out; 686 return ret;
687 687
688 crtc->base.properties = &crtc->properties; 688 crtc->base.properties = &crtc->properties;
689 689
@@ -697,9 +697,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
697 if (cursor) 697 if (cursor)
698 cursor->possible_crtcs = 1 << drm_crtc_index(crtc); 698 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
699 699
700 out: 700 return 0;
701
702 return ret;
703} 701}
704EXPORT_SYMBOL(drm_crtc_init_with_planes); 702EXPORT_SYMBOL(drm_crtc_init_with_planes);
705 703
@@ -723,6 +721,12 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
723 drm_mode_object_put(dev, &crtc->base); 721 drm_mode_object_put(dev, &crtc->base);
724 list_del(&crtc->head); 722 list_del(&crtc->head);
725 dev->mode_config.num_crtc--; 723 dev->mode_config.num_crtc--;
724
725 WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
726 if (crtc->state && crtc->funcs->atomic_destroy_state)
727 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
728
729 memset(crtc, 0, sizeof(*crtc));
726} 730}
727EXPORT_SYMBOL(drm_crtc_cleanup); 731EXPORT_SYMBOL(drm_crtc_cleanup);
728 732
@@ -766,7 +770,6 @@ static void drm_mode_remove(struct drm_connector *connector,
766/** 770/**
767 * drm_connector_get_cmdline_mode - reads the user's cmdline mode 771 * drm_connector_get_cmdline_mode - reads the user's cmdline mode
768 * @connector: connector to quwery 772 * @connector: connector to quwery
769 * @mode: returned mode
770 * 773 *
771 * The kernel supports per-connector configration of its consoles through 774 * The kernel supports per-connector configration of its consoles through
772 * use of the video= parameter. This function parses that option and 775 * use of the video= parameter. This function parses that option and
@@ -870,6 +873,8 @@ int drm_connector_init(struct drm_device *dev,
870 873
871 drm_connector_get_cmdline_mode(connector); 874 drm_connector_get_cmdline_mode(connector);
872 875
876 /* We should add connectors at the end to avoid upsetting the connector
877 * index too much. */
873 list_add_tail(&connector->head, &dev->mode_config.connector_list); 878 list_add_tail(&connector->head, &dev->mode_config.connector_list);
874 dev->mode_config.num_connector++; 879 dev->mode_config.num_connector++;
875 880
@@ -905,6 +910,11 @@ void drm_connector_cleanup(struct drm_connector *connector)
905 struct drm_device *dev = connector->dev; 910 struct drm_device *dev = connector->dev;
906 struct drm_display_mode *mode, *t; 911 struct drm_display_mode *mode, *t;
907 912
913 if (connector->tile_group) {
914 drm_mode_put_tile_group(dev, connector->tile_group);
915 connector->tile_group = NULL;
916 }
917
908 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) 918 list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
909 drm_mode_remove(connector, mode); 919 drm_mode_remove(connector, mode);
910 920
@@ -919,6 +929,13 @@ void drm_connector_cleanup(struct drm_connector *connector)
919 connector->name = NULL; 929 connector->name = NULL;
920 list_del(&connector->head); 930 list_del(&connector->head);
921 dev->mode_config.num_connector--; 931 dev->mode_config.num_connector--;
932
933 WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);
934 if (connector->state && connector->funcs->atomic_destroy_state)
935 connector->funcs->atomic_destroy_state(connector,
936 connector->state);
937
938 memset(connector, 0, sizeof(*connector));
922} 939}
923EXPORT_SYMBOL(drm_connector_cleanup); 940EXPORT_SYMBOL(drm_connector_cleanup);
924 941
@@ -933,6 +950,9 @@ unsigned int drm_connector_index(struct drm_connector *connector)
933{ 950{
934 unsigned int index = 0; 951 unsigned int index = 0;
935 struct drm_connector *tmp; 952 struct drm_connector *tmp;
953 struct drm_mode_config *config = &connector->dev->mode_config;
954
955 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
936 956
937 list_for_each_entry(tmp, &connector->dev->mode_config.connector_list, head) { 957 list_for_each_entry(tmp, &connector->dev->mode_config.connector_list, head) {
938 if (tmp == connector) 958 if (tmp == connector)
@@ -1057,6 +1077,8 @@ void drm_bridge_cleanup(struct drm_bridge *bridge)
1057 list_del(&bridge->head); 1077 list_del(&bridge->head);
1058 dev->mode_config.num_bridge--; 1078 dev->mode_config.num_bridge--;
1059 drm_modeset_unlock_all(dev); 1079 drm_modeset_unlock_all(dev);
1080
1081 memset(bridge, 0, sizeof(*bridge));
1060} 1082}
1061EXPORT_SYMBOL(drm_bridge_cleanup); 1083EXPORT_SYMBOL(drm_bridge_cleanup);
1062 1084
@@ -1123,10 +1145,11 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
1123 drm_modeset_lock_all(dev); 1145 drm_modeset_lock_all(dev);
1124 drm_mode_object_put(dev, &encoder->base); 1146 drm_mode_object_put(dev, &encoder->base);
1125 kfree(encoder->name); 1147 kfree(encoder->name);
1126 encoder->name = NULL;
1127 list_del(&encoder->head); 1148 list_del(&encoder->head);
1128 dev->mode_config.num_encoder--; 1149 dev->mode_config.num_encoder--;
1129 drm_modeset_unlock_all(dev); 1150 drm_modeset_unlock_all(dev);
1151
1152 memset(encoder, 0, sizeof(*encoder));
1130} 1153}
1131EXPORT_SYMBOL(drm_encoder_cleanup); 1154EXPORT_SYMBOL(drm_encoder_cleanup);
1132 1155
@@ -1153,11 +1176,11 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1153{ 1176{
1154 int ret; 1177 int ret;
1155 1178
1156 drm_modeset_lock_all(dev);
1157
1158 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 1179 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
1159 if (ret) 1180 if (ret)
1160 goto out; 1181 return ret;
1182
1183 drm_modeset_lock_init(&plane->mutex);
1161 1184
1162 plane->base.properties = &plane->properties; 1185 plane->base.properties = &plane->properties;
1163 plane->dev = dev; 1186 plane->dev = dev;
@@ -1167,8 +1190,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1167 if (!plane->format_types) { 1190 if (!plane->format_types) {
1168 DRM_DEBUG_KMS("out of memory when allocating plane\n"); 1191 DRM_DEBUG_KMS("out of memory when allocating plane\n");
1169 drm_mode_object_put(dev, &plane->base); 1192 drm_mode_object_put(dev, &plane->base);
1170 ret = -ENOMEM; 1193 return -ENOMEM;
1171 goto out;
1172 } 1194 }
1173 1195
1174 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); 1196 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
@@ -1185,10 +1207,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1185 dev->mode_config.plane_type_property, 1207 dev->mode_config.plane_type_property,
1186 plane->type); 1208 plane->type);
1187 1209
1188 out: 1210 return 0;
1189 drm_modeset_unlock_all(dev);
1190
1191 return ret;
1192} 1211}
1193EXPORT_SYMBOL(drm_universal_plane_init); 1212EXPORT_SYMBOL(drm_universal_plane_init);
1194 1213
@@ -1246,6 +1265,12 @@ void drm_plane_cleanup(struct drm_plane *plane)
1246 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1265 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1247 dev->mode_config.num_overlay_plane--; 1266 dev->mode_config.num_overlay_plane--;
1248 drm_modeset_unlock_all(dev); 1267 drm_modeset_unlock_all(dev);
1268
1269 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
1270 if (plane->state && plane->funcs->atomic_destroy_state)
1271 plane->funcs->atomic_destroy_state(plane, plane->state);
1272
1273 memset(plane, 0, sizeof(*plane));
1249} 1274}
1250EXPORT_SYMBOL(drm_plane_cleanup); 1275EXPORT_SYMBOL(drm_plane_cleanup);
1251 1276
@@ -1328,6 +1353,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
1328 "PATH", 0); 1353 "PATH", 0);
1329 dev->mode_config.path_property = dev_path; 1354 dev->mode_config.path_property = dev_path;
1330 1355
1356 dev->mode_config.tile_property = drm_property_create(dev,
1357 DRM_MODE_PROP_BLOB |
1358 DRM_MODE_PROP_IMMUTABLE,
1359 "TILE", 0);
1360
1331 return 0; 1361 return 0;
1332} 1362}
1333 1363
@@ -1388,12 +1418,13 @@ EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
1388 * responsible for allocating a list of format names and passing them to 1418 * responsible for allocating a list of format names and passing them to
1389 * this routine. 1419 * this routine.
1390 */ 1420 */
1391int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, 1421int drm_mode_create_tv_properties(struct drm_device *dev,
1422 unsigned int num_modes,
1392 char *modes[]) 1423 char *modes[])
1393{ 1424{
1394 struct drm_property *tv_selector; 1425 struct drm_property *tv_selector;
1395 struct drm_property *tv_subconnector; 1426 struct drm_property *tv_subconnector;
1396 int i; 1427 unsigned int i;
1397 1428
1398 if (dev->mode_config.tv_select_subconnector_property) 1429 if (dev->mode_config.tv_select_subconnector_property)
1399 return 0; 1430 return 0;
@@ -1491,7 +1522,7 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
1491 * connectors. 1522 * connectors.
1492 * 1523 *
1493 * Returns: 1524 * Returns:
1494 * Zero on success, errno on failure. 1525 * Zero on success, negative errno on failure.
1495 */ 1526 */
1496int drm_mode_create_aspect_ratio_property(struct drm_device *dev) 1527int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
1497{ 1528{
@@ -1535,6 +1566,30 @@ int drm_mode_create_dirty_info_property(struct drm_device *dev)
1535} 1566}
1536EXPORT_SYMBOL(drm_mode_create_dirty_info_property); 1567EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1537 1568
1569/**
1570 * drm_mode_create_suggested_offset_properties - create suggests offset properties
1571 * @dev: DRM device
1572 *
1573 * Create the the suggested x/y offset property for connectors.
1574 */
1575int drm_mode_create_suggested_offset_properties(struct drm_device *dev)
1576{
1577 if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property)
1578 return 0;
1579
1580 dev->mode_config.suggested_x_property =
1581 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff);
1582
1583 dev->mode_config.suggested_y_property =
1584 drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff);
1585
1586 if (dev->mode_config.suggested_x_property == NULL ||
1587 dev->mode_config.suggested_y_property == NULL)
1588 return -ENOMEM;
1589 return 0;
1590}
1591EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
1592
1538static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) 1593static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
1539{ 1594{
1540 uint32_t total_objects = 0; 1595 uint32_t total_objects = 0;
@@ -1651,7 +1706,7 @@ static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
1651 * the caller. 1706 * the caller.
1652 * 1707 *
1653 * Returns: 1708 * Returns:
1654 * Zero on success, errno on failure. 1709 * Zero on success, negative errno on failure.
1655 */ 1710 */
1656static int drm_crtc_convert_umode(struct drm_display_mode *out, 1711static int drm_crtc_convert_umode(struct drm_display_mode *out,
1657 const struct drm_mode_modeinfo *in) 1712 const struct drm_mode_modeinfo *in)
@@ -1694,7 +1749,7 @@ static int drm_crtc_convert_umode(struct drm_display_mode *out,
1694 * Called by the user via ioctl. 1749 * Called by the user via ioctl.
1695 * 1750 *
1696 * Returns: 1751 * Returns:
1697 * Zero on success, errno on failure. 1752 * Zero on success, negative errno on failure.
1698 */ 1753 */
1699int drm_mode_getresources(struct drm_device *dev, void *data, 1754int drm_mode_getresources(struct drm_device *dev, void *data,
1700 struct drm_file *file_priv) 1755 struct drm_file *file_priv)
@@ -1745,7 +1800,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
1745 card_res->count_fbs = fb_count; 1800 card_res->count_fbs = fb_count;
1746 mutex_unlock(&file_priv->fbs_lock); 1801 mutex_unlock(&file_priv->fbs_lock);
1747 1802
1748 drm_modeset_lock_all(dev); 1803 /* mode_config.mutex protects the connector list against e.g. DP MST
1804 * connector hot-adding. CRTC/Plane lists are invariant. */
1805 mutex_lock(&dev->mode_config.mutex);
1749 if (!drm_is_primary_client(file_priv)) { 1806 if (!drm_is_primary_client(file_priv)) {
1750 1807
1751 mode_group = NULL; 1808 mode_group = NULL;
@@ -1865,7 +1922,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
1865 card_res->count_connectors, card_res->count_encoders); 1922 card_res->count_connectors, card_res->count_encoders);
1866 1923
1867out: 1924out:
1868 drm_modeset_unlock_all(dev); 1925 mutex_unlock(&dev->mode_config.mutex);
1869 return ret; 1926 return ret;
1870} 1927}
1871 1928
@@ -1880,26 +1937,22 @@ out:
1880 * Called by the user via ioctl. 1937 * Called by the user via ioctl.
1881 * 1938 *
1882 * Returns: 1939 * Returns:
1883 * Zero on success, errno on failure. 1940 * Zero on success, negative errno on failure.
1884 */ 1941 */
1885int drm_mode_getcrtc(struct drm_device *dev, 1942int drm_mode_getcrtc(struct drm_device *dev,
1886 void *data, struct drm_file *file_priv) 1943 void *data, struct drm_file *file_priv)
1887{ 1944{
1888 struct drm_mode_crtc *crtc_resp = data; 1945 struct drm_mode_crtc *crtc_resp = data;
1889 struct drm_crtc *crtc; 1946 struct drm_crtc *crtc;
1890 int ret = 0;
1891 1947
1892 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1948 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1893 return -EINVAL; 1949 return -EINVAL;
1894 1950
1895 drm_modeset_lock_all(dev);
1896
1897 crtc = drm_crtc_find(dev, crtc_resp->crtc_id); 1951 crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
1898 if (!crtc) { 1952 if (!crtc)
1899 ret = -ENOENT; 1953 return -ENOENT;
1900 goto out;
1901 }
1902 1954
1955 drm_modeset_lock_crtc(crtc, crtc->primary);
1903 crtc_resp->x = crtc->x; 1956 crtc_resp->x = crtc->x;
1904 crtc_resp->y = crtc->y; 1957 crtc_resp->y = crtc->y;
1905 crtc_resp->gamma_size = crtc->gamma_size; 1958 crtc_resp->gamma_size = crtc->gamma_size;
@@ -1916,10 +1969,9 @@ int drm_mode_getcrtc(struct drm_device *dev,
1916 } else { 1969 } else {
1917 crtc_resp->mode_valid = 0; 1970 crtc_resp->mode_valid = 0;
1918 } 1971 }
1972 drm_modeset_unlock_crtc(crtc);
1919 1973
1920out: 1974 return 0;
1921 drm_modeset_unlock_all(dev);
1922 return ret;
1923} 1975}
1924 1976
1925static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, 1977static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
@@ -1935,6 +1987,15 @@ static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
1935 return true; 1987 return true;
1936} 1988}
1937 1989
1990static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)
1991{
1992 /* For atomic drivers only state objects are synchronously updated and
1993 * protected by modeset locks, so check those first. */
1994 if (connector->state)
1995 return connector->state->best_encoder;
1996 return connector->encoder;
1997}
1998
1938/** 1999/**
1939 * drm_mode_getconnector - get connector configuration 2000 * drm_mode_getconnector - get connector configuration
1940 * @dev: drm device for the ioctl 2001 * @dev: drm device for the ioctl
@@ -1946,13 +2007,14 @@ static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
1946 * Called by the user via ioctl. 2007 * Called by the user via ioctl.
1947 * 2008 *
1948 * Returns: 2009 * Returns:
1949 * Zero on success, errno on failure. 2010 * Zero on success, negative errno on failure.
1950 */ 2011 */
1951int drm_mode_getconnector(struct drm_device *dev, void *data, 2012int drm_mode_getconnector(struct drm_device *dev, void *data,
1952 struct drm_file *file_priv) 2013 struct drm_file *file_priv)
1953{ 2014{
1954 struct drm_mode_get_connector *out_resp = data; 2015 struct drm_mode_get_connector *out_resp = data;
1955 struct drm_connector *connector; 2016 struct drm_connector *connector;
2017 struct drm_encoder *encoder;
1956 struct drm_display_mode *mode; 2018 struct drm_display_mode *mode;
1957 int mode_count = 0; 2019 int mode_count = 0;
1958 int props_count = 0; 2020 int props_count = 0;
@@ -2008,8 +2070,10 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2008 out_resp->subpixel = connector->display_info.subpixel_order; 2070 out_resp->subpixel = connector->display_info.subpixel_order;
2009 out_resp->connection = connector->status; 2071 out_resp->connection = connector->status;
2010 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 2072 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2011 if (connector->encoder) 2073
2012 out_resp->encoder_id = connector->encoder->base.id; 2074 encoder = drm_connector_get_encoder(connector);
2075 if (encoder)
2076 out_resp->encoder_id = encoder->base.id;
2013 else 2077 else
2014 out_resp->encoder_id = 0; 2078 out_resp->encoder_id = 0;
2015 drm_modeset_unlock(&dev->mode_config.connection_mutex); 2079 drm_modeset_unlock(&dev->mode_config.connection_mutex);
@@ -2079,6 +2143,33 @@ out:
2079 return ret; 2143 return ret;
2080} 2144}
2081 2145
2146static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
2147{
2148 struct drm_connector *connector;
2149 struct drm_device *dev = encoder->dev;
2150 bool uses_atomic = false;
2151
2152 /* For atomic drivers only state objects are synchronously updated and
2153 * protected by modeset locks, so check those first. */
2154 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2155 if (!connector->state)
2156 continue;
2157
2158 uses_atomic = true;
2159
2160 if (connector->state->best_encoder != encoder)
2161 continue;
2162
2163 return connector->state->crtc;
2164 }
2165
2166 /* Don't return stale data (e.g. pending async disable). */
2167 if (uses_atomic)
2168 return NULL;
2169
2170 return encoder->crtc;
2171}
2172
2082/** 2173/**
2083 * drm_mode_getencoder - get encoder configuration 2174 * drm_mode_getencoder - get encoder configuration
2084 * @dev: drm device for the ioctl 2175 * @dev: drm device for the ioctl
@@ -2090,37 +2181,38 @@ out:
2090 * Called by the user via ioctl. 2181 * Called by the user via ioctl.
2091 * 2182 *
2092 * Returns: 2183 * Returns:
2093 * Zero on success, errno on failure. 2184 * Zero on success, negative errno on failure.
2094 */ 2185 */
2095int drm_mode_getencoder(struct drm_device *dev, void *data, 2186int drm_mode_getencoder(struct drm_device *dev, void *data,
2096 struct drm_file *file_priv) 2187 struct drm_file *file_priv)
2097{ 2188{
2098 struct drm_mode_get_encoder *enc_resp = data; 2189 struct drm_mode_get_encoder *enc_resp = data;
2099 struct drm_encoder *encoder; 2190 struct drm_encoder *encoder;
2100 int ret = 0; 2191 struct drm_crtc *crtc;
2101 2192
2102 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2193 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2103 return -EINVAL; 2194 return -EINVAL;
2104 2195
2105 drm_modeset_lock_all(dev);
2106 encoder = drm_encoder_find(dev, enc_resp->encoder_id); 2196 encoder = drm_encoder_find(dev, enc_resp->encoder_id);
2107 if (!encoder) { 2197 if (!encoder)
2108 ret = -ENOENT; 2198 return -ENOENT;
2109 goto out;
2110 }
2111 2199
2112 if (encoder->crtc) 2200 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2201 crtc = drm_encoder_get_crtc(encoder);
2202 if (crtc)
2203 enc_resp->crtc_id = crtc->base.id;
2204 else if (encoder->crtc)
2113 enc_resp->crtc_id = encoder->crtc->base.id; 2205 enc_resp->crtc_id = encoder->crtc->base.id;
2114 else 2206 else
2115 enc_resp->crtc_id = 0; 2207 enc_resp->crtc_id = 0;
2208 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2209
2116 enc_resp->encoder_type = encoder->encoder_type; 2210 enc_resp->encoder_type = encoder->encoder_type;
2117 enc_resp->encoder_id = encoder->base.id; 2211 enc_resp->encoder_id = encoder->base.id;
2118 enc_resp->possible_crtcs = encoder->possible_crtcs; 2212 enc_resp->possible_crtcs = encoder->possible_crtcs;
2119 enc_resp->possible_clones = encoder->possible_clones; 2213 enc_resp->possible_clones = encoder->possible_clones;
2120 2214
2121out: 2215 return 0;
2122 drm_modeset_unlock_all(dev);
2123 return ret;
2124} 2216}
2125 2217
2126/** 2218/**
@@ -2134,7 +2226,7 @@ out:
2134 * Called by the user via ioctl. 2226 * Called by the user via ioctl.
2135 * 2227 *
2136 * Returns: 2228 * Returns:
2137 * Zero on success, errno on failure. 2229 * Zero on success, negative errno on failure.
2138 */ 2230 */
2139int drm_mode_getplane_res(struct drm_device *dev, void *data, 2231int drm_mode_getplane_res(struct drm_device *dev, void *data,
2140 struct drm_file *file_priv) 2232 struct drm_file *file_priv)
@@ -2143,13 +2235,12 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
2143 struct drm_mode_config *config; 2235 struct drm_mode_config *config;
2144 struct drm_plane *plane; 2236 struct drm_plane *plane;
2145 uint32_t __user *plane_ptr; 2237 uint32_t __user *plane_ptr;
2146 int copied = 0, ret = 0; 2238 int copied = 0;
2147 unsigned num_planes; 2239 unsigned num_planes;
2148 2240
2149 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2241 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2150 return -EINVAL; 2242 return -EINVAL;
2151 2243
2152 drm_modeset_lock_all(dev);
2153 config = &dev->mode_config; 2244 config = &dev->mode_config;
2154 2245
2155 if (file_priv->universal_planes) 2246 if (file_priv->universal_planes)
@@ -2165,6 +2256,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
2165 (plane_resp->count_planes >= num_planes)) { 2256 (plane_resp->count_planes >= num_planes)) {
2166 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; 2257 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
2167 2258
2259 /* Plane lists are invariant, no locking needed. */
2168 list_for_each_entry(plane, &config->plane_list, head) { 2260 list_for_each_entry(plane, &config->plane_list, head) {
2169 /* 2261 /*
2170 * Unless userspace set the 'universal planes' 2262 * Unless userspace set the 'universal planes'
@@ -2174,18 +2266,14 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
2174 !file_priv->universal_planes) 2266 !file_priv->universal_planes)
2175 continue; 2267 continue;
2176 2268
2177 if (put_user(plane->base.id, plane_ptr + copied)) { 2269 if (put_user(plane->base.id, plane_ptr + copied))
2178 ret = -EFAULT; 2270 return -EFAULT;
2179 goto out;
2180 }
2181 copied++; 2271 copied++;
2182 } 2272 }
2183 } 2273 }
2184 plane_resp->count_planes = num_planes; 2274 plane_resp->count_planes = num_planes;
2185 2275
2186out: 2276 return 0;
2187 drm_modeset_unlock_all(dev);
2188 return ret;
2189} 2277}
2190 2278
2191/** 2279/**
@@ -2199,7 +2287,7 @@ out:
2199 * Called by the user via ioctl. 2287 * Called by the user via ioctl.
2200 * 2288 *
2201 * Returns: 2289 * Returns:
2202 * Zero on success, errno on failure. 2290 * Zero on success, negative errno on failure.
2203 */ 2291 */
2204int drm_mode_getplane(struct drm_device *dev, void *data, 2292int drm_mode_getplane(struct drm_device *dev, void *data,
2205 struct drm_file *file_priv) 2293 struct drm_file *file_priv)
@@ -2207,18 +2295,15 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
2207 struct drm_mode_get_plane *plane_resp = data; 2295 struct drm_mode_get_plane *plane_resp = data;
2208 struct drm_plane *plane; 2296 struct drm_plane *plane;
2209 uint32_t __user *format_ptr; 2297 uint32_t __user *format_ptr;
2210 int ret = 0;
2211 2298
2212 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2299 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2213 return -EINVAL; 2300 return -EINVAL;
2214 2301
2215 drm_modeset_lock_all(dev);
2216 plane = drm_plane_find(dev, plane_resp->plane_id); 2302 plane = drm_plane_find(dev, plane_resp->plane_id);
2217 if (!plane) { 2303 if (!plane)
2218 ret = -ENOENT; 2304 return -ENOENT;
2219 goto out;
2220 }
2221 2305
2306 drm_modeset_lock(&plane->mutex, NULL);
2222 if (plane->crtc) 2307 if (plane->crtc)
2223 plane_resp->crtc_id = plane->crtc->base.id; 2308 plane_resp->crtc_id = plane->crtc->base.id;
2224 else 2309 else
@@ -2228,6 +2313,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
2228 plane_resp->fb_id = plane->fb->base.id; 2313 plane_resp->fb_id = plane->fb->base.id;
2229 else 2314 else
2230 plane_resp->fb_id = 0; 2315 plane_resp->fb_id = 0;
2316 drm_modeset_unlock(&plane->mutex);
2231 2317
2232 plane_resp->plane_id = plane->base.id; 2318 plane_resp->plane_id = plane->base.id;
2233 plane_resp->possible_crtcs = plane->possible_crtcs; 2319 plane_resp->possible_crtcs = plane->possible_crtcs;
@@ -2243,15 +2329,12 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
2243 if (copy_to_user(format_ptr, 2329 if (copy_to_user(format_ptr,
2244 plane->format_types, 2330 plane->format_types,
2245 sizeof(uint32_t) * plane->format_count)) { 2331 sizeof(uint32_t) * plane->format_count)) {
2246 ret = -EFAULT; 2332 return -EFAULT;
2247 goto out;
2248 } 2333 }
2249 } 2334 }
2250 plane_resp->count_format_types = plane->format_count; 2335 plane_resp->count_format_types = plane->format_count;
2251 2336
2252out: 2337 return 0;
2253 drm_modeset_unlock_all(dev);
2254 return ret;
2255} 2338}
2256 2339
2257/* 2340/*
@@ -2274,7 +2357,7 @@ static int __setplane_internal(struct drm_plane *plane,
2274{ 2357{
2275 int ret = 0; 2358 int ret = 0;
2276 unsigned int fb_width, fb_height; 2359 unsigned int fb_width, fb_height;
2277 int i; 2360 unsigned int i;
2278 2361
2279 /* No fb means shut it down */ 2362 /* No fb means shut it down */
2280 if (!fb) { 2363 if (!fb) {
@@ -2378,13 +2461,12 @@ static int setplane_internal(struct drm_plane *plane,
2378 * valid crtc). 2461 * valid crtc).
2379 * 2462 *
2380 * Returns: 2463 * Returns:
2381 * Zero on success, errno on failure. 2464 * Zero on success, negative errno on failure.
2382 */ 2465 */
2383int drm_mode_setplane(struct drm_device *dev, void *data, 2466int drm_mode_setplane(struct drm_device *dev, void *data,
2384 struct drm_file *file_priv) 2467 struct drm_file *file_priv)
2385{ 2468{
2386 struct drm_mode_set_plane *plane_req = data; 2469 struct drm_mode_set_plane *plane_req = data;
2387 struct drm_mode_object *obj;
2388 struct drm_plane *plane; 2470 struct drm_plane *plane;
2389 struct drm_crtc *crtc = NULL; 2471 struct drm_crtc *crtc = NULL;
2390 struct drm_framebuffer *fb = NULL; 2472 struct drm_framebuffer *fb = NULL;
@@ -2407,14 +2489,12 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
2407 * First, find the plane, crtc, and fb objects. If not available, 2489 * First, find the plane, crtc, and fb objects. If not available,
2408 * we don't bother to call the driver. 2490 * we don't bother to call the driver.
2409 */ 2491 */
2410 obj = drm_mode_object_find(dev, plane_req->plane_id, 2492 plane = drm_plane_find(dev, plane_req->plane_id);
2411 DRM_MODE_OBJECT_PLANE); 2493 if (!plane) {
2412 if (!obj) {
2413 DRM_DEBUG_KMS("Unknown plane ID %d\n", 2494 DRM_DEBUG_KMS("Unknown plane ID %d\n",
2414 plane_req->plane_id); 2495 plane_req->plane_id);
2415 return -ENOENT; 2496 return -ENOENT;
2416 } 2497 }
2417 plane = obj_to_plane(obj);
2418 2498
2419 if (plane_req->fb_id) { 2499 if (plane_req->fb_id) {
2420 fb = drm_framebuffer_lookup(dev, plane_req->fb_id); 2500 fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
@@ -2424,14 +2504,12 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
2424 return -ENOENT; 2504 return -ENOENT;
2425 } 2505 }
2426 2506
2427 obj = drm_mode_object_find(dev, plane_req->crtc_id, 2507 crtc = drm_crtc_find(dev, plane_req->crtc_id);
2428 DRM_MODE_OBJECT_CRTC); 2508 if (!crtc) {
2429 if (!obj) {
2430 DRM_DEBUG_KMS("Unknown crtc ID %d\n", 2509 DRM_DEBUG_KMS("Unknown crtc ID %d\n",
2431 plane_req->crtc_id); 2510 plane_req->crtc_id);
2432 return -ENOENT; 2511 return -ENOENT;
2433 } 2512 }
2434 crtc = obj_to_crtc(obj);
2435 } 2513 }
2436 2514
2437 /* 2515 /*
@@ -2453,7 +2531,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
2453 * interface. The only thing it adds is correct refcounting dance. 2531 * interface. The only thing it adds is correct refcounting dance.
2454 * 2532 *
2455 * Returns: 2533 * Returns:
2456 * Zero on success, errno on failure. 2534 * Zero on success, negative errno on failure.
2457 */ 2535 */
2458int drm_mode_set_config_internal(struct drm_mode_set *set) 2536int drm_mode_set_config_internal(struct drm_mode_set *set)
2459{ 2537{
@@ -2546,7 +2624,7 @@ EXPORT_SYMBOL(drm_crtc_check_viewport);
2546 * Called by the user via ioctl. 2624 * Called by the user via ioctl.
2547 * 2625 *
2548 * Returns: 2626 * Returns:
2549 * Zero on success, errno on failure. 2627 * Zero on success, negative errno on failure.
2550 */ 2628 */
2551int drm_mode_setcrtc(struct drm_device *dev, void *data, 2629int drm_mode_setcrtc(struct drm_device *dev, void *data,
2552 struct drm_file *file_priv) 2630 struct drm_file *file_priv)
@@ -2709,7 +2787,7 @@ out:
2709 * userspace wants to make use of these capabilities. 2787 * userspace wants to make use of these capabilities.
2710 * 2788 *
2711 * Returns: 2789 * Returns:
2712 * Zero on success, errno on failure. 2790 * Zero on success, negative errno on failure.
2713 */ 2791 */
2714static int drm_mode_cursor_universal(struct drm_crtc *crtc, 2792static int drm_mode_cursor_universal(struct drm_crtc *crtc,
2715 struct drm_mode_cursor2 *req, 2793 struct drm_mode_cursor2 *req,
@@ -2810,7 +2888,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
2810 * If this crtc has a universal cursor plane, call that plane's update 2888 * If this crtc has a universal cursor plane, call that plane's update
2811 * handler rather than using legacy cursor handlers. 2889 * handler rather than using legacy cursor handlers.
2812 */ 2890 */
2813 drm_modeset_lock_crtc(crtc); 2891 drm_modeset_lock_crtc(crtc, crtc->cursor);
2814 if (crtc->cursor) { 2892 if (crtc->cursor) {
2815 ret = drm_mode_cursor_universal(crtc, req, file_priv); 2893 ret = drm_mode_cursor_universal(crtc, req, file_priv);
2816 goto out; 2894 goto out;
@@ -2857,7 +2935,7 @@ out:
2857 * Called by the user via ioctl. 2935 * Called by the user via ioctl.
2858 * 2936 *
2859 * Returns: 2937 * Returns:
2860 * Zero on success, errno on failure. 2938 * Zero on success, negative errno on failure.
2861 */ 2939 */
2862int drm_mode_cursor_ioctl(struct drm_device *dev, 2940int drm_mode_cursor_ioctl(struct drm_device *dev,
2863 void *data, struct drm_file *file_priv) 2941 void *data, struct drm_file *file_priv)
@@ -2884,7 +2962,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
2884 * Called by the user via ioctl. 2962 * Called by the user via ioctl.
2885 * 2963 *
2886 * Returns: 2964 * Returns:
2887 * Zero on success, errno on failure. 2965 * Zero on success, negative errno on failure.
2888 */ 2966 */
2889int drm_mode_cursor2_ioctl(struct drm_device *dev, 2967int drm_mode_cursor2_ioctl(struct drm_device *dev,
2890 void *data, struct drm_file *file_priv) 2968 void *data, struct drm_file *file_priv)
@@ -2943,23 +3021,21 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format);
2943 * @file_priv: drm file for the ioctl call 3021 * @file_priv: drm file for the ioctl call
2944 * 3022 *
2945 * Add a new FB to the specified CRTC, given a user request. This is the 3023 * Add a new FB to the specified CRTC, given a user request. This is the
2946 * original addfb ioclt which only supported RGB formats. 3024 * original addfb ioctl which only supported RGB formats.
2947 * 3025 *
2948 * Called by the user via ioctl. 3026 * Called by the user via ioctl.
2949 * 3027 *
2950 * Returns: 3028 * Returns:
2951 * Zero on success, errno on failure. 3029 * Zero on success, negative errno on failure.
2952 */ 3030 */
2953int drm_mode_addfb(struct drm_device *dev, 3031int drm_mode_addfb(struct drm_device *dev,
2954 void *data, struct drm_file *file_priv) 3032 void *data, struct drm_file *file_priv)
2955{ 3033{
2956 struct drm_mode_fb_cmd *or = data; 3034 struct drm_mode_fb_cmd *or = data;
2957 struct drm_mode_fb_cmd2 r = {}; 3035 struct drm_mode_fb_cmd2 r = {};
2958 struct drm_mode_config *config = &dev->mode_config; 3036 int ret;
2959 struct drm_framebuffer *fb;
2960 int ret = 0;
2961 3037
2962 /* Use new struct with format internally */ 3038 /* convert to new format and call new ioctl */
2963 r.fb_id = or->fb_id; 3039 r.fb_id = or->fb_id;
2964 r.width = or->width; 3040 r.width = or->width;
2965 r.height = or->height; 3041 r.height = or->height;
@@ -2967,28 +3043,13 @@ int drm_mode_addfb(struct drm_device *dev,
2967 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); 3043 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
2968 r.handles[0] = or->handle; 3044 r.handles[0] = or->handle;
2969 3045
2970 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 3046 ret = drm_mode_addfb2(dev, &r, file_priv);
2971 return -EINVAL; 3047 if (ret)
2972 3048 return ret;
2973 if ((config->min_width > r.width) || (r.width > config->max_width))
2974 return -EINVAL;
2975
2976 if ((config->min_height > r.height) || (r.height > config->max_height))
2977 return -EINVAL;
2978 3049
2979 fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); 3050 or->fb_id = r.fb_id;
2980 if (IS_ERR(fb)) {
2981 DRM_DEBUG_KMS("could not create framebuffer\n");
2982 return PTR_ERR(fb);
2983 }
2984 3051
2985 mutex_lock(&file_priv->fbs_lock); 3052 return 0;
2986 or->fb_id = fb->base.id;
2987 list_add(&fb->filp_head, &file_priv->fbs);
2988 DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
2989 mutex_unlock(&file_priv->fbs_lock);
2990
2991 return ret;
2992} 3053}
2993 3054
2994static int format_check(const struct drm_mode_fb_cmd2 *r) 3055static int format_check(const struct drm_mode_fb_cmd2 *r)
@@ -3080,7 +3141,7 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
3080 num_planes = drm_format_num_planes(r->pixel_format); 3141 num_planes = drm_format_num_planes(r->pixel_format);
3081 3142
3082 if (r->width == 0 || r->width % hsub) { 3143 if (r->width == 0 || r->width % hsub) {
3083 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height); 3144 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
3084 return -EINVAL; 3145 return -EINVAL;
3085 } 3146 }
3086 3147
@@ -3170,7 +3231,7 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
3170 * Called by the user via ioctl. 3231 * Called by the user via ioctl.
3171 * 3232 *
3172 * Returns: 3233 * Returns:
3173 * Zero on success, errno on failure. 3234 * Zero on success, negative errno on failure.
3174 */ 3235 */
3175int drm_mode_addfb2(struct drm_device *dev, 3236int drm_mode_addfb2(struct drm_device *dev,
3176 void *data, struct drm_file *file_priv) 3237 void *data, struct drm_file *file_priv)
@@ -3198,7 +3259,7 @@ int drm_mode_addfb2(struct drm_device *dev,
3198 * Called by the user via ioctl. 3259 * Called by the user via ioctl.
3199 * 3260 *
3200 * Returns: 3261 * Returns:
3201 * Zero on success, errno on failure. 3262 * Zero on success, negative errno on failure.
3202 */ 3263 */
3203int drm_mode_rmfb(struct drm_device *dev, 3264int drm_mode_rmfb(struct drm_device *dev,
3204 void *data, struct drm_file *file_priv) 3265 void *data, struct drm_file *file_priv)
@@ -3252,7 +3313,7 @@ fail_lookup:
3252 * Called by the user via ioctl. 3313 * Called by the user via ioctl.
3253 * 3314 *
3254 * Returns: 3315 * Returns:
3255 * Zero on success, errno on failure. 3316 * Zero on success, negative errno on failure.
3256 */ 3317 */
3257int drm_mode_getfb(struct drm_device *dev, 3318int drm_mode_getfb(struct drm_device *dev,
3258 void *data, struct drm_file *file_priv) 3319 void *data, struct drm_file *file_priv)
@@ -3313,7 +3374,7 @@ int drm_mode_getfb(struct drm_device *dev,
3313 * Called by the user via ioctl. 3374 * Called by the user via ioctl.
3314 * 3375 *
3315 * Returns: 3376 * Returns:
3316 * Zero on success, errno on failure. 3377 * Zero on success, negative errno on failure.
3317 */ 3378 */
3318int drm_mode_dirtyfb_ioctl(struct drm_device *dev, 3379int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
3319 void *data, struct drm_file *file_priv) 3380 void *data, struct drm_file *file_priv)
@@ -3393,7 +3454,7 @@ out_err1:
3393 * Called by the user via ioctl. 3454 * Called by the user via ioctl.
3394 * 3455 *
3395 * Returns: 3456 * Returns:
3396 * Zero on success, errno on failure. 3457 * Zero on success, negative errno on failure.
3397 */ 3458 */
3398void drm_fb_release(struct drm_file *priv) 3459void drm_fb_release(struct drm_file *priv)
3399{ 3460{
@@ -3402,7 +3463,7 @@ void drm_fb_release(struct drm_file *priv)
3402 3463
3403 /* 3464 /*
3404 * When the file gets released that means no one else can access the fb 3465 * When the file gets released that means no one else can access the fb
3405 * list any more, so no need to grab fpriv->fbs_lock. And we need to to 3466 * list any more, so no need to grab fpriv->fbs_lock. And we need to
3406 * avoid upsetting lockdep since the universal cursor code adds a 3467 * avoid upsetting lockdep since the universal cursor code adds a
3407 * framebuffer while holding mutex locks. 3468 * framebuffer while holding mutex locks.
3408 * 3469 *
@@ -3435,6 +3496,10 @@ void drm_fb_release(struct drm_file *priv)
3435 * object with drm_object_attach_property. The returned property object must be 3496 * object with drm_object_attach_property. The returned property object must be
3436 * freed with drm_property_destroy. 3497 * freed with drm_property_destroy.
3437 * 3498 *
3499 * Note that the DRM core keeps a per-device list of properties and that, if
3500 * drm_mode_config_cleanup() is called, it will destroy all properties created
3501 * by the driver.
3502 *
3438 * Returns: 3503 * Returns:
3439 * A pointer to the newly created property on success, NULL on failure. 3504 * A pointer to the newly created property on success, NULL on failure.
3440 */ 3505 */
@@ -3462,7 +3527,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
3462 3527
3463 property->flags = flags; 3528 property->flags = flags;
3464 property->num_values = num_values; 3529 property->num_values = num_values;
3465 INIT_LIST_HEAD(&property->enum_blob_list); 3530 INIT_LIST_HEAD(&property->enum_list);
3466 3531
3467 if (name) { 3532 if (name) {
3468 strncpy(property->name, name, DRM_PROP_NAME_LEN); 3533 strncpy(property->name, name, DRM_PROP_NAME_LEN);
@@ -3611,7 +3676,7 @@ static struct drm_property *property_create_range(struct drm_device *dev,
3611 * object with drm_object_attach_property. The returned property object must be 3676 * object with drm_object_attach_property. The returned property object must be
3612 * freed with drm_property_destroy. 3677 * freed with drm_property_destroy.
3613 * 3678 *
3614 * Userspace is allowed to set any interger value in the (min, max) range 3679 * Userspace is allowed to set any integer value in the (min, max) range
3615 * inclusive. 3680 * inclusive.
3616 * 3681 *
3617 * Returns: 3682 * Returns:
@@ -3684,8 +3749,8 @@ int drm_property_add_enum(struct drm_property *property, int index,
3684 (value > 63)) 3749 (value > 63))
3685 return -EINVAL; 3750 return -EINVAL;
3686 3751
3687 if (!list_empty(&property->enum_blob_list)) { 3752 if (!list_empty(&property->enum_list)) {
3688 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 3753 list_for_each_entry(prop_enum, &property->enum_list, head) {
3689 if (prop_enum->value == value) { 3754 if (prop_enum->value == value) {
3690 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 3755 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
3691 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 3756 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
@@ -3703,7 +3768,7 @@ int drm_property_add_enum(struct drm_property *property, int index,
3703 prop_enum->value = value; 3768 prop_enum->value = value;
3704 3769
3705 property->values[index] = value; 3770 property->values[index] = value;
3706 list_add_tail(&prop_enum->head, &property->enum_blob_list); 3771 list_add_tail(&prop_enum->head, &property->enum_list);
3707 return 0; 3772 return 0;
3708} 3773}
3709EXPORT_SYMBOL(drm_property_add_enum); 3774EXPORT_SYMBOL(drm_property_add_enum);
@@ -3720,7 +3785,7 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
3720{ 3785{
3721 struct drm_property_enum *prop_enum, *pt; 3786 struct drm_property_enum *prop_enum, *pt;
3722 3787
3723 list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) { 3788 list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) {
3724 list_del(&prop_enum->head); 3789 list_del(&prop_enum->head);
3725 kfree(prop_enum); 3790 kfree(prop_enum);
3726 } 3791 }
@@ -3823,17 +3888,20 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
3823EXPORT_SYMBOL(drm_object_property_get_value); 3888EXPORT_SYMBOL(drm_object_property_get_value);
3824 3889
3825/** 3890/**
3826 * drm_mode_getproperty_ioctl - get the current value of a connector's property 3891 * drm_mode_getproperty_ioctl - get the property metadata
3827 * @dev: DRM device 3892 * @dev: DRM device
3828 * @data: ioctl data 3893 * @data: ioctl data
3829 * @file_priv: DRM file info 3894 * @file_priv: DRM file info
3830 * 3895 *
3831 * This function retrieves the current value for an connectors's property. 3896 * This function retrieves the metadata for a given property, like the different
3897 * possible values for an enum property or the limits for a range property.
3898 *
3899 * Blob properties are special
3832 * 3900 *
3833 * Called by the user via ioctl. 3901 * Called by the user via ioctl.
3834 * 3902 *
3835 * Returns: 3903 * Returns:
3836 * Zero on success, errno on failure. 3904 * Zero on success, negative errno on failure.
3837 */ 3905 */
3838int drm_mode_getproperty_ioctl(struct drm_device *dev, 3906int drm_mode_getproperty_ioctl(struct drm_device *dev,
3839 void *data, struct drm_file *file_priv) 3907 void *data, struct drm_file *file_priv)
@@ -3841,16 +3909,12 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
3841 struct drm_mode_get_property *out_resp = data; 3909 struct drm_mode_get_property *out_resp = data;
3842 struct drm_property *property; 3910 struct drm_property *property;
3843 int enum_count = 0; 3911 int enum_count = 0;
3844 int blob_count = 0;
3845 int value_count = 0; 3912 int value_count = 0;
3846 int ret = 0, i; 3913 int ret = 0, i;
3847 int copied; 3914 int copied;
3848 struct drm_property_enum *prop_enum; 3915 struct drm_property_enum *prop_enum;
3849 struct drm_mode_property_enum __user *enum_ptr; 3916 struct drm_mode_property_enum __user *enum_ptr;
3850 struct drm_property_blob *prop_blob;
3851 uint32_t __user *blob_id_ptr;
3852 uint64_t __user *values_ptr; 3917 uint64_t __user *values_ptr;
3853 uint32_t __user *blob_length_ptr;
3854 3918
3855 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 3919 if (!drm_core_check_feature(dev, DRIVER_MODESET))
3856 return -EINVAL; 3920 return -EINVAL;
@@ -3864,11 +3928,8 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
3864 3928
3865 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) || 3929 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3866 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) { 3930 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
3867 list_for_each_entry(prop_enum, &property->enum_blob_list, head) 3931 list_for_each_entry(prop_enum, &property->enum_list, head)
3868 enum_count++; 3932 enum_count++;
3869 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
3870 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
3871 blob_count++;
3872 } 3933 }
3873 3934
3874 value_count = property->num_values; 3935 value_count = property->num_values;
@@ -3893,7 +3954,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
3893 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { 3954 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
3894 copied = 0; 3955 copied = 0;
3895 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; 3956 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
3896 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 3957 list_for_each_entry(prop_enum, &property->enum_list, head) {
3897 3958
3898 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) { 3959 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
3899 ret = -EFAULT; 3960 ret = -EFAULT;
@@ -3911,35 +3972,24 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
3911 out_resp->count_enum_blobs = enum_count; 3972 out_resp->count_enum_blobs = enum_count;
3912 } 3973 }
3913 3974
3914 if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) { 3975 /*
3915 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) { 3976 * NOTE: The idea seems to have been to use this to read all the blob
3916 copied = 0; 3977 * property values. But nothing ever added them to the corresponding
3917 blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr; 3978 * list, userspace always used the special-purpose get_blob ioctl to
3918 blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr; 3979 * read the value for a blob property. It also doesn't make a lot of
3919 3980 * sense to return values here when everything else is just metadata for
3920 list_for_each_entry(prop_blob, &property->enum_blob_list, head) { 3981 * the property itself.
3921 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) { 3982 */
3922 ret = -EFAULT; 3983 if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
3923 goto done; 3984 out_resp->count_enum_blobs = 0;
3924 }
3925
3926 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
3927 ret = -EFAULT;
3928 goto done;
3929 }
3930
3931 copied++;
3932 }
3933 }
3934 out_resp->count_enum_blobs = blob_count;
3935 }
3936done: 3985done:
3937 drm_modeset_unlock_all(dev); 3986 drm_modeset_unlock_all(dev);
3938 return ret; 3987 return ret;
3939} 3988}
3940 3989
3941static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length, 3990static struct drm_property_blob *
3942 void *data) 3991drm_property_create_blob(struct drm_device *dev, size_t length,
3992 const void *data)
3943{ 3993{
3944 struct drm_property_blob *blob; 3994 struct drm_property_blob *blob;
3945 int ret; 3995 int ret;
@@ -3985,7 +4035,7 @@ static void drm_property_destroy_blob(struct drm_device *dev,
3985 * Called by the user via ioctl. 4035 * Called by the user via ioctl.
3986 * 4036 *
3987 * Returns: 4037 * Returns:
3988 * Zero on success, errno on failure. 4038 * Zero on success, negative errno on failure.
3989 */ 4039 */
3990int drm_mode_getblob_ioctl(struct drm_device *dev, 4040int drm_mode_getblob_ioctl(struct drm_device *dev,
3991 void *data, struct drm_file *file_priv) 4041 void *data, struct drm_file *file_priv)
@@ -4019,12 +4069,25 @@ done:
4019 return ret; 4069 return ret;
4020} 4070}
4021 4071
4072/**
4073 * drm_mode_connector_set_path_property - set tile property on connector
4074 * @connector: connector to set property on.
4075 * @path: path to use for property.
4076 *
4077 * This creates a property to expose to userspace to specify a
4078 * connector path. This is mainly used for DisplayPort MST where
4079 * connectors have a topology and we want to allow userspace to give
4080 * them more meaningful names.
4081 *
4082 * Returns:
4083 * Zero on success, negative errno on failure.
4084 */
4022int drm_mode_connector_set_path_property(struct drm_connector *connector, 4085int drm_mode_connector_set_path_property(struct drm_connector *connector,
4023 char *path) 4086 const char *path)
4024{ 4087{
4025 struct drm_device *dev = connector->dev; 4088 struct drm_device *dev = connector->dev;
4026 int ret, size; 4089 size_t size = strlen(path) + 1;
4027 size = strlen(path) + 1; 4090 int ret;
4028 4091
4029 connector->path_blob_ptr = drm_property_create_blob(connector->dev, 4092 connector->path_blob_ptr = drm_property_create_blob(connector->dev,
4030 size, path); 4093 size, path);
@@ -4039,6 +4102,52 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector,
4039EXPORT_SYMBOL(drm_mode_connector_set_path_property); 4102EXPORT_SYMBOL(drm_mode_connector_set_path_property);
4040 4103
4041/** 4104/**
4105 * drm_mode_connector_set_tile_property - set tile property on connector
4106 * @connector: connector to set property on.
4107 *
4108 * This looks up the tile information for a connector, and creates a
4109 * property for userspace to parse if it exists. The property is of
4110 * the form of 8 integers using ':' as a separator.
4111 *
4112 * Returns:
4113 * Zero on success, errno on failure.
4114 */
4115int drm_mode_connector_set_tile_property(struct drm_connector *connector)
4116{
4117 struct drm_device *dev = connector->dev;
4118 int ret, size;
4119 char tile[256];
4120
4121 if (connector->tile_blob_ptr)
4122 drm_property_destroy_blob(dev, connector->tile_blob_ptr);
4123
4124 if (!connector->has_tile) {
4125 connector->tile_blob_ptr = NULL;
4126 ret = drm_object_property_set_value(&connector->base,
4127 dev->mode_config.tile_property, 0);
4128 return ret;
4129 }
4130
4131 snprintf(tile, 256, "%d:%d:%d:%d:%d:%d:%d:%d",
4132 connector->tile_group->id, connector->tile_is_single_monitor,
4133 connector->num_h_tile, connector->num_v_tile,
4134 connector->tile_h_loc, connector->tile_v_loc,
4135 connector->tile_h_size, connector->tile_v_size);
4136 size = strlen(tile) + 1;
4137
4138 connector->tile_blob_ptr = drm_property_create_blob(connector->dev,
4139 size, tile);
4140 if (!connector->tile_blob_ptr)
4141 return -EINVAL;
4142
4143 ret = drm_object_property_set_value(&connector->base,
4144 dev->mode_config.tile_property,
4145 connector->tile_blob_ptr->base.id);
4146 return ret;
4147}
4148EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
4149
4150/**
4042 * drm_mode_connector_update_edid_property - update the edid property of a connector 4151 * drm_mode_connector_update_edid_property - update the edid property of a connector
4043 * @connector: drm connector 4152 * @connector: drm connector
4044 * @edid: new value of the edid property 4153 * @edid: new value of the edid property
@@ -4047,13 +4156,14 @@ EXPORT_SYMBOL(drm_mode_connector_set_path_property);
4047 * connector's edid property. 4156 * connector's edid property.
4048 * 4157 *
4049 * Returns: 4158 * Returns:
4050 * Zero on success, errno on failure. 4159 * Zero on success, negative errno on failure.
4051 */ 4160 */
4052int drm_mode_connector_update_edid_property(struct drm_connector *connector, 4161int drm_mode_connector_update_edid_property(struct drm_connector *connector,
4053 struct edid *edid) 4162 const struct edid *edid)
4054{ 4163{
4055 struct drm_device *dev = connector->dev; 4164 struct drm_device *dev = connector->dev;
4056 int ret, size; 4165 size_t size;
4166 int ret;
4057 4167
4058 /* ignore requests to set edid when overridden */ 4168 /* ignore requests to set edid when overridden */
4059 if (connector->override_edid) 4169 if (connector->override_edid)
@@ -4143,7 +4253,7 @@ static bool drm_property_change_is_valid(struct drm_property *property,
4143 * Called by the user via ioctl. 4253 * Called by the user via ioctl.
4144 * 4254 *
4145 * Returns: 4255 * Returns:
4146 * Zero on success, errno on failure. 4256 * Zero on success, negative errno on failure.
4147 */ 4257 */
4148int drm_mode_connector_property_set_ioctl(struct drm_device *dev, 4258int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
4149 void *data, struct drm_file *file_priv) 4259 void *data, struct drm_file *file_priv)
@@ -4226,7 +4336,7 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
4226EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); 4336EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
4227 4337
4228/** 4338/**
4229 * drm_mode_getproperty_ioctl - get the current value of a object's property 4339 * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
4230 * @dev: DRM device 4340 * @dev: DRM device
4231 * @data: ioctl data 4341 * @data: ioctl data
4232 * @file_priv: DRM file info 4342 * @file_priv: DRM file info
@@ -4238,7 +4348,7 @@ EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
4238 * Called by the user via ioctl. 4348 * Called by the user via ioctl.
4239 * 4349 *
4240 * Returns: 4350 * Returns:
4241 * Zero on success, errno on failure. 4351 * Zero on success, negative errno on failure.
4242 */ 4352 */
4243int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, 4353int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4244 struct drm_file *file_priv) 4354 struct drm_file *file_priv)
@@ -4310,7 +4420,7 @@ out:
4310 * Called by the user via ioctl. 4420 * Called by the user via ioctl.
4311 * 4421 *
4312 * Returns: 4422 * Returns:
4313 * Zero on success, errno on failure. 4423 * Zero on success, negative errno on failure.
4314 */ 4424 */
4315int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, 4425int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4316 struct drm_file *file_priv) 4426 struct drm_file *file_priv)
@@ -4382,7 +4492,7 @@ out:
4382 * possible_clones and possible_crtcs bitmasks. 4492 * possible_clones and possible_crtcs bitmasks.
4383 * 4493 *
4384 * Returns: 4494 * Returns:
4385 * Zero on success, errno on failure. 4495 * Zero on success, negative errno on failure.
4386 */ 4496 */
4387int drm_mode_connector_attach_encoder(struct drm_connector *connector, 4497int drm_mode_connector_attach_encoder(struct drm_connector *connector,
4388 struct drm_encoder *encoder) 4498 struct drm_encoder *encoder)
@@ -4409,7 +4519,7 @@ EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
4409 * fixed gamma table size. 4519 * fixed gamma table size.
4410 * 4520 *
4411 * Returns: 4521 * Returns:
4412 * Zero on success, errno on failure. 4522 * Zero on success, negative errno on failure.
4413 */ 4523 */
4414int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, 4524int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
4415 int gamma_size) 4525 int gamma_size)
@@ -4438,7 +4548,7 @@ EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
4438 * Called by the user via ioctl. 4548 * Called by the user via ioctl.
4439 * 4549 *
4440 * Returns: 4550 * Returns:
4441 * Zero on success, errno on failure. 4551 * Zero on success, negative errno on failure.
4442 */ 4552 */
4443int drm_mode_gamma_set_ioctl(struct drm_device *dev, 4553int drm_mode_gamma_set_ioctl(struct drm_device *dev,
4444 void *data, struct drm_file *file_priv) 4554 void *data, struct drm_file *file_priv)
@@ -4510,7 +4620,7 @@ out:
4510 * Called by the user via ioctl. 4620 * Called by the user via ioctl.
4511 * 4621 *
4512 * Returns: 4622 * Returns:
4513 * Zero on success, errno on failure. 4623 * Zero on success, negative errno on failure.
4514 */ 4624 */
4515int drm_mode_gamma_get_ioctl(struct drm_device *dev, 4625int drm_mode_gamma_get_ioctl(struct drm_device *dev,
4516 void *data, struct drm_file *file_priv) 4626 void *data, struct drm_file *file_priv)
@@ -4576,7 +4686,7 @@ out:
4576 * Called by the user via ioctl. 4686 * Called by the user via ioctl.
4577 * 4687 *
4578 * Returns: 4688 * Returns:
4579 * Zero on success, errno on failure. 4689 * Zero on success, negative errno on failure.
4580 */ 4690 */
4581int drm_mode_page_flip_ioctl(struct drm_device *dev, 4691int drm_mode_page_flip_ioctl(struct drm_device *dev,
4582 void *data, struct drm_file *file_priv) 4692 void *data, struct drm_file *file_priv)
@@ -4599,7 +4709,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
4599 if (!crtc) 4709 if (!crtc)
4600 return -ENOENT; 4710 return -ENOENT;
4601 4711
4602 drm_modeset_lock_crtc(crtc); 4712 drm_modeset_lock_crtc(crtc, crtc->primary);
4603 if (crtc->primary->fb == NULL) { 4713 if (crtc->primary->fb == NULL) {
4604 /* The framebuffer is currently unbound, presumably 4714 /* The framebuffer is currently unbound, presumably
4605 * due to a hotplug event, that userspace has not 4715 * due to a hotplug event, that userspace has not
@@ -4742,7 +4852,7 @@ EXPORT_SYMBOL(drm_mode_config_reset);
4742 * Called by the user via ioctl. 4852 * Called by the user via ioctl.
4743 * 4853 *
4744 * Returns: 4854 * Returns:
4745 * Zero on success, errno on failure. 4855 * Zero on success, negative errno on failure.
4746 */ 4856 */
4747int drm_mode_create_dumb_ioctl(struct drm_device *dev, 4857int drm_mode_create_dumb_ioctl(struct drm_device *dev,
4748 void *data, struct drm_file *file_priv) 4858 void *data, struct drm_file *file_priv)
@@ -4769,6 +4879,16 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
4769 if (PAGE_ALIGN(size) == 0) 4879 if (PAGE_ALIGN(size) == 0)
4770 return -EINVAL; 4880 return -EINVAL;
4771 4881
4882 /*
4883 * handle, pitch and size are output parameters. Zero them out to
4884 * prevent drivers from accidentally using uninitialized data. Since
4885 * not all existing userspace is clearing these fields properly we
4886 * cannot reject IOCTL with garbage in them.
4887 */
4888 args->handle = 0;
4889 args->pitch = 0;
4890 args->size = 0;
4891
4772 return dev->driver->dumb_create(file_priv, dev, args); 4892 return dev->driver->dumb_create(file_priv, dev, args);
4773} 4893}
4774 4894
@@ -4784,7 +4904,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
4784 * Called by the user via ioctl. 4904 * Called by the user via ioctl.
4785 * 4905 *
4786 * Returns: 4906 * Returns:
4787 * Zero on success, errno on failure. 4907 * Zero on success, negative errno on failure.
4788 */ 4908 */
4789int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, 4909int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
4790 void *data, struct drm_file *file_priv) 4910 void *data, struct drm_file *file_priv)
@@ -4811,7 +4931,7 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
4811 * Called by the user via ioctl. 4931 * Called by the user via ioctl.
4812 * 4932 *
4813 * Returns: 4933 * Returns:
4814 * Zero on success, errno on failure. 4934 * Zero on success, negative errno on failure.
4815 */ 4935 */
4816int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, 4936int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
4817 void *data, struct drm_file *file_priv) 4937 void *data, struct drm_file *file_priv)
@@ -5097,6 +5217,7 @@ void drm_mode_config_init(struct drm_device *dev)
5097 INIT_LIST_HEAD(&dev->mode_config.property_blob_list); 5217 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
5098 INIT_LIST_HEAD(&dev->mode_config.plane_list); 5218 INIT_LIST_HEAD(&dev->mode_config.plane_list);
5099 idr_init(&dev->mode_config.crtc_idr); 5219 idr_init(&dev->mode_config.crtc_idr);
5220 idr_init(&dev->mode_config.tile_idr);
5100 5221
5101 drm_modeset_lock_all(dev); 5222 drm_modeset_lock_all(dev);
5102 drm_mode_create_standard_connector_properties(dev); 5223 drm_mode_create_standard_connector_properties(dev);
@@ -5184,6 +5305,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5184 crtc->funcs->destroy(crtc); 5305 crtc->funcs->destroy(crtc);
5185 } 5306 }
5186 5307
5308 idr_destroy(&dev->mode_config.tile_idr);
5187 idr_destroy(&dev->mode_config.crtc_idr); 5309 idr_destroy(&dev->mode_config.crtc_idr);
5188 drm_modeset_lock_fini(&dev->mode_config.connection_mutex); 5310 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
5189} 5311}
@@ -5206,3 +5328,100 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
5206 supported_rotations); 5328 supported_rotations);
5207} 5329}
5208EXPORT_SYMBOL(drm_mode_create_rotation_property); 5330EXPORT_SYMBOL(drm_mode_create_rotation_property);
5331
5332/**
5333 * DOC: Tile group
5334 *
5335 * Tile groups are used to represent tiled monitors with a unique
5336 * integer identifier. Tiled monitors using DisplayID v1.3 have
5337 * a unique 8-byte handle, we store this in a tile group, so we
5338 * have a common identifier for all tiles in a monitor group.
5339 */
5340static void drm_tile_group_free(struct kref *kref)
5341{
5342 struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
5343 struct drm_device *dev = tg->dev;
5344 mutex_lock(&dev->mode_config.idr_mutex);
5345 idr_remove(&dev->mode_config.tile_idr, tg->id);
5346 mutex_unlock(&dev->mode_config.idr_mutex);
5347 kfree(tg);
5348}
5349
5350/**
5351 * drm_mode_put_tile_group - drop a reference to a tile group.
5352 * @dev: DRM device
5353 * @tg: tile group to drop reference to.
5354 *
5355 * drop reference to tile group and free if 0.
5356 */
5357void drm_mode_put_tile_group(struct drm_device *dev,
5358 struct drm_tile_group *tg)
5359{
5360 kref_put(&tg->refcount, drm_tile_group_free);
5361}
5362
5363/**
5364 * drm_mode_get_tile_group - get a reference to an existing tile group
5365 * @dev: DRM device
5366 * @topology: 8-bytes unique per monitor.
5367 *
5368 * Use the unique bytes to get a reference to an existing tile group.
5369 *
5370 * RETURNS:
5371 * tile group or NULL if not found.
5372 */
5373struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
5374 char topology[8])
5375{
5376 struct drm_tile_group *tg;
5377 int id;
5378 mutex_lock(&dev->mode_config.idr_mutex);
5379 idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
5380 if (!memcmp(tg->group_data, topology, 8)) {
5381 if (!kref_get_unless_zero(&tg->refcount))
5382 tg = NULL;
5383 mutex_unlock(&dev->mode_config.idr_mutex);
5384 return tg;
5385 }
5386 }
5387 mutex_unlock(&dev->mode_config.idr_mutex);
5388 return NULL;
5389}
5390
5391/**
5392 * drm_mode_create_tile_group - create a tile group from a displayid description
5393 * @dev: DRM device
5394 * @topology: 8-bytes unique per monitor.
5395 *
5396 * Create a tile group for the unique monitor, and get a unique
5397 * identifier for the tile group.
5398 *
5399 * RETURNS:
5400 * new tile group or error.
5401 */
5402struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
5403 char topology[8])
5404{
5405 struct drm_tile_group *tg;
5406 int ret;
5407
5408 tg = kzalloc(sizeof(*tg), GFP_KERNEL);
5409 if (!tg)
5410 return ERR_PTR(-ENOMEM);
5411
5412 kref_init(&tg->refcount);
5413 memcpy(tg->group_data, topology, 8);
5414 tg->dev = dev;
5415
5416 mutex_lock(&dev->mode_config.idr_mutex);
5417 ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
5418 if (ret >= 0) {
5419 tg->id = ret;
5420 } else {
5421 kfree(tg);
5422 tg = ERR_PTR(ret);
5423 }
5424
5425 mutex_unlock(&dev->mode_config.idr_mutex);
5426 return tg;
5427}