Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/connector: Add drm_connector_find_by_fwnode() function (v3)

Add a function to find a connector based on a fwnode.

This will be used by the new drm_connector_oob_hotplug_event()
function which is added by the next patch in this patch-set.

Changes in v2:
- Complete rewrite to use a global connector list in drm_connector.c
rather then using a class-dev-iter in drm_sysfs.c

Changes in v3:
- Add forward declaration for struct fwnode_handle to drm_crtc_internal.h
(fixes warning reported by kernel test robot <lkp@intel.com>)

Tested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://lore.kernel.org/r/20210817215201.795062-4-hdegoede@redhat.com

+60
+50
drivers/gpu/drm/drm_connector.c
··· 65 65 * support can instead use e.g. drm_helper_hpd_irq_event(). 66 66 */ 67 67 68 + /* 69 + * Global connector list for drm_connector_find_by_fwnode(). 70 + * Note drm_connector_[un]register() first take connector->lock and then 71 + * take the connector_list_lock. 72 + */ 73 + static DEFINE_MUTEX(connector_list_lock); 74 + static LIST_HEAD(connector_list); 75 + 68 76 struct drm_conn_prop_enum_list { 69 77 int type; 70 78 const char *name; ··· 275 267 goto out_put_type_id; 276 268 } 277 269 270 + INIT_LIST_HEAD(&connector->global_connector_list_entry); 278 271 INIT_LIST_HEAD(&connector->probed_modes); 279 272 INIT_LIST_HEAD(&connector->modes); 280 273 mutex_init(&connector->mutex); ··· 543 534 /* Let userspace know we have a new connector */ 544 535 drm_sysfs_hotplug_event(connector->dev); 545 536 537 + mutex_lock(&connector_list_lock); 538 + list_add_tail(&connector->global_connector_list_entry, &connector_list); 539 + mutex_unlock(&connector_list_lock); 546 540 goto unlock; 547 541 548 542 err_debugfs: ··· 573 561 mutex_unlock(&connector->mutex); 574 562 return; 575 563 } 564 + 565 + mutex_lock(&connector_list_lock); 566 + list_del_init(&connector->global_connector_list_entry); 567 + mutex_unlock(&connector_list_lock); 576 568 577 569 if (connector->funcs->early_unregister) 578 570 connector->funcs->early_unregister(connector); ··· 2559 2543 drm_connector_put(connector); 2560 2544 2561 2545 return ret; 2546 + } 2547 + 2548 + /** 2549 + * drm_connector_find_by_fwnode - Find a connector based on the associated fwnode 2550 + * @fwnode: fwnode for which to find the matching drm_connector 2551 + * 2552 + * This functions looks up a drm_connector based on its associated fwnode. When 2553 + * a connector is found a reference to the connector is returned. The caller must 2554 + * call drm_connector_put() to release this reference when it is done with the 2555 + * connector. 2556 + * 2557 + * Returns: A reference to the found connector or an ERR_PTR(). 2558 + */ 2559 + struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode) 2560 + { 2561 + struct drm_connector *connector, *found = ERR_PTR(-ENODEV); 2562 + 2563 + if (!fwnode) 2564 + return ERR_PTR(-ENODEV); 2565 + 2566 + mutex_lock(&connector_list_lock); 2567 + 2568 + list_for_each_entry(connector, &connector_list, global_connector_list_entry) { 2569 + if (connector->fwnode == fwnode || 2570 + (connector->fwnode && connector->fwnode->secondary == fwnode)) { 2571 + drm_connector_get(connector); 2572 + found = connector; 2573 + break; 2574 + } 2575 + } 2576 + 2577 + mutex_unlock(&connector_list_lock); 2578 + 2579 + return found; 2562 2580 } 2563 2581 2564 2582
+2
drivers/gpu/drm/drm_crtc_internal.h
··· 58 58 struct edid; 59 59 struct kref; 60 60 struct work_struct; 61 + struct fwnode_handle; 61 62 62 63 /* drm_crtc.c */ 63 64 int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, ··· 187 186 int drm_connector_create_standard_properties(struct drm_device *dev); 188 187 const char *drm_get_connector_force_name(enum drm_connector_force force); 189 188 void drm_connector_free_work_fn(struct work_struct *work); 189 + struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode); 190 190 191 191 /* IOCTL */ 192 192 int drm_connector_property_set_ioctl(struct drm_device *dev,
+8
include/drm/drm_connector.h
··· 1247 1247 */ 1248 1248 struct list_head head; 1249 1249 1250 + /** 1251 + * @global_connector_list_entry: 1252 + * 1253 + * Connector entry in the global connector-list, used by 1254 + * drm_connector_find_by_fwnode(). 1255 + */ 1256 + struct list_head global_connector_list_entry; 1257 + 1250 1258 /** @base: base KMS object */ 1251 1259 struct drm_mode_object base; 1252 1260