1 /* $NetBSD: drm_panel.c,v 1.4 2020/01/03 21:01:16 jmcneill Exp $ */ 2 3 /* 4 * Copyright (C) 2013, NVIDIA Corporation. All rights reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sub license, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 */ 25 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: drm_panel.c,v 1.4 2020/01/03 21:01:16 jmcneill Exp $"); 28 29 #include <linux/err.h> 30 #include <linux/module.h> 31 32 #include <drm/drm_crtc.h> 33 #include <drm/drm_panel.h> 34 35 #ifdef __NetBSD__ 36 static struct mutex panel_lock; 37 static struct list_head panel_list = LIST_HEAD_INIT(panel_list); 38 #else 39 static DEFINE_MUTEX(panel_lock); 40 static LIST_HEAD(panel_list); 41 #endif 42 43 #ifdef __NetBSD__ 44 void drm_panel_init_lock(void) 45 { 46 linux_mutex_init(&panel_lock); 47 } 48 void drm_panel_fini_lock(void) 49 { 50 linux_mutex_destroy(&panel_lock); 51 } 52 #endif 53 54 void drm_panel_init(struct drm_panel *panel) 55 { 56 INIT_LIST_HEAD(&panel->list); 57 } 58 EXPORT_SYMBOL(drm_panel_init); 59 60 int drm_panel_add(struct drm_panel *panel) 61 { 62 mutex_lock(&panel_lock); 63 list_add_tail(&panel->list, &panel_list); 64 mutex_unlock(&panel_lock); 65 66 return 0; 67 } 68 EXPORT_SYMBOL(drm_panel_add); 69 70 void drm_panel_remove(struct drm_panel *panel) 71 { 72 mutex_lock(&panel_lock); 73 list_del_init(&panel->list); 74 mutex_unlock(&panel_lock); 75 } 76 EXPORT_SYMBOL(drm_panel_remove); 77 78 int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector) 79 { 80 if (panel->connector) 81 return -EBUSY; 82 83 panel->connector = connector; 84 panel->drm = connector->dev; 85 86 return 0; 87 } 88 EXPORT_SYMBOL(drm_panel_attach); 89 90 int drm_panel_detach(struct drm_panel *panel) 91 { 92 panel->connector = NULL; 93 panel->drm = NULL; 94 95 return 0; 96 } 97 EXPORT_SYMBOL(drm_panel_detach); 98 99 #ifdef CONFIG_OF 100 struct drm_panel *of_drm_find_panel(struct device_node *np) 101 { 102 struct drm_panel *panel; 103 104 mutex_lock(&panel_lock); 105 106 list_for_each_entry(panel, &panel_list, list) { 107 if (panel->dev->of_node == np) { 108 mutex_unlock(&panel_lock); 109 return panel; 110 } 111 } 112 113 mutex_unlock(&panel_lock); 114 return NULL; 115 } 116 EXPORT_SYMBOL(of_drm_find_panel); 117 #endif 118 119 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 120 MODULE_DESCRIPTION("DRM panel infrastructure"); 121 MODULE_LICENSE("GPL and additional rights"); 122