mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	greybus: svc: reconfig APBridgeA-Switch link to handle required load
SW-4894, SW-4389, and share a common root cause, namely that the power-on reset configuration of the APBridgeA-Switch link of PWM Gear 1, 1 Lane, Slow Auto, is insufficient to handle some required traffic loads, such as 3 audio streams plus boot-over-UniPro or 4 audio streams. The correct long-term solution is to implement a UniPro Power Mode Manager as in that considers the demands placed on the network, and adjusts power modes accordingly. The present commit implements a short-term, brute-force hack to allow continued system testing: - Upon receiving an SVC HELLO request, schedule deferred work to reconfigure the APB1-Switch link to PWM G2, 1 lane, Slow Auto - When the Camera driver transitions a White Camera module from active to inactive, return the APB1-Switch link to PWM G2, 1 lane, Slow Auto The Camera driver already steps up the APBridgeA-Camera link speed while a camera module is active, which affords sufficient margin for simultaneous audio and hotplug activity, and the Camera driver already steps down the link speed thereafter: the change made by the present patch is simply to tweak the stepped-down power mode to match the new baseline configuration. Signed-off-by: Mitchell Tasman <tasman@leaflabs.com> Tested-by: Mark Greer <mgreer@animalcreek.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
		
							parent
							
								
									3e29bcf4b1
								
							
						
					
					
						commit
						ee2f2074fd
					
				
					 2 changed files with 37 additions and 3 deletions
				
			
		| 
						 | 
					@ -131,9 +131,9 @@ static int gb_camera_set_intf_power_mode(struct gb_camera *gcam, u8 intf_id,
 | 
				
			||||||
		ret = gb_svc_intf_set_power_mode(svc, intf_id,
 | 
							ret = gb_svc_intf_set_power_mode(svc, intf_id,
 | 
				
			||||||
						 GB_SVC_UNIPRO_HS_SERIES_A,
 | 
											 GB_SVC_UNIPRO_HS_SERIES_A,
 | 
				
			||||||
						 GB_SVC_UNIPRO_SLOW_AUTO_MODE,
 | 
											 GB_SVC_UNIPRO_SLOW_AUTO_MODE,
 | 
				
			||||||
						 1, 2,
 | 
											 2, 1,
 | 
				
			||||||
						 GB_SVC_UNIPRO_SLOW_AUTO_MODE,
 | 
											 GB_SVC_UNIPRO_SLOW_AUTO_MODE,
 | 
				
			||||||
						 1, 2,
 | 
											 2, 1,
 | 
				
			||||||
						 0, 0);
 | 
											 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,8 @@ struct gb_svc_deferred_request {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gb_svc_queue_deferred_request(struct gb_operation *operation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t endo_id_show(struct device *dev,
 | 
					static ssize_t endo_id_show(struct device *dev,
 | 
				
			||||||
			struct device_attribute *attr, char *buf)
 | 
								struct device_attribute *attr, char *buf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -695,7 +697,7 @@ static int gb_svc_hello(struct gb_operation *op)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gb_svc_debugfs_init(svc);
 | 
						gb_svc_debugfs_init(svc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return gb_svc_queue_deferred_request(op);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct gb_interface *gb_svc_interface_lookup(struct gb_svc *svc,
 | 
					static struct gb_interface *gb_svc_interface_lookup(struct gb_svc *svc,
 | 
				
			||||||
| 
						 | 
					@ -754,6 +756,35 @@ static void gb_svc_intf_reenable(struct gb_svc *svc, struct gb_interface *intf)
 | 
				
			||||||
	mutex_unlock(&intf->mutex);
 | 
						mutex_unlock(&intf->mutex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gb_svc_process_hello_deferred(struct gb_operation *operation)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gb_connection *connection = operation->connection;
 | 
				
			||||||
 | 
						struct gb_svc *svc = gb_connection_get_data(connection);
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * XXX This is a hack/work-around to reconfigure the APBridgeA-Switch
 | 
				
			||||||
 | 
						 * link to PWM G2, 1 Lane, Slow Auto, so that it has sufficient
 | 
				
			||||||
 | 
						 * bandwidth for 3 audio streams plus boot-over-UniPro of a hot-plugged
 | 
				
			||||||
 | 
						 * module.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * The code should be removed once SW-2217, Heuristic for UniPro
 | 
				
			||||||
 | 
						 * Power Mode Changes is resolved.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ret = gb_svc_intf_set_power_mode(svc, svc->ap_intf_id,
 | 
				
			||||||
 | 
										GB_SVC_UNIPRO_HS_SERIES_A,
 | 
				
			||||||
 | 
										GB_SVC_UNIPRO_SLOW_AUTO_MODE,
 | 
				
			||||||
 | 
										2, 1,
 | 
				
			||||||
 | 
										GB_SVC_UNIPRO_SLOW_AUTO_MODE,
 | 
				
			||||||
 | 
										2, 1,
 | 
				
			||||||
 | 
										0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							dev_warn(&svc->dev,
 | 
				
			||||||
 | 
								"power mode change failed on AP to switch link: %d\n",
 | 
				
			||||||
 | 
								ret);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
 | 
					static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct gb_svc_intf_hotplug_request *request;
 | 
						struct gb_svc_intf_hotplug_request *request;
 | 
				
			||||||
| 
						 | 
					@ -963,6 +994,9 @@ static void gb_svc_process_deferred_request(struct work_struct *work)
 | 
				
			||||||
	type = operation->request->header->type;
 | 
						type = operation->request->header->type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (type) {
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case GB_SVC_TYPE_SVC_HELLO:
 | 
				
			||||||
 | 
							gb_svc_process_hello_deferred(operation);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case GB_SVC_TYPE_INTF_HOTPLUG:
 | 
						case GB_SVC_TYPE_INTF_HOTPLUG:
 | 
				
			||||||
		gb_svc_process_intf_hotplug(operation);
 | 
							gb_svc_process_intf_hotplug(operation);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue