@@ -2429,28 +2429,34 @@ static void set_user_specified(struct console_cmdline *c, bool user_specified)
24292429 console_set_on_cmdline = 1 ;
24302430}
24312431
2432- static int __add_preferred_console (const char * name , const short idx , char * options ,
2432+ static int __add_preferred_console (const char * name , const short idx ,
2433+ const char * devname , char * options ,
24332434 char * brl_options , bool user_specified )
24342435{
24352436 struct console_cmdline * c ;
24362437 int i ;
24372438
2439+ if (!name && !devname )
2440+ return - EINVAL ;
2441+
24382442 /*
24392443 * We use a signed short index for struct console for device drivers to
24402444 * indicate a not yet assigned index or port. However, a negative index
2441- * value is not valid for preferred console.
2445+ * value is not valid when the console name and index are defined on
2446+ * the command line.
24422447 */
2443- if (idx < 0 )
2448+ if (name && idx < 0 )
24442449 return - EINVAL ;
24452450
24462451 /*
24472452 * See if this tty is not yet registered, and
24482453 * if we have a slot free.
24492454 */
24502455 for (i = 0 , c = console_cmdline ;
2451- i < MAX_CMDLINECONSOLES && c -> name [0 ];
2456+ i < MAX_CMDLINECONSOLES && ( c -> name [0 ] || c -> devname [ 0 ]) ;
24522457 i ++ , c ++ ) {
2453- if (strcmp (c -> name , name ) == 0 && c -> index == idx ) {
2458+ if ((name && strcmp (c -> name , name ) == 0 && c -> index == idx ) ||
2459+ (devname && strcmp (c -> devname , devname ) == 0 )) {
24542460 if (!brl_options )
24552461 preferred_console = i ;
24562462 set_user_specified (c , user_specified );
@@ -2461,7 +2467,10 @@ static int __add_preferred_console(const char *name, const short idx, char *opti
24612467 return - E2BIG ;
24622468 if (!brl_options )
24632469 preferred_console = i ;
2464- strscpy (c -> name , name , sizeof (c -> name ));
2470+ if (name )
2471+ strscpy (c -> name , name );
2472+ if (devname )
2473+ strscpy (c -> devname , devname );
24652474 c -> options = options ;
24662475 set_user_specified (c , user_specified );
24672476 braille_set_options (c , brl_options );
@@ -2486,8 +2495,13 @@ __setup("console_msg_format=", console_msg_format_setup);
24862495 */
24872496static int __init console_setup (char * str )
24882497{
2489- char buf [sizeof (console_cmdline [0 ].name ) + 4 ]; /* 4 for "ttyS" */
2490- char * s , * options , * brl_options = NULL ;
2498+ static_assert (sizeof (console_cmdline [0 ].devname ) >= sizeof (console_cmdline [0 ].name ) + 4 );
2499+ char buf [sizeof (console_cmdline [0 ].devname )];
2500+ char * brl_options = NULL ;
2501+ char * ttyname = NULL ;
2502+ char * devname = NULL ;
2503+ char * options ;
2504+ char * s ;
24912505 int idx ;
24922506
24932507 /*
@@ -2496,17 +2510,23 @@ static int __init console_setup(char *str)
24962510 * for exactly this purpose.
24972511 */
24982512 if (str [0 ] == 0 || strcmp (str , "null" ) == 0 ) {
2499- __add_preferred_console ("ttynull" , 0 , NULL , NULL , true);
2513+ __add_preferred_console ("ttynull" , 0 , NULL , NULL , NULL , true);
25002514 return 1 ;
25012515 }
25022516
25032517 if (_braille_console_setup (& str , & brl_options ))
25042518 return 1 ;
25052519
2520+ /* For a DEVNAME:0.0 style console the character device is unknown early */
2521+ if (strchr (str , ':' ))
2522+ devname = buf ;
2523+ else
2524+ ttyname = buf ;
2525+
25062526 /*
25072527 * Decode str into name, index, options.
25082528 */
2509- if (isdigit (str [0 ]))
2529+ if (ttyname && isdigit (str [0 ]))
25102530 scnprintf (buf , sizeof (buf ), "ttyS%s" , str );
25112531 else
25122532 strscpy (buf , str );
@@ -2523,12 +2543,18 @@ static int __init console_setup(char *str)
25232543#endif
25242544
25252545 for (s = buf ; * s ; s ++ )
2526- if (isdigit (* s ) || * s == ',' )
2546+ if (( ttyname && isdigit (* s ) ) || * s == ',' )
25272547 break ;
2528- idx = simple_strtoul (s , NULL , 10 );
2548+
2549+ /* @idx will get defined when devname matches. */
2550+ if (devname )
2551+ idx = -1 ;
2552+ else
2553+ idx = simple_strtoul (s , NULL , 10 );
2554+
25292555 * s = 0 ;
25302556
2531- __add_preferred_console (buf , idx , options , brl_options , true);
2557+ __add_preferred_console (ttyname , idx , devname , options , brl_options , true);
25322558 return 1 ;
25332559}
25342560__setup ("console=" , console_setup );
@@ -2548,7 +2574,51 @@ __setup("console=", console_setup);
25482574 */
25492575int add_preferred_console (const char * name , const short idx , char * options )
25502576{
2551- return __add_preferred_console (name , idx , options , NULL , false);
2577+ return __add_preferred_console (name , idx , NULL , options , NULL , false);
2578+ }
2579+
2580+ /**
2581+ * match_devname_and_update_preferred_console - Update a preferred console
2582+ * when matching devname is found.
2583+ * @devname: DEVNAME:0.0 style device name
2584+ * @name: Name of the corresponding console driver, e.g. "ttyS"
2585+ * @idx: Console index, e.g. port number.
2586+ *
2587+ * The function checks whether a device with the given @devname is
2588+ * preferred via the console=DEVNAME:0.0 command line option.
2589+ * It fills the missing console driver name and console index
2590+ * so that a later register_console() call could find (match)
2591+ * and enable this device.
2592+ *
2593+ * It might be used when a driver subsystem initializes particular
2594+ * devices with already known DEVNAME:0.0 style names. And it
2595+ * could predict which console driver name and index this device
2596+ * would later get associated with.
2597+ *
2598+ * Return: 0 on success, negative error code on failure.
2599+ */
2600+ int match_devname_and_update_preferred_console (const char * devname ,
2601+ const char * name ,
2602+ const short idx )
2603+ {
2604+ struct console_cmdline * c = console_cmdline ;
2605+ int i ;
2606+
2607+ if (!devname || !strlen (devname ) || !name || !strlen (name ) || idx < 0 )
2608+ return - EINVAL ;
2609+
2610+ for (i = 0 ; i < MAX_CMDLINECONSOLES && (c -> name [0 ] || c -> devname [0 ]);
2611+ i ++ , c ++ ) {
2612+ if (!strcmp (devname , c -> devname )) {
2613+ pr_info ("associate the preferred console \"%s\" with \"%s%d\"\n" ,
2614+ devname , name , idx );
2615+ strscpy (c -> name , name );
2616+ c -> index = idx ;
2617+ return 0 ;
2618+ }
2619+ }
2620+
2621+ return - ENOENT ;
25522622}
25532623
25542624bool console_suspend_enabled = true;
@@ -3318,8 +3388,11 @@ static int try_enable_preferred_console(struct console *newcon,
33183388 int i , err ;
33193389
33203390 for (i = 0 , c = console_cmdline ;
3321- i < MAX_CMDLINECONSOLES && c -> name [0 ];
3391+ i < MAX_CMDLINECONSOLES && ( c -> name [0 ] || c -> devname [ 0 ]) ;
33223392 i ++ , c ++ ) {
3393+ /* Console not yet initialized? */
3394+ if (!c -> name [0 ])
3395+ continue ;
33233396 if (c -> user_specified != user_specified )
33243397 continue ;
33253398 if (!newcon -> match ||
0 commit comments