diff options
-rw-r--r-- | drivers/tty/tty_io.c | 24 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 2 |
2 files changed, 17 insertions, 9 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index c37a215177c0..02785d844354 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -3152,9 +3152,12 @@ static int tty_cdev_add(struct tty_driver *driver, dev_t dev, | |||
3152 | unsigned int index, unsigned int count) | 3152 | unsigned int index, unsigned int count) |
3153 | { | 3153 | { |
3154 | /* init here, since reused cdevs cause crashes */ | 3154 | /* init here, since reused cdevs cause crashes */ |
3155 | cdev_init(&driver->cdevs[index], &tty_fops); | 3155 | driver->cdevs[index] = cdev_alloc(); |
3156 | driver->cdevs[index].owner = driver->owner; | 3156 | if (!driver->cdevs[index]) |
3157 | return cdev_add(&driver->cdevs[index], dev, count); | 3157 | return -ENOMEM; |
3158 | cdev_init(driver->cdevs[index], &tty_fops); | ||
3159 | driver->cdevs[index]->owner = driver->owner; | ||
3160 | return cdev_add(driver->cdevs[index], dev, count); | ||
3158 | } | 3161 | } |
3159 | 3162 | ||
3160 | /** | 3163 | /** |
@@ -3260,8 +3263,10 @@ struct device *tty_register_device_attr(struct tty_driver *driver, | |||
3260 | 3263 | ||
3261 | error: | 3264 | error: |
3262 | put_device(dev); | 3265 | put_device(dev); |
3263 | if (cdev) | 3266 | if (cdev) { |
3264 | cdev_del(&driver->cdevs[index]); | 3267 | cdev_del(driver->cdevs[index]); |
3268 | driver->cdevs[index] = NULL; | ||
3269 | } | ||
3265 | return ERR_PTR(retval); | 3270 | return ERR_PTR(retval); |
3266 | } | 3271 | } |
3267 | EXPORT_SYMBOL_GPL(tty_register_device_attr); | 3272 | EXPORT_SYMBOL_GPL(tty_register_device_attr); |
@@ -3281,8 +3286,10 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
3281 | { | 3286 | { |
3282 | device_destroy(tty_class, | 3287 | device_destroy(tty_class, |
3283 | MKDEV(driver->major, driver->minor_start) + index); | 3288 | MKDEV(driver->major, driver->minor_start) + index); |
3284 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) | 3289 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { |
3285 | cdev_del(&driver->cdevs[index]); | 3290 | cdev_del(driver->cdevs[index]); |
3291 | driver->cdevs[index] = NULL; | ||
3292 | } | ||
3286 | } | 3293 | } |
3287 | EXPORT_SYMBOL(tty_unregister_device); | 3294 | EXPORT_SYMBOL(tty_unregister_device); |
3288 | 3295 | ||
@@ -3347,6 +3354,7 @@ err_free_all: | |||
3347 | kfree(driver->ports); | 3354 | kfree(driver->ports); |
3348 | kfree(driver->ttys); | 3355 | kfree(driver->ttys); |
3349 | kfree(driver->termios); | 3356 | kfree(driver->termios); |
3357 | kfree(driver->cdevs); | ||
3350 | kfree(driver); | 3358 | kfree(driver); |
3351 | return ERR_PTR(err); | 3359 | return ERR_PTR(err); |
3352 | } | 3360 | } |
@@ -3375,7 +3383,7 @@ static void destruct_tty_driver(struct kref *kref) | |||
3375 | } | 3383 | } |
3376 | proc_tty_unregister_driver(driver); | 3384 | proc_tty_unregister_driver(driver); |
3377 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) | 3385 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) |
3378 | cdev_del(&driver->cdevs[0]); | 3386 | cdev_del(driver->cdevs[0]); |
3379 | } | 3387 | } |
3380 | kfree(driver->cdevs); | 3388 | kfree(driver->cdevs); |
3381 | kfree(driver->ports); | 3389 | kfree(driver->ports); |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 92e337c18839..161052477f77 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
@@ -296,7 +296,7 @@ struct tty_operations { | |||
296 | struct tty_driver { | 296 | struct tty_driver { |
297 | int magic; /* magic number for this structure */ | 297 | int magic; /* magic number for this structure */ |
298 | struct kref kref; /* Reference management */ | 298 | struct kref kref; /* Reference management */ |
299 | struct cdev *cdevs; | 299 | struct cdev **cdevs; |
300 | struct module *owner; | 300 | struct module *owner; |
301 | const char *driver_name; | 301 | const char *driver_name; |
302 | const char *name; | 302 | const char *name; |