diff mbox

tty: Fallback to use dynamic major number

Message ID 1389848602-30985-1-git-send-email-tushar.behera@linaro.org
State New
Headers show

Commit Message

Tushar Behera Jan. 16, 2014, 5:03 a.m. UTC
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 <tushar.behera@linaro.org>
---
Hi Greg,

This is my second attempt at getting this fixed. Let me know if you are
okay with this.

Initial approach to fix this problem was by forcing samsung-uart driver
to use dynamic major number, but it was rejected [1] because of possible
user-space breakage. Current approach falls back to dynamic major
number as a fallback in case of failure.
[1] https://lkml.org/lkml/2013/12/27/2

 drivers/tty/tty_io.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

Comments

Tushar Behera Jan. 17, 2014, 9:24 a.m. UTC | #1
On 16 January 2014 23:45, Mark Brown <broonie@kernel.org> wrote:
> On Thu, Jan 16, 2014 at 09:22:40AM -0800, Greg KH wrote:
>> On Thu, Jan 16, 2014 at 05:08:14PM +0000, Mark Brown wrote:
>
>> > No, the issue is happening because the drivers are registering things
>> > at module load time and not at device instantiation time.
>
>> That's a driver bug that could easily be fixed, instead of hacking up
>> the tty core :)
>
> Looking at the code it really, really looked intentional - in any case
> that seems worthwhile, Tushar this looks like a way forwards?
>

Ok. I will prepare a patch with this approach for amba-pl011 and
samsung-uart drivers. If that works well, I will extend that to other
serial drivers.

Thanks to both of you for your time.
diff mbox

Patch

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index c74a00a..0c692be 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3341,6 +3341,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 node\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);
@@ -3348,9 +3364,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;