diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-11-11 06:07:35 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-11-11 06:07:35 -0500 |
commit | 732052ed3e7539d87136dd833be523747af3fb3e (patch) | |
tree | 7989d3062e50f3edc2a206148c6e776f88e7a2c1 /drivers/char/drm/drm_sysfs.c | |
parent | e96e33eeb8b876c7ec009c557ca5269328eceda0 (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.c | 68 |
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 | ||
30 | struct simple_dev { | 28 | struct 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 | ||
37 | static LIST_HEAD(simple_dev_list); | ||
38 | static DEFINE_SPINLOCK(simple_dev_list_lock); | ||
39 | |||
40 | static void release_simple_dev(struct class_device *class_dev) | 34 | static 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 | ||
121 | static 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 | |||
129 | static 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 | */ |
141 | struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, | 147 | struct 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: | 181 | error: |
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 | */ |
192 | void drm_sysfs_device_remove(dev_t dev) | 193 | void 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 | } |