From: Tushar Behera <[email protected]>

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-uart drivers, both of these
drivers use same set of major/minor numbers. If both of these drivers
are enabled, probe of samsung-uart driver fails because the desired
node is busy.

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 <[email protected]>
[cernekee: fix checkpatch warnings]
Signed-off-by: Kevin Cernekee <[email protected]>
---
 drivers/tty/tty_io.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 0508a1d..a6d4d9a 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3365,6 +3365,22 @@ 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) {
+                       pr_warn("Default device node (%d:%d) for %s is busy, 
using dynamic major number\n",
+                               driver->major, driver->minor_start,
+                               driver->name);
+                       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);
@@ -3372,9 +3388,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;
-- 
2.1.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to