aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Moreau <pierre.morrow@free.fr>2016-12-07 18:57:08 -0500
committerBen Skeggs <bskeggs@redhat.com>2016-12-12 20:40:16 -0500
commitdb1a0ae21461afa4bc435651a6dd55e0e6ef4a8b (patch)
treea100b660d9b65be8d76e72e2501a24b8cb877410
parent79d48dadb0a71ec31ec8ce234ad0811a50123580 (diff)
drm/nouveau/bl: Assign different names to interfaces
Currently, every backlight interface created by Nouveau uses the same name, nv_backlight. This leads to a sysfs warning as it tries to create an already existing folder. This patch adds a incremented number to the name, but keeps the initial name as nv_backlight, to avoid possibly breaking userspace; the second interface will be named nv_backlight1, and so on. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86539 v2: * Switch to using ida for generating unique IDs, as suggested by Ilia Mirkin; * Allocate backlight name on the stack, as suggested by Ilia Mirkin; * Move `nouveau_get_backlight_name()` to avoid forward declaration, as suggested by Ilia Mirkin; * Fix reference to bug report formatting, as reported by Nick Tenney. v3: * Define a macro for the size of the backlight name, to avoid defining it multiple times; * Use snprintf in place of sprintf. v4: * Do not create similarly named interfaces when reaching the maximum amount of unique names, but fail instead, as pointed out by Lukas Wunner Signed-off-by: Pierre Moreau <pierre.morrow@free.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c74
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
4 files changed, 83 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index 5e2c5685b4dd..a34cd35d4965 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -31,11 +31,35 @@
31 */ 31 */
32 32
33#include <linux/backlight.h> 33#include <linux/backlight.h>
34#include <linux/idr.h>
34 35
35#include "nouveau_drv.h" 36#include "nouveau_drv.h"
36#include "nouveau_reg.h" 37#include "nouveau_reg.h"
37#include "nouveau_encoder.h" 38#include "nouveau_encoder.h"
38 39
40static struct ida bl_ida;
41#define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0'
42
43struct backlight_connector {
44 struct list_head head;
45 int id;
46};
47
48static bool
49nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE], struct backlight_connector
50 *connector)
51{
52 const int nb = ida_simple_get(&bl_ida, 0, 0, GFP_KERNEL);
53 if (nb < 0 || nb >= 100)
54 return false;
55 if (nb > 0)
56 snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb);
57 else
58 snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight");
59 connector->id = nb;
60 return true;
61}
62
39static int 63static int
40nv40_get_intensity(struct backlight_device *bd) 64nv40_get_intensity(struct backlight_device *bd)
41{ 65{
@@ -74,6 +98,8 @@ nv40_backlight_init(struct drm_connector *connector)
74 struct nvif_object *device = &drm->device.object; 98 struct nvif_object *device = &drm->device.object;
75 struct backlight_properties props; 99 struct backlight_properties props;
76 struct backlight_device *bd; 100 struct backlight_device *bd;
101 struct backlight_connector bl_connector;
102 char backlight_name[BL_NAME_SIZE];
77 103
78 if (!(nvif_rd32(device, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) 104 if (!(nvif_rd32(device, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
79 return 0; 105 return 0;
@@ -81,10 +107,19 @@ nv40_backlight_init(struct drm_connector *connector)
81 memset(&props, 0, sizeof(struct backlight_properties)); 107 memset(&props, 0, sizeof(struct backlight_properties));
82 props.type = BACKLIGHT_RAW; 108 props.type = BACKLIGHT_RAW;
83 props.max_brightness = 31; 109 props.max_brightness = 31;
84 bd = backlight_device_register("nv_backlight", connector->kdev, drm, 110 if (!nouveau_get_backlight_name(backlight_name, &bl_connector)) {
111 NV_ERROR(drm, "Failed to retrieve a unique name for the backlight interface\n");
112 return 0;
113 }
114 bd = backlight_device_register(backlight_name , connector->kdev, drm,
85 &nv40_bl_ops, &props); 115 &nv40_bl_ops, &props);
86 if (IS_ERR(bd)) 116
117 if (IS_ERR(bd)) {
118 if (bl_connector.id > 0)
119 ida_simple_remove(&bl_ida, bl_connector.id);
87 return PTR_ERR(bd); 120 return PTR_ERR(bd);
121 }
122 list_add(&bl_connector.head, &drm->bl_connectors);
88 drm->backlight = bd; 123 drm->backlight = bd;
89 bd->props.brightness = nv40_get_intensity(bd); 124 bd->props.brightness = nv40_get_intensity(bd);
90 backlight_update_status(bd); 125 backlight_update_status(bd);
@@ -182,6 +217,8 @@ nv50_backlight_init(struct drm_connector *connector)
182 struct backlight_properties props; 217 struct backlight_properties props;
183 struct backlight_device *bd; 218 struct backlight_device *bd;
184 const struct backlight_ops *ops; 219 const struct backlight_ops *ops;
220 struct backlight_connector bl_connector;
221 char backlight_name[BL_NAME_SIZE];
185 222
186 nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); 223 nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS);
187 if (!nv_encoder) { 224 if (!nv_encoder) {
@@ -203,11 +240,20 @@ nv50_backlight_init(struct drm_connector *connector)
203 memset(&props, 0, sizeof(struct backlight_properties)); 240 memset(&props, 0, sizeof(struct backlight_properties));
204 props.type = BACKLIGHT_RAW; 241 props.type = BACKLIGHT_RAW;
205 props.max_brightness = 100; 242 props.max_brightness = 100;
206 bd = backlight_device_register("nv_backlight", connector->kdev, 243 if (!nouveau_get_backlight_name(backlight_name, &bl_connector)) {
244 NV_ERROR(drm, "Failed to retrieve a unique name for the backlight interface\n");
245 return 0;
246 }
247 bd = backlight_device_register(backlight_name , connector->kdev,
207 nv_encoder, ops, &props); 248 nv_encoder, ops, &props);
208 if (IS_ERR(bd)) 249
250 if (IS_ERR(bd)) {
251 if (bl_connector.id > 0)
252 ida_simple_remove(&bl_ida, bl_connector.id);
209 return PTR_ERR(bd); 253 return PTR_ERR(bd);
254 }
210 255
256 list_add(&bl_connector.head, &drm->bl_connectors);
211 drm->backlight = bd; 257 drm->backlight = bd;
212 bd->props.brightness = bd->ops->get_brightness(bd); 258 bd->props.brightness = bd->ops->get_brightness(bd);
213 backlight_update_status(bd); 259 backlight_update_status(bd);
@@ -221,6 +267,8 @@ nouveau_backlight_init(struct drm_device *dev)
221 struct nvif_device *device = &drm->device; 267 struct nvif_device *device = &drm->device;
222 struct drm_connector *connector; 268 struct drm_connector *connector;
223 269
270 INIT_LIST_HEAD(&drm->bl_connectors);
271
224 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 272 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
225 if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && 273 if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
226 connector->connector_type != DRM_MODE_CONNECTOR_eDP) 274 connector->connector_type != DRM_MODE_CONNECTOR_eDP)
@@ -247,9 +295,27 @@ void
247nouveau_backlight_exit(struct drm_device *dev) 295nouveau_backlight_exit(struct drm_device *dev)
248{ 296{
249 struct nouveau_drm *drm = nouveau_drm(dev); 297 struct nouveau_drm *drm = nouveau_drm(dev);
298 struct backlight_connector *connector;
299
300 list_for_each_entry(connector, &drm->bl_connectors, head) {
301 if (connector->id >= 0)
302 ida_simple_remove(&bl_ida, connector->id);
303 }
250 304
251 if (drm->backlight) { 305 if (drm->backlight) {
252 backlight_device_unregister(drm->backlight); 306 backlight_device_unregister(drm->backlight);
253 drm->backlight = NULL; 307 drm->backlight = NULL;
254 } 308 }
255} 309}
310
311void
312nouveau_backlight_ctor(void)
313{
314 ida_init(&bl_ida);
315}
316
317void
318nouveau_backlight_dtor(void)
319{
320 ida_destroy(&bl_ida);
321}
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
index 330fe0fc5c11..4a75df06c139 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.h
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
@@ -91,6 +91,8 @@ int nouveau_crtc_set_config(struct drm_mode_set *set);
91#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT 91#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
92extern int nouveau_backlight_init(struct drm_device *); 92extern int nouveau_backlight_init(struct drm_device *);
93extern void nouveau_backlight_exit(struct drm_device *); 93extern void nouveau_backlight_exit(struct drm_device *);
94extern void nouveau_backlight_ctor(void);
95extern void nouveau_backlight_dtor(void);
94#else 96#else
95static inline int 97static inline int
96nouveau_backlight_init(struct drm_device *dev) 98nouveau_backlight_init(struct drm_device *dev)
@@ -101,6 +103,14 @@ nouveau_backlight_init(struct drm_device *dev)
101static inline void 103static inline void
102nouveau_backlight_exit(struct drm_device *dev) { 104nouveau_backlight_exit(struct drm_device *dev) {
103} 105}
106
107static inline void
108nouveau_backlight_ctor(void) {
109}
110
111static inline void
112nouveau_backlight_dtor(void) {
113}
104#endif 114#endif
105 115
106struct drm_framebuffer * 116struct drm_framebuffer *
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 064a925ed69a..59348fc41c77 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1122,6 +1122,7 @@ nouveau_drm_init(void)
1122#endif 1122#endif
1123 1123
1124 nouveau_register_dsm_handler(); 1124 nouveau_register_dsm_handler();
1125 nouveau_backlight_ctor();
1125 return drm_pci_init(&driver_pci, &nouveau_drm_pci_driver); 1126 return drm_pci_init(&driver_pci, &nouveau_drm_pci_driver);
1126} 1127}
1127 1128
@@ -1132,6 +1133,7 @@ nouveau_drm_exit(void)
1132 return; 1133 return;
1133 1134
1134 drm_pci_exit(&driver_pci, &nouveau_drm_pci_driver); 1135 drm_pci_exit(&driver_pci, &nouveau_drm_pci_driver);
1136 nouveau_backlight_dtor();
1135 nouveau_unregister_dsm_handler(); 1137 nouveau_unregister_dsm_handler();
1136 1138
1137#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER 1139#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 9730c0ef6c6a..8d5ed5bfdacb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -163,6 +163,7 @@ struct nouveau_drm {
163 struct nvbios vbios; 163 struct nvbios vbios;
164 struct nouveau_display *display; 164 struct nouveau_display *display;
165 struct backlight_device *backlight; 165 struct backlight_device *backlight;
166 struct list_head bl_connectors;
166 struct work_struct hpd_work; 167 struct work_struct hpd_work;
167#ifdef CONFIG_ACPI 168#ifdef CONFIG_ACPI
168 struct notifier_block acpi_nb; 169 struct notifier_block acpi_nb;