From 2551952e802cab4c01081c1c880643795af2afb8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 14 Jun 2013 02:55:25 +0200 Subject: drm: Add default modes for connectors in unknown state The DRM CRTC helpers add default modes to connectors in the connected state if no mode can be retrieved from the connector. This behaviour is useful for VGA or DVI outputs that have no connected DDC bus. However, in such cases, the status of the output usually can't be retrieved and is reported as connector_status_unknown. Extend the addition of default modes to connectors in an unknown state to support outputs that can retrieve neither the modes nor the connection status. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Reviewed-by: Daniel Vetter --- include/drm/drm_modeset_helper_vtables.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 16ff3fa148f5..0d184d526a22 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -866,13 +866,19 @@ struct drm_connector_helper_funcs { * The usual way to implement this is to cache the EDID retrieved in the * probe callback somewhere in the driver-private connector structure. * In this function drivers then parse the modes in the EDID and add - * them by calling drm_add_edid_modes(). But connectors that driver a + * them by calling drm_add_edid_modes(). But connectors that drive a * fixed panel can also manually add specific modes using * drm_mode_probed_add(). Drivers which manually add modes should also * make sure that the &drm_connector.display_info, * &drm_connector.width_mm and &drm_connector.height_mm fields are * filled in. * + * Note that the caller function will automatically add standard VESA + * DMT modes up to 1024x768 if the .get_modes() helper operation returns + * no mode and if the connector status is connector_status_connected or + * connector_status_unknown. There is no need to call + * drm_add_modes_noedid() manually in that case. + * * Virtual drivers that just want some standard VESA mode with a given * resolution can call drm_add_modes_noedid(), and mark the preferred * one using drm_set_preferred_mode(). -- cgit v1.2.3-71-gd317 From 47f10854ca8958c5bf31c3a3fcd8e2c73ccc9925 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 15 Sep 2017 01:12:02 +0300 Subject: drm: Don't export the drm_gem_dumb_destroy() function The drm_gem_dumb_destroy() isn't used in drivers, don't export it. Signed-off-by: Laurent Pinchart Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_dumb_buffers.c | 8 +++++--- drivers/gpu/drm/drm_gem.c | 12 +----------- drivers/gpu/drm/drm_internal.h | 3 +++ include/drm/drm_gem.h | 3 --- 4 files changed, 9 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c index d18a740fe0f1..ad17fa21cebb 100644 --- a/drivers/gpu/drm/drm_dumb_buffers.c +++ b/drivers/gpu/drm/drm_dumb_buffers.c @@ -29,6 +29,7 @@ #include #include "drm_crtc_internal.h" +#include "drm_internal.h" /** * DOC: overview @@ -46,9 +47,10 @@ * KMS frame buffers. * * To support dumb objects drivers must implement the &drm_driver.dumb_create - * operation. &drm_driver.dumb_destroy defaults to drm_gem_dumb_destroy() if - * not set and &drm_driver.dumb_map_offset defaults to - * drm_gem_dumb_map_offset(). See the callbacks for further details. + * and &drm_driver.dumb_map_offset operations (the latter defaults to + * drm_gem_dumb_map_offset() if not set). Drivers that don't use GEM handles + * additionally need to implement the &drm_driver.dumb_destroy operation. See + * the callbacks for further details. * * Note that dumb objects may not be used for gpu acceleration, as has been * attempted on some ARM embedded platforms. Such drivers really must have diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 92f89cee213e..34b2f111c01c 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -335,22 +335,12 @@ out: } EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset); -/** - * drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers - * @file: drm file-private structure to remove the dumb handle from - * @dev: corresponding drm_device - * @handle: the dumb handle to remove - * - * This implements the &drm_driver.dumb_destroy kms driver callback for drivers - * which use gem to manage their backing storage. - */ int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, - uint32_t handle) + u32 handle) { return drm_gem_handle_delete(file, handle); } -EXPORT_SYMBOL(drm_gem_dumb_destroy); /** * drm_gem_handle_create_tail - internal functions to create a handle diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 81d386b5b92a..fad2249ee67b 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -191,6 +191,9 @@ void drm_gem_unpin(struct drm_gem_object *obj); int drm_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); void drm_gem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map); +int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, + u32 handle); + /* drm_debugfs.c drm_debugfs_crc.c */ #if defined(CONFIG_DEBUG_FS) int drm_debugfs_init(struct drm_minor *minor, int minor_id, diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 5e6daa1c982f..240049566592 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -416,8 +416,5 @@ int drm_gem_fence_array_add_implicit(struct xarray *fence_array, bool write); int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, u32 handle, u64 *offset); -int drm_gem_dumb_destroy(struct drm_file *file, - struct drm_device *dev, - uint32_t handle); #endif /* __DRM_GEM_H__ */ -- cgit v1.2.3-71-gd317 From 8dbe1b4a15977f31f6b3b79e577ad96a795c9827 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 20 Feb 2020 17:16:28 +0200 Subject: drm: Move legacy device list out of drm_driver The drm_driver structure contains a single field (legacy_dev_list) that is modified by the DRM core, used to store a linked list of legacy DRM devices associated with the driver. In order to make the structure const, move the field out to a global variable. This requires locking access to the global where the local field didn't require serialization, but this only affects legacy drivers, and isn't in any hot path. While at it, compile-out the legacy_dev_list field when DRM_LEGACY isn't defined. Signed-off-by: Laurent Pinchart Reviewed-by: Daniel Vetter Reviewed-by: Emil Velikov --- drivers/gpu/drm/drm_pci.c | 25 +++++++++++++++++-------- include/drm/drm_device.h | 10 +++------- include/drm/drm_drv.h | 2 -- 3 files changed, 20 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 6dba4b8ce4fe..dfb138aaccba 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -24,6 +24,8 @@ #include #include +#include +#include #include #include @@ -36,6 +38,9 @@ #include "drm_legacy.h" #ifdef CONFIG_DRM_LEGACY +/* List of devices hanging off drivers with stealth attach. */ +static LIST_HEAD(legacy_dev_list); +static DEFINE_MUTEX(legacy_dev_list_lock); /** * drm_pci_alloc - Allocate a PCI consistent memory block, for DMA. @@ -225,10 +230,11 @@ static int drm_get_pci_dev(struct pci_dev *pdev, if (ret) goto err_agp; - /* No locking needed since shadow-attach is single-threaded since it may - * only be called from the per-driver module init hook. */ - if (drm_core_check_feature(dev, DRIVER_LEGACY)) - list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list); + if (drm_core_check_feature(dev, DRIVER_LEGACY)) { + mutex_lock(&legacy_dev_list_lock); + list_add_tail(&dev->legacy_dev_list, &legacy_dev_list); + mutex_unlock(&legacy_dev_list_lock); + } return 0; @@ -261,7 +267,6 @@ int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) return -EINVAL; /* If not using KMS, fall back to stealth mode manual scanning. */ - INIT_LIST_HEAD(&driver->legacy_dev_list); for (i = 0; pdriver->id_table[i].vendor != 0; i++) { pid = &pdriver->id_table[i]; @@ -304,11 +309,15 @@ void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) if (!(driver->driver_features & DRIVER_LEGACY)) { WARN_ON(1); } else { - list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list, + mutex_lock(&legacy_dev_list_lock); + list_for_each_entry_safe(dev, tmp, &legacy_dev_list, legacy_dev_list) { - list_del(&dev->legacy_dev_list); - drm_put_dev(dev); + if (dev->driver == driver) { + list_del(&dev->legacy_dev_list); + drm_put_dev(dev); + } } + mutex_unlock(&legacy_dev_list_lock); } DRM_INFO("Module unloaded\n"); } diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 283a93ce4617..bd5abe7cd48f 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -51,13 +51,6 @@ enum switch_power_state { * may contain multiple heads. */ struct drm_device { - /** - * @legacy_dev_list: - * - * List of devices per driver for stealth attach cleanup - */ - struct list_head legacy_dev_list; - /** @if_version: Highest interface version set */ int if_version; @@ -336,6 +329,9 @@ struct drm_device { /* Everything below here is for legacy driver, never use! */ /* private: */ #if IS_ENABLED(CONFIG_DRM_LEGACY) + /* List of devices per driver for stealth attach cleanup */ + struct list_head legacy_dev_list; + /* Context handle management - linked list of context handles */ struct list_head ctxlist; diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 02787319246a..827838e0a97e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -499,8 +499,6 @@ struct drm_driver { /* Everything below here is for legacy driver, never use! */ /* private: */ - /* List of devices hanging off this driver with stealth attach. */ - struct list_head legacy_dev_list; int (*firstopen) (struct drm_device *); void (*preclose) (struct drm_device *, struct drm_file *file_priv); int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); -- cgit v1.2.3-71-gd317 From b1dda997a8a98fcb98189e5f4ee3108bc3da3d21 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 21 Feb 2020 00:19:22 +0200 Subject: drm: Use a const drm_driver for legacy PCI devices Now that the legacy PCI support code doesn't need to write to the drm_driver structure, it can be treated as const through the whole DRM core, unconditionally. This allows declaring the structure as const in all drivers, removing one possible attack vector. Signed-off-by: Laurent Pinchart Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_drv.c | 4 ---- drivers/gpu/drm/drm_pci.c | 8 +++++--- include/drm/drm_device.h | 4 ---- include/drm/drm_legacy.h | 10 ++++++---- 4 files changed, 11 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 734303802bc3..3f57e880685e 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -589,11 +589,7 @@ static int drm_dev_init(struct drm_device *dev, kref_init(&dev->ref); dev->dev = get_device(parent); -#ifdef CONFIG_DRM_LEGACY - dev->driver = (struct drm_driver *)driver; -#else dev->driver = driver; -#endif INIT_LIST_HEAD(&dev->managed.resources); spin_lock_init(&dev->managed.lock); diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index dfb138aaccba..5370e6b492fd 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -201,7 +201,7 @@ static void drm_pci_agp_init(struct drm_device *dev) static int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver) + const struct drm_driver *driver) { struct drm_device *dev; int ret; @@ -255,7 +255,8 @@ err_free: * * Return: 0 on success or a negative error code on failure. */ -int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) +int drm_legacy_pci_init(const struct drm_driver *driver, + struct pci_driver *pdriver) { struct pci_dev *pdev = NULL; const struct pci_device_id *pid; @@ -300,7 +301,8 @@ EXPORT_SYMBOL(drm_legacy_pci_init); * Unregister a DRM driver shadow-attached through drm_legacy_pci_init(). This * is deprecated and only used by dri1 drivers. */ -void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) +void drm_legacy_pci_exit(const struct drm_driver *driver, + struct pci_driver *pdriver) { struct drm_device *dev, *tmp; diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index bd5abe7cd48f..939904ae88fc 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -76,11 +76,7 @@ struct drm_device { } managed; /** @driver: DRM driver managing the device */ -#ifdef CONFIG_DRM_LEGACY - struct drm_driver *driver; -#else const struct drm_driver *driver; -#endif /** * @dev_private: diff --git a/include/drm/drm_legacy.h b/include/drm/drm_legacy.h index 852d7451eeb1..8ed04e9be997 100644 --- a/include/drm/drm_legacy.h +++ b/include/drm/drm_legacy.h @@ -198,8 +198,10 @@ struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size, size_t align); void drm_pci_free(struct drm_device *dev, struct drm_dma_handle *dmah); -int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); -void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); +int drm_legacy_pci_init(const struct drm_driver *driver, + struct pci_driver *pdriver); +void drm_legacy_pci_exit(const struct drm_driver *driver, + struct pci_driver *pdriver); #else @@ -214,13 +216,13 @@ static inline void drm_pci_free(struct drm_device *dev, { } -static inline int drm_legacy_pci_init(struct drm_driver *driver, +static inline int drm_legacy_pci_init(const struct drm_driver *driver, struct pci_driver *pdriver) { return -EINVAL; } -static inline void drm_legacy_pci_exit(struct drm_driver *driver, +static inline void drm_legacy_pci_exit(const struct drm_driver *driver, struct pci_driver *pdriver) { } -- cgit v1.2.3-71-gd317