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>

authored by Dave Airlie and committed by Dave Airlie 732052ed e96e33ee

+51 -51
+3 -4
drivers/char/drm/drmP.h
··· 547 void (*kernel_context_switch_unlock) (struct drm_device * dev, 548 drm_lock_t * lock); 549 int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); 550 551 /** 552 * Called by \c drm_device_is_agp. Typically used to determine if a ··· 983 char *name); 984 extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); 985 extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, 986 - dev_t dev, 987 - struct device *device, 988 - const char *fmt, ...); 989 - extern void drm_sysfs_device_remove(dev_t dev); 990 991 /* Inline replacements for DRM_IOREMAP macros */ 992 static __inline__ void drm_core_ioremap(struct drm_map *map,
··· 547 void (*kernel_context_switch_unlock) (struct drm_device * dev, 548 drm_lock_t * lock); 549 int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); 550 + int (*dri_library_name) (struct drm_device *dev, char *buf); 551 552 /** 553 * Called by \c drm_device_is_agp. Typically used to determine if a ··· 982 char *name); 983 extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); 984 extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, 985 + drm_head_t *head); 986 + extern void drm_sysfs_device_remove(struct class_device *class_dev); 987 988 /* Inline replacements for DRM_IOREMAP macros */ 989 static __inline__ void drm_core_ioremap(struct drm_map *map,
+3 -8
drivers/char/drm/drm_stub.c
··· 200 goto err_g1; 201 } 202 203 - head->dev_class = drm_sysfs_device_add(drm_class, 204 - MKDEV(DRM_MAJOR, 205 - minor), 206 - &dev->pdev->dev, 207 - "card%d", minor); 208 if (IS_ERR(head->dev_class)) { 209 printk(KERN_ERR 210 "DRM: Error sysfs_device_add.\n"); ··· 313 DRM_DEBUG("release secondary minor %d\n", minor); 314 315 drm_proc_cleanup(minor, drm_proc_root, head->dev_root); 316 - drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor)); 317 318 - *head = (drm_head_t) { 319 - .dev = NULL}; 320 321 drm_heads[minor] = NULL; 322
··· 200 goto err_g1; 201 } 202 203 + head->dev_class = drm_sysfs_device_add(drm_class, head); 204 if (IS_ERR(head->dev_class)) { 205 printk(KERN_ERR 206 "DRM: Error sysfs_device_add.\n"); ··· 317 DRM_DEBUG("release secondary minor %d\n", minor); 318 319 drm_proc_cleanup(minor, drm_proc_root, head->dev_root); 320 + drm_sysfs_device_remove(head->dev_class); 321 322 + *head = (drm_head_t) {.dev = NULL}; 323 324 drm_heads[minor] = NULL; 325
+28 -38
drivers/char/drm/drm_sysfs.c
··· 15 #include <linux/device.h> 16 #include <linux/kdev_t.h> 17 #include <linux/err.h> 18 - #include <linux/slab.h> 19 - #include <linux/string.h> 20 21 #include "drm_core.h" 22 #include "drmP.h" ··· 26 #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) 27 28 struct simple_dev { 29 - struct list_head node; 30 dev_t dev; 31 struct class_device class_dev; 32 }; 33 #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) 34 - 35 - static LIST_HEAD(simple_dev_list); 36 - static DEFINE_SPINLOCK(simple_dev_list_lock); 37 38 static void release_simple_dev(struct class_device *class_dev) 39 { ··· 118 class_unregister(&cs->class); 119 } 120 121 /** 122 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 123 * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. ··· 144 * Note: the struct drm_sysfs_class passed to this function must have previously been 145 * created with a call to drm_sysfs_create(). 146 */ 147 - struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, 148 - struct device *device, 149 - const char *fmt, ...) 150 { 151 - va_list args; 152 struct simple_dev *s_dev = NULL; 153 - int retval; 154 155 if ((cs == NULL) || (IS_ERR(cs))) { 156 retval = -ENODEV; ··· 162 } 163 memset(s_dev, 0x00, sizeof(*s_dev)); 164 165 - s_dev->dev = dev; 166 - s_dev->class_dev.dev = device; 167 s_dev->class_dev.class = &cs->class; 168 169 - va_start(args, fmt); 170 - vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args); 171 - va_end(args); 172 retval = class_device_register(&s_dev->class_dev); 173 if (retval) 174 goto error; 175 176 class_device_create_file(&s_dev->class_dev, &cs->attr); 177 178 - spin_lock(&simple_dev_list_lock); 179 - list_add(&s_dev->node, &simple_dev_list); 180 - spin_unlock(&simple_dev_list_lock); 181 - 182 return &s_dev->class_dev; 183 184 - error: 185 kfree(s_dev); 186 return ERR_PTR(retval); 187 } ··· 190 * This call unregisters and cleans up a class device that was created with a 191 * call to drm_sysfs_device_add() 192 */ 193 - void drm_sysfs_device_remove(dev_t dev) 194 { 195 - struct simple_dev *s_dev = NULL; 196 - int found = 0; 197 198 - spin_lock(&simple_dev_list_lock); 199 - list_for_each_entry(s_dev, &simple_dev_list, node) { 200 - if (s_dev->dev == dev) { 201 - found = 1; 202 - break; 203 - } 204 - } 205 - if (found) { 206 - list_del(&s_dev->node); 207 - spin_unlock(&simple_dev_list_lock); 208 - class_device_unregister(&s_dev->class_dev); 209 - } else { 210 - spin_unlock(&simple_dev_list_lock); 211 - } 212 }
··· 15 #include <linux/device.h> 16 #include <linux/kdev_t.h> 17 #include <linux/err.h> 18 19 #include "drm_core.h" 20 #include "drmP.h" ··· 28 #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) 29 30 struct simple_dev { 31 dev_t dev; 32 struct class_device class_dev; 33 }; 34 #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) 35 36 static void release_simple_dev(struct class_device *class_dev) 37 { ··· 124 class_unregister(&cs->class); 125 } 126 127 + static ssize_t show_dri(struct class_device *class_device, char *buf) 128 + { 129 + drm_device_t * dev = ((drm_head_t *)class_get_devdata(class_device))->dev; 130 + if (dev->driver->dri_library_name) 131 + return dev->driver->dri_library_name(dev, buf); 132 + return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); 133 + } 134 + 135 + static struct class_device_attribute class_device_attrs[] = { 136 + __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), 137 + }; 138 + 139 /** 140 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 141 * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. ··· 138 * Note: the struct drm_sysfs_class passed to this function must have previously been 139 * created with a call to drm_sysfs_create(). 140 */ 141 + struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, 142 + drm_head_t *head) 143 { 144 struct simple_dev *s_dev = NULL; 145 + int i, retval; 146 147 if ((cs == NULL) || (IS_ERR(cs))) { 148 retval = -ENODEV; ··· 158 } 159 memset(s_dev, 0x00, sizeof(*s_dev)); 160 161 + s_dev->dev = MKDEV(DRM_MAJOR, head->minor); 162 + s_dev->class_dev.dev = &(head->dev->pdev)->dev; 163 s_dev->class_dev.class = &cs->class; 164 165 + snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); 166 retval = class_device_register(&s_dev->class_dev); 167 if (retval) 168 goto error; 169 170 class_device_create_file(&s_dev->class_dev, &cs->attr); 171 + class_set_devdata(&s_dev->class_dev, head); 172 173 + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) 174 + class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); 175 return &s_dev->class_dev; 176 177 + error: 178 kfree(s_dev); 179 return ERR_PTR(retval); 180 } ··· 189 * This call unregisters and cleans up a class device that was created with a 190 * call to drm_sysfs_device_add() 191 */ 192 + void drm_sysfs_device_remove(struct class_device *class_dev) 193 { 194 + struct simple_dev *s_dev = to_simple_dev(class_dev); 195 + int i; 196 197 + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) 198 + class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); 199 + class_device_unregister(&s_dev->class_dev); 200 }
+11
drivers/char/drm/radeon_drv.c
··· 42 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); 43 module_param_named(no_wb, radeon_no_wb, int, 0444); 44 45 46 static struct pci_device_id pciidlist[] = { 47 radeon_PCI_IDS ··· 71 .lastclose = radeon_driver_lastclose, 72 .unload = radeon_driver_unload, 73 .vblank_wait = radeon_driver_vblank_wait, 74 .irq_preinstall = radeon_driver_irq_preinstall, 75 .irq_postinstall = radeon_driver_irq_postinstall, 76 .irq_uninstall = radeon_driver_irq_uninstall,
··· 42 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); 43 module_param_named(no_wb, radeon_no_wb, int, 0444); 44 45 + static int dri_library_name(struct drm_device *dev, char *buf) 46 + { 47 + drm_radeon_private_t *dev_priv = dev->dev_private; 48 + int family = dev_priv->flags & CHIP_FAMILY_MASK; 49 + 50 + return snprintf(buf, PAGE_SIZE, "%s\n", 51 + (family < CHIP_R200) ? "radeon" : 52 + ((family < CHIP_R300) ? "r200" : 53 + "r300")); 54 + } 55 56 static struct pci_device_id pciidlist[] = { 57 radeon_PCI_IDS ··· 61 .lastclose = radeon_driver_lastclose, 62 .unload = radeon_driver_unload, 63 .vblank_wait = radeon_driver_vblank_wait, 64 + .dri_library_name = dri_library_name, 65 .irq_preinstall = radeon_driver_irq_preinstall, 66 .irq_postinstall = radeon_driver_irq_postinstall, 67 .irq_uninstall = radeon_driver_irq_uninstall,
+1 -1
drivers/char/drm/radeon_drv.h
··· 103 CHIP_R100, 104 CHIP_RS100, 105 CHIP_RV100, 106 - CHIP_R200, 107 CHIP_RV200, 108 CHIP_RS200, 109 CHIP_R250, 110 CHIP_RS250,
··· 103 CHIP_R100, 104 CHIP_RS100, 105 CHIP_RV100, 106 CHIP_RV200, 107 + CHIP_R200, 108 CHIP_RS200, 109 CHIP_R250, 110 CHIP_RS250,
+5
drivers/char/drm/via_drv.c
··· 29 30 #include "drm_pciids.h" 31 32 33 static struct pci_device_id pciidlist[] = { 34 viadrv_PCI_IDS ··· 65 .irq_uninstall = via_driver_irq_uninstall, 66 .irq_handler = via_driver_irq_handler, 67 .dma_quiescent = via_driver_dma_quiescent, 68 .reclaim_buffers = drm_core_reclaim_buffers, 69 .get_map_ofs = drm_core_get_map_ofs, 70 .get_reg_ofs = drm_core_get_reg_ofs,
··· 29 30 #include "drm_pciids.h" 31 32 + static int dri_library_name(struct drm_device *dev, char *buf) 33 + { 34 + return snprintf(buf, PAGE_SIZE, "unichrome"); 35 + } 36 37 static struct pci_device_id pciidlist[] = { 38 viadrv_PCI_IDS ··· 61 .irq_uninstall = via_driver_irq_uninstall, 62 .irq_handler = via_driver_irq_handler, 63 .dma_quiescent = via_driver_dma_quiescent, 64 + .dri_library_name = dri_library_name, 65 .reclaim_buffers = drm_core_reclaim_buffers, 66 .get_map_ofs = drm_core_get_map_ofs, 67 .get_reg_ofs = drm_core_get_reg_ofs,