Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'fbdev-fixes-4.0' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux

Pull fbdev fixes from Tomi Valkeinen:
- Fix regression in with omapdss when using i2c displays
- Fix possible null deref in fbmon
- Check kalloc return value in AMBA CLCD

* tag 'fbdev-fixes-4.0' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux:
OMAPDSS: fix regression with display sysfs files
video: fbdev: fix possible null dereference
video: ARM CLCD: Add missing error check for devm_kzalloc

+102 -87
+3
drivers/video/fbdev/amba-clcd.c
··· 599 599 600 600 len = clcdfb_snprintf_mode(NULL, 0, mode); 601 601 name = devm_kzalloc(dev, len + 1, GFP_KERNEL); 602 + if (!name) 603 + return -ENOMEM; 604 + 602 605 clcdfb_snprintf_mode(name, len + 1, mode); 603 606 mode->name = name; 604 607
+3 -3
drivers/video/fbdev/core/fbmon.c
··· 624 624 int num = 0, i, first = 1; 625 625 int ver, rev; 626 626 627 - ver = edid[EDID_STRUCT_VERSION]; 628 - rev = edid[EDID_STRUCT_REVISION]; 629 - 630 627 mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); 631 628 if (mode == NULL) 632 629 return NULL; ··· 633 636 kfree(mode); 634 637 return NULL; 635 638 } 639 + 640 + ver = edid[EDID_STRUCT_VERSION]; 641 + rev = edid[EDID_STRUCT_REVISION]; 636 642 637 643 *dbsize = 0; 638 644
+95 -84
drivers/video/fbdev/omap2/dss/display-sysfs.c
··· 28 28 #include <video/omapdss.h> 29 29 #include "dss.h" 30 30 31 - static struct omap_dss_device *to_dss_device_sysfs(struct device *dev) 31 + static ssize_t display_name_show(struct omap_dss_device *dssdev, char *buf) 32 32 { 33 - struct omap_dss_device *dssdev = NULL; 34 - 35 - for_each_dss_dev(dssdev) { 36 - if (dssdev->dev == dev) { 37 - omap_dss_put_device(dssdev); 38 - return dssdev; 39 - } 40 - } 41 - 42 - return NULL; 43 - } 44 - 45 - static ssize_t display_name_show(struct device *dev, 46 - struct device_attribute *attr, char *buf) 47 - { 48 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 49 - 50 33 return snprintf(buf, PAGE_SIZE, "%s\n", 51 34 dssdev->name ? 52 35 dssdev->name : ""); 53 36 } 54 37 55 - static ssize_t display_enabled_show(struct device *dev, 56 - struct device_attribute *attr, char *buf) 38 + static ssize_t display_enabled_show(struct omap_dss_device *dssdev, char *buf) 57 39 { 58 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 59 - 60 40 return snprintf(buf, PAGE_SIZE, "%d\n", 61 41 omapdss_device_is_enabled(dssdev)); 62 42 } 63 43 64 - static ssize_t display_enabled_store(struct device *dev, 65 - struct device_attribute *attr, 44 + static ssize_t display_enabled_store(struct omap_dss_device *dssdev, 66 45 const char *buf, size_t size) 67 46 { 68 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 69 47 int r; 70 48 bool enable; 71 49 ··· 68 90 return size; 69 91 } 70 92 71 - static ssize_t display_tear_show(struct device *dev, 72 - struct device_attribute *attr, char *buf) 93 + static ssize_t display_tear_show(struct omap_dss_device *dssdev, char *buf) 73 94 { 74 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 75 95 return snprintf(buf, PAGE_SIZE, "%d\n", 76 96 dssdev->driver->get_te ? 77 97 dssdev->driver->get_te(dssdev) : 0); 78 98 } 79 99 80 - static ssize_t display_tear_store(struct device *dev, 81 - struct device_attribute *attr, const char *buf, size_t size) 100 + static ssize_t display_tear_store(struct omap_dss_device *dssdev, 101 + const char *buf, size_t size) 82 102 { 83 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 84 103 int r; 85 104 bool te; 86 105 ··· 95 120 return size; 96 121 } 97 122 98 - static ssize_t display_timings_show(struct device *dev, 99 - struct device_attribute *attr, char *buf) 123 + static ssize_t display_timings_show(struct omap_dss_device *dssdev, char *buf) 100 124 { 101 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 102 125 struct omap_video_timings t; 103 126 104 127 if (!dssdev->driver->get_timings) ··· 110 137 t.y_res, t.vfp, t.vbp, t.vsw); 111 138 } 112 139 113 - static ssize_t display_timings_store(struct device *dev, 114 - struct device_attribute *attr, const char *buf, size_t size) 140 + static ssize_t display_timings_store(struct omap_dss_device *dssdev, 141 + const char *buf, size_t size) 115 142 { 116 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 117 143 struct omap_video_timings t = dssdev->panel.timings; 118 144 int r, found; 119 145 ··· 148 176 return size; 149 177 } 150 178 151 - static ssize_t display_rotate_show(struct device *dev, 152 - struct device_attribute *attr, char *buf) 179 + static ssize_t display_rotate_show(struct omap_dss_device *dssdev, char *buf) 153 180 { 154 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 155 181 int rotate; 156 182 if (!dssdev->driver->get_rotate) 157 183 return -ENOENT; ··· 157 187 return snprintf(buf, PAGE_SIZE, "%u\n", rotate); 158 188 } 159 189 160 - static ssize_t display_rotate_store(struct device *dev, 161 - struct device_attribute *attr, const char *buf, size_t size) 190 + static ssize_t display_rotate_store(struct omap_dss_device *dssdev, 191 + const char *buf, size_t size) 162 192 { 163 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 164 193 int rot, r; 165 194 166 195 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) ··· 176 207 return size; 177 208 } 178 209 179 - static ssize_t display_mirror_show(struct device *dev, 180 - struct device_attribute *attr, char *buf) 210 + static ssize_t display_mirror_show(struct omap_dss_device *dssdev, char *buf) 181 211 { 182 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 183 212 int mirror; 184 213 if (!dssdev->driver->get_mirror) 185 214 return -ENOENT; ··· 185 218 return snprintf(buf, PAGE_SIZE, "%u\n", mirror); 186 219 } 187 220 188 - static ssize_t display_mirror_store(struct device *dev, 189 - struct device_attribute *attr, const char *buf, size_t size) 221 + static ssize_t display_mirror_store(struct omap_dss_device *dssdev, 222 + const char *buf, size_t size) 190 223 { 191 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 192 224 int r; 193 225 bool mirror; 194 226 ··· 205 239 return size; 206 240 } 207 241 208 - static ssize_t display_wss_show(struct device *dev, 209 - struct device_attribute *attr, char *buf) 242 + static ssize_t display_wss_show(struct omap_dss_device *dssdev, char *buf) 210 243 { 211 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 212 244 unsigned int wss; 213 245 214 246 if (!dssdev->driver->get_wss) ··· 217 253 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); 218 254 } 219 255 220 - static ssize_t display_wss_store(struct device *dev, 221 - struct device_attribute *attr, const char *buf, size_t size) 256 + static ssize_t display_wss_store(struct omap_dss_device *dssdev, 257 + const char *buf, size_t size) 222 258 { 223 - struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); 224 259 u32 wss; 225 260 int r; 226 261 ··· 240 277 return size; 241 278 } 242 279 243 - static DEVICE_ATTR(display_name, S_IRUGO, display_name_show, NULL); 244 - static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, 280 + struct display_attribute { 281 + struct attribute attr; 282 + ssize_t (*show)(struct omap_dss_device *, char *); 283 + ssize_t (*store)(struct omap_dss_device *, const char *, size_t); 284 + }; 285 + 286 + #define DISPLAY_ATTR(_name, _mode, _show, _store) \ 287 + struct display_attribute display_attr_##_name = \ 288 + __ATTR(_name, _mode, _show, _store) 289 + 290 + static DISPLAY_ATTR(name, S_IRUGO, display_name_show, NULL); 291 + static DISPLAY_ATTR(display_name, S_IRUGO, display_name_show, NULL); 292 + static DISPLAY_ATTR(enabled, S_IRUGO|S_IWUSR, 245 293 display_enabled_show, display_enabled_store); 246 - static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, 294 + static DISPLAY_ATTR(tear_elim, S_IRUGO|S_IWUSR, 247 295 display_tear_show, display_tear_store); 248 - static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR, 296 + static DISPLAY_ATTR(timings, S_IRUGO|S_IWUSR, 249 297 display_timings_show, display_timings_store); 250 - static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR, 298 + static DISPLAY_ATTR(rotate, S_IRUGO|S_IWUSR, 251 299 display_rotate_show, display_rotate_store); 252 - static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR, 300 + static DISPLAY_ATTR(mirror, S_IRUGO|S_IWUSR, 253 301 display_mirror_show, display_mirror_store); 254 - static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR, 302 + static DISPLAY_ATTR(wss, S_IRUGO|S_IWUSR, 255 303 display_wss_show, display_wss_store); 256 304 257 - static const struct attribute *display_sysfs_attrs[] = { 258 - &dev_attr_display_name.attr, 259 - &dev_attr_enabled.attr, 260 - &dev_attr_tear_elim.attr, 261 - &dev_attr_timings.attr, 262 - &dev_attr_rotate.attr, 263 - &dev_attr_mirror.attr, 264 - &dev_attr_wss.attr, 305 + static struct attribute *display_sysfs_attrs[] = { 306 + &display_attr_name.attr, 307 + &display_attr_display_name.attr, 308 + &display_attr_enabled.attr, 309 + &display_attr_tear_elim.attr, 310 + &display_attr_timings.attr, 311 + &display_attr_rotate.attr, 312 + &display_attr_mirror.attr, 313 + &display_attr_wss.attr, 265 314 NULL 315 + }; 316 + 317 + static ssize_t display_attr_show(struct kobject *kobj, struct attribute *attr, 318 + char *buf) 319 + { 320 + struct omap_dss_device *dssdev; 321 + struct display_attribute *display_attr; 322 + 323 + dssdev = container_of(kobj, struct omap_dss_device, kobj); 324 + display_attr = container_of(attr, struct display_attribute, attr); 325 + 326 + if (!display_attr->show) 327 + return -ENOENT; 328 + 329 + return display_attr->show(dssdev, buf); 330 + } 331 + 332 + static ssize_t display_attr_store(struct kobject *kobj, struct attribute *attr, 333 + const char *buf, size_t size) 334 + { 335 + struct omap_dss_device *dssdev; 336 + struct display_attribute *display_attr; 337 + 338 + dssdev = container_of(kobj, struct omap_dss_device, kobj); 339 + display_attr = container_of(attr, struct display_attribute, attr); 340 + 341 + if (!display_attr->store) 342 + return -ENOENT; 343 + 344 + return display_attr->store(dssdev, buf, size); 345 + } 346 + 347 + static const struct sysfs_ops display_sysfs_ops = { 348 + .show = display_attr_show, 349 + .store = display_attr_store, 350 + }; 351 + 352 + static struct kobj_type display_ktype = { 353 + .sysfs_ops = &display_sysfs_ops, 354 + .default_attrs = display_sysfs_attrs, 266 355 }; 267 356 268 357 int display_init_sysfs(struct platform_device *pdev) ··· 323 308 int r; 324 309 325 310 for_each_dss_dev(dssdev) { 326 - struct kobject *kobj = &dssdev->dev->kobj; 327 - 328 - r = sysfs_create_files(kobj, display_sysfs_attrs); 311 + r = kobject_init_and_add(&dssdev->kobj, &display_ktype, 312 + &pdev->dev.kobj, dssdev->alias); 329 313 if (r) { 330 314 DSSERR("failed to create sysfs files\n"); 331 - goto err; 332 - } 333 - 334 - r = sysfs_create_link(&pdev->dev.kobj, kobj, dssdev->alias); 335 - if (r) { 336 - sysfs_remove_files(kobj, display_sysfs_attrs); 337 - 338 - DSSERR("failed to create sysfs display link\n"); 315 + omap_dss_put_device(dssdev); 339 316 goto err; 340 317 } 341 318 } ··· 345 338 struct omap_dss_device *dssdev = NULL; 346 339 347 340 for_each_dss_dev(dssdev) { 348 - sysfs_remove_link(&pdev->dev.kobj, dssdev->alias); 349 - sysfs_remove_files(&dssdev->dev->kobj, 350 - display_sysfs_attrs); 341 + if (kobject_name(&dssdev->kobj) == NULL) 342 + continue; 343 + 344 + kobject_del(&dssdev->kobj); 345 + kobject_put(&dssdev->kobj); 346 + 347 + memset(&dssdev->kobj, 0, sizeof(dssdev->kobj)); 351 348 } 352 349 }
+1
include/video/omapdss.h
··· 689 689 }; 690 690 691 691 struct omap_dss_device { 692 + struct kobject kobj; 692 693 struct device *dev; 693 694 694 695 struct module *owner;