aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drm_sysfs.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@starflyer.(none)>2005-11-11 06:07:35 -0500
committerDave Airlie <airlied@linux.ie>2005-11-11 06:07:35 -0500
commit732052ed3e7539d87136dd833be523747af3fb3e (patch)
tree7989d3062e50f3edc2a206148c6e776f88e7a2c1 /drivers/char/drm/drm_sysfs.c
parente96e33eeb8b876c7ec009c557ca5269328eceda0 (diff)
drm: simplify sysfs code for drm
This simplifies the sysfs code for the drm and add a dri_library_name attribute which can be used by a userspace app to figure out which library to load. From: Jon Smirl <jonsmirl@gmail.com> Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/drm_sysfs.c')
-rw-r--r--drivers/char/drm/drm_sysfs.c68
1 files changed, 29 insertions, 39 deletions
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 6d3449761914..68e43ddc16ae 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -15,8 +15,6 @@
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/kdev_t.h> 16#include <linux/kdev_t.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h>
19#include <linux/string.h>
20 18
21#include "drm_core.h" 19#include "drm_core.h"
22#include "drmP.h" 20#include "drmP.h"
@@ -28,15 +26,11 @@ struct drm_sysfs_class {
28#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) 26#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
29 27
30struct simple_dev { 28struct simple_dev {
31 struct list_head node;
32 dev_t dev; 29 dev_t dev;
33 struct class_device class_dev; 30 struct class_device class_dev;
34}; 31};
35#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) 32#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
36 33
37static LIST_HEAD(simple_dev_list);
38static DEFINE_SPINLOCK(simple_dev_list_lock);
39
40static void release_simple_dev(struct class_device *class_dev) 34static void release_simple_dev(struct class_device *class_dev)
41{ 35{
42 struct simple_dev *s_dev = to_simple_dev(class_dev); 36 struct simple_dev *s_dev = to_simple_dev(class_dev);
@@ -124,6 +118,18 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs)
124 class_unregister(&cs->class); 118 class_unregister(&cs->class);
125} 119}
126 120
121static ssize_t show_dri(struct class_device *class_device, char *buf)
122{
123 drm_device_t * dev = ((drm_head_t *)class_get_devdata(class_device))->dev;
124 if (dev->driver->dri_library_name)
125 return dev->driver->dri_library_name(dev, buf);
126 return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name);
127}
128
129static struct class_device_attribute class_device_attrs[] = {
130 __ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
131};
132
127/** 133/**
128 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 134 * drm_sysfs_device_add - adds a class device to sysfs for a character driver
129 * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. 135 * @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
@@ -138,13 +144,11 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs)
138 * Note: the struct drm_sysfs_class passed to this function must have previously been 144 * Note: the struct drm_sysfs_class passed to this function must have previously been
139 * created with a call to drm_sysfs_create(). 145 * created with a call to drm_sysfs_create().
140 */ 146 */
141struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, 147struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
142 struct device *device, 148 drm_head_t *head)
143 const char *fmt, ...)
144{ 149{
145 va_list args;
146 struct simple_dev *s_dev = NULL; 150 struct simple_dev *s_dev = NULL;
147 int retval; 151 int i, retval;
148 152
149 if ((cs == NULL) || (IS_ERR(cs))) { 153 if ((cs == NULL) || (IS_ERR(cs))) {
150 retval = -ENODEV; 154 retval = -ENODEV;
@@ -158,26 +162,23 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
158 } 162 }
159 memset(s_dev, 0x00, sizeof(*s_dev)); 163 memset(s_dev, 0x00, sizeof(*s_dev));
160 164
161 s_dev->dev = dev; 165 s_dev->dev = MKDEV(DRM_MAJOR, head->minor);
162 s_dev->class_dev.dev = device; 166 s_dev->class_dev.dev = &(head->dev->pdev)->dev;
163 s_dev->class_dev.class = &cs->class; 167 s_dev->class_dev.class = &cs->class;
164 168
165 va_start(args, fmt); 169 snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor);
166 vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
167 va_end(args);
168 retval = class_device_register(&s_dev->class_dev); 170 retval = class_device_register(&s_dev->class_dev);
169 if (retval) 171 if (retval)
170 goto error; 172 goto error;
171 173
172 class_device_create_file(&s_dev->class_dev, &cs->attr); 174 class_device_create_file(&s_dev->class_dev, &cs->attr);
175 class_set_devdata(&s_dev->class_dev, head);
173 176
174 spin_lock(&simple_dev_list_lock); 177 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
175 list_add(&s_dev->node, &simple_dev_list); 178 class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
176 spin_unlock(&simple_dev_list_lock);
177
178 return &s_dev->class_dev; 179 return &s_dev->class_dev;
179 180
180 error: 181error:
181 kfree(s_dev); 182 kfree(s_dev);
182 return ERR_PTR(retval); 183 return ERR_PTR(retval);
183} 184}
@@ -189,23 +190,12 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
189 * This call unregisters and cleans up a class device that was created with a 190 * This call unregisters and cleans up a class device that was created with a
190 * call to drm_sysfs_device_add() 191 * call to drm_sysfs_device_add()
191 */ 192 */
192void drm_sysfs_device_remove(dev_t dev) 193void drm_sysfs_device_remove(struct class_device *class_dev)
193{ 194{
194 struct simple_dev *s_dev = NULL; 195 struct simple_dev *s_dev = to_simple_dev(class_dev);
195 int found = 0; 196 int i;
196 197
197 spin_lock(&simple_dev_list_lock); 198 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
198 list_for_each_entry(s_dev, &simple_dev_list, node) { 199 class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]);
199 if (s_dev->dev == dev) { 200 class_device_unregister(&s_dev->class_dev);
200 found = 1;
201 break;
202 }
203 }
204 if (found) {
205 list_del(&s_dev->node);
206 spin_unlock(&simple_dev_list_lock);
207 class_device_unregister(&s_dev->class_dev);
208 } else {
209 spin_unlock(&simple_dev_list_lock);
210 }
211} 201}