In a multi-platform scenario, the hard-coded major/minor numbers in serial drivers may conflict with each other. A typical scenario is observed with amba-pl011 and samsung-serial drivers, both of these drivers use same set of major/minor numbers. Because of this there is no serial output on Samsung boards if amba-pl011 is enabled alongwith samsung-serial driver.
The issue is fixed by adding a fallback in driver core, so that we can use dynamic major number in case device node allocation fails for hard-coded major/minor number.
Signed-off-by: Tushar Behera tushar.behera@linaro.org --- drivers/tty/tty_io.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index c74a00a..4ed35b9 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3341,6 +3341,18 @@ int tty_register_driver(struct tty_driver *driver) dev_t dev; struct device *d;
+ if (driver->major) { + dev = MKDEV(driver->major, driver->minor_start); + error = register_chrdev_region(dev, driver->num, driver->name); + /* In case of error, fall back to dynamic allocation */ + if (error < 0) + driver->major = 0; + } + + /* + * Don't replace the following check with an else to above if statement, + * as it may also be called as a fallback. + */ if (!driver->major) { error = alloc_chrdev_region(&dev, driver->minor_start, driver->num, driver->name); @@ -3348,9 +3360,6 @@ int tty_register_driver(struct tty_driver *driver) driver->major = MAJOR(dev); driver->minor_start = MINOR(dev); } - } else { - dev = MKDEV(driver->major, driver->minor_start); - error = register_chrdev_region(dev, driver->num, driver->name); } if (error < 0) goto err;