forked from mirrors/linux
		
	driver core: Add fw_devlink kernel commandline option
fwnode_operations.add_links allows creating device links from information provided by firmware. fwnode_operations.add_links is currently implemented only by OF/devicetree code and a specific case of efi. However, there's nothing preventing ACPI or other firmware types from implementing it. The OF implementation is currently controlled by a kernel commandline parameter called of_devlink. Since this feature is generic isn't limited to OF, add a generic fw_devlink kernel commandline parameter to control this feature across firmware types. Signed-off-by: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20200222014038.180923-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									1745d299af
								
							
						
					
					
						commit
						8375e74f2b
					
				
					 3 changed files with 46 additions and 1 deletions
				
			
		| 
						 | 
					@ -1350,6 +1350,24 @@
 | 
				
			||||||
			can be changed at run time by the max_graph_depth file
 | 
								can be changed at run time by the max_graph_depth file
 | 
				
			||||||
			in the tracefs tracing directory. default: 0 (no limit)
 | 
								in the tracefs tracing directory. default: 0 (no limit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fw_devlink=	[KNL] Create device links between consumer and supplier
 | 
				
			||||||
 | 
								devices by scanning the firmware to infer the
 | 
				
			||||||
 | 
								consumer/supplier relationships. This feature is
 | 
				
			||||||
 | 
								especially useful when drivers are loaded as modules as
 | 
				
			||||||
 | 
								it ensures proper ordering of tasks like device probing
 | 
				
			||||||
 | 
								(suppliers first, then consumers), supplier boot state
 | 
				
			||||||
 | 
								clean up (only after all consumers have probed),
 | 
				
			||||||
 | 
								suspend/resume & runtime PM (consumers first, then
 | 
				
			||||||
 | 
								suppliers).
 | 
				
			||||||
 | 
								Format: { off | permissive | on | rpm }
 | 
				
			||||||
 | 
								off --	Don't create device links from firmware info.
 | 
				
			||||||
 | 
								permissive -- Create device links from firmware info
 | 
				
			||||||
 | 
									but use it only for ordering boot state clean
 | 
				
			||||||
 | 
									up (sync_state() calls).
 | 
				
			||||||
 | 
								on -- 	Create device links from firmware info and use it
 | 
				
			||||||
 | 
									to enforce probe and suspend/resume ordering.
 | 
				
			||||||
 | 
								rpm --	Like "on", but also use to order runtime PM.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gamecon.map[2|3]=
 | 
						gamecon.map[2|3]=
 | 
				
			||||||
			[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
 | 
								[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
 | 
				
			||||||
			support via parallel port (up to 5 devices per port)
 | 
								support via parallel port (up to 5 devices per port)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2332,6 +2332,31 @@ static int device_private_init(struct device *dev)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32 fw_devlink_flags;
 | 
				
			||||||
 | 
					static int __init fw_devlink_setup(char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!arg)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcmp(arg, "off") == 0) {
 | 
				
			||||||
 | 
							fw_devlink_flags = 0;
 | 
				
			||||||
 | 
						} else if (strcmp(arg, "permissive") == 0) {
 | 
				
			||||||
 | 
							fw_devlink_flags = DL_FLAG_SYNC_STATE_ONLY;
 | 
				
			||||||
 | 
						} else if (strcmp(arg, "on") == 0) {
 | 
				
			||||||
 | 
							fw_devlink_flags = DL_FLAG_AUTOPROBE_CONSUMER;
 | 
				
			||||||
 | 
						} else if (strcmp(arg, "rpm") == 0) {
 | 
				
			||||||
 | 
							fw_devlink_flags = DL_FLAG_AUTOPROBE_CONSUMER |
 | 
				
			||||||
 | 
									   DL_FLAG_PM_RUNTIME;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					early_param("fw_devlink", fw_devlink_setup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32 fw_devlink_get_flags(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return fw_devlink_flags;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * device_add - add device to device hierarchy.
 | 
					 * device_add - add device to device hierarchy.
 | 
				
			||||||
 * @dev: device.
 | 
					 * @dev: device.
 | 
				
			||||||
| 
						 | 
					@ -2480,7 +2505,7 @@ int device_add(struct device *dev)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	device_link_add_missing_supplier_links();
 | 
						device_link_add_missing_supplier_links();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fwnode_has_op(dev->fwnode, add_links)) {
 | 
						if (fw_devlink_flags && fwnode_has_op(dev->fwnode, add_links)) {
 | 
				
			||||||
		fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev);
 | 
							fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev);
 | 
				
			||||||
		if (fw_ret == -ENODEV)
 | 
							if (fw_ret == -ENODEV)
 | 
				
			||||||
			device_link_wait_for_mandatory_supplier(dev);
 | 
								device_link_wait_for_mandatory_supplier(dev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,4 +170,6 @@ struct fwnode_operations {
 | 
				
			||||||
	} while (false)
 | 
						} while (false)
 | 
				
			||||||
#define get_dev_from_fwnode(fwnode)	get_device((fwnode)->dev)
 | 
					#define get_dev_from_fwnode(fwnode)	get_device((fwnode)->dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern u32 fw_devlink_get_flags(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue