Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2338c39e authored by Manu Gautam's avatar Manu Gautam
Browse files

usb: bam: Use runtime PM APIs on BAM device for LPM



Simplify driver's handling of power management by
using its own runtimePM infrastructure instead of
invoking runtimePM APIs on parent USB controller
device.

Change-Id: Iafebc9b10d8327486b4899b520799e5e7b6629a7
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent cf0721fb
Loading
Loading
Loading
Loading
+98 −190
Original line number Diff line number Diff line
@@ -150,13 +150,10 @@ struct usb_bam_ipa_handshake_info {

	enum usb_bam_mode cur_bam_mode;
	enum usb_ctrl bam_type;
	bool lpm_wait_handshake;
	int connect_complete;
	bool lpm_wait_pipes;
	int bus_suspend;
	bool disconnected;
	bool in_lpm;
	bool pending_lpm;
	u8 prod_pipes_enabled_per_bam;

	int (*wake_cb)(void *);
@@ -192,9 +189,6 @@ static struct usb_bam_ctx_type msm_usb_bam[MAX_BAMS];
static enum usb_ctrl qdss_usb_bam_type;

static struct usb_bam_host_info host_info[MAX_BAMS];
static struct device *usb_device;
static bool probe_finished;
static bool qdss_usb_active;

static int __usb_bam_register_wake_cb(enum usb_ctrl bam_type, int idx,
				      int (*callback)(void *user),
@@ -740,20 +734,6 @@ static int disconnect_pipe(enum usb_ctrl cur_bam, u8 idx)
	return 0;
}

static bool _usb_bam_resume_core(void)
{
	log_event(1, "Resuming usb peripheral/host device\n");

	if (usb_device)
		pm_runtime_resume(usb_device);
	else {
		pr_err("%s: usb device is not initialized\n", __func__);
		return false;
	}

	return true;
}

static bool _hsic_host_bam_resume_core(void)
{
	log_event(1, "%s: enter\n", __func__);
@@ -769,44 +749,6 @@ static bool _hsic_host_bam_resume_core(void)
	return false;
}

static bool _hsic_device_bam_resume_core(void)
{
	log_event(1, "%s: enter\n", __func__);

	/* Not supported yet */
	return false;
}

static void _usb_bam_suspend_core(enum usb_ctrl bam_type, bool disconnect)
{

	log_event(1, "%s: enter bam=%s\n", __func__,
			bam_enable_strings[bam_type]);

	if (!usb_device) {
		pr_err("%s: usb device is not initialized\n", __func__);
		return;
	}

	spin_lock(&usb_bam_ipa_handshake_info_lock);
	info[bam_type].lpm_wait_handshake = false;
	info[bam_type].lpm_wait_pipes = 0;

	if (info[bam_type].pending_lpm) {
		info[bam_type].pending_lpm = 0;
		spin_unlock(&usb_bam_ipa_handshake_info_lock);
		log_event(1, "%s: Going to LPM\n", __func__);
		pm_runtime_idle(usb_device);
	} else
		spin_unlock(&usb_bam_ipa_handshake_info_lock);
}

static void _hsic_device_bam_suspend_core(void)
{
	/* Not supported yet */
	log_event(1, "%s: enter\n", __func__);
}

static void _hsic_host_bam_suspend_core(void)
{
	log_event(1, "%s: enter\n", __func__);
@@ -826,22 +768,13 @@ static void usb_bam_suspend_core(enum usb_ctrl bam_type,
	log_event(1, "%s: enter bam=%s\n", __func__,
			bam_enable_strings[bam_type]);

	switch (bam_type) {
	case CI_CTRL:
	/* TODO: This needs the correct handling for DWC3_CTRL */
	case DWC3_CTRL:
		_usb_bam_suspend_core(bam_type, disconnect);
		break;
	case HSIC_CTRL:
		if (bam_mode == USB_BAM_DEVICE)
			_hsic_device_bam_suspend_core();
		else /* USB_BAM_HOST */
			_hsic_host_bam_suspend_core();
		break;
	default:
	if ((bam_mode == USB_BAM_DEVICE) || (bam_type != HSIC_CTRL)) {
		pr_err("%s: Invalid BAM type %d\n", __func__, bam_type);
		return;
	}

	_hsic_host_bam_suspend_core();
	return;
}

static bool usb_bam_resume_core(enum usb_ctrl bam_type,
@@ -850,22 +783,12 @@ static bool usb_bam_resume_core(enum usb_ctrl bam_type,
	log_event(1, "%s: enter bam=%s\n", __func__,
			bam_enable_strings[bam_type]);

	switch (bam_type) {
	case CI_CTRL:
	/* TODO: This needs the correct handling for DWC3_CTRL */
	case DWC3_CTRL:
		return _usb_bam_resume_core();
		break;
	case HSIC_CTRL:
		if (bam_mode == USB_BAM_DEVICE)
			return _hsic_device_bam_resume_core();
		else /* USB_BAM_HOST */
			return _hsic_host_bam_resume_core();
		break;
	default:
	if ((bam_mode == USB_BAM_DEVICE) || (bam_type != HSIC_CTRL)) {
		pr_err("%s: Invalid BAM type %d\n", __func__, bam_type);
		return false;
	}

	return _hsic_host_bam_resume_core();
}

/**
@@ -910,7 +833,6 @@ static int usb_bam_disconnect_ipa_prod(
	spin_lock(&usb_bam_ipa_handshake_info_lock);
	if (bam_mode == USB_BAM_DEVICE && !is_dpl) {
		info[cur_bam].connect_complete = 0;
		info[cur_bam].lpm_wait_pipes = 1;
		info[cur_bam].disconnected = 1;
	}
	spin_unlock(&usb_bam_ipa_handshake_info_lock);
@@ -1048,16 +970,10 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
	struct usb_bam_pipe_connect *pipe_connect =
				&ctx->usb_bam_connections[idx];
	struct msm_usb_bam_platform_data *pdata;
	struct device *bam_dev = &ctx->usb_bam_pdev->dev;
	struct msm_usb_bam_platform_data *pdata = bam_dev->platform_data;
	enum usb_bam_mode cur_mode;

	if (!ctx->usb_bam_pdev) {
		pr_err("%s: usb_bam not present\n", __func__);
		return -ENODEV;
	}

	pdata = ctx->usb_bam_pdev->dev.platform_data;

	if (pipe_connect->enabled) {
		pr_warning("%s: connection %d was already established\n"
				   , __func__, idx);
@@ -1075,6 +991,10 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)

	cur_mode = pipe_connect->bam_mode;

	log_event(1, "%s: PM Runtime GET %d, count: %d\n",
			__func__, idx, get_pm_runtime_counter(bam_dev));
	pm_runtime_get_sync(bam_dev);

	spin_lock(&ctx->usb_bam_lock);
	/* Check if BAM requires RESET before connect and reset of first pipe */
	if ((pdata->reset_on_connect == true) &&
@@ -1099,6 +1019,9 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
	ret = connect_pipe(cur_bam, idx, bam_pipe_idx);
	if (ret) {
		pr_err("%s: pipe connection[%d] failure\n", __func__, idx);
		log_event(1, "%s: err, PM RT PUT %d, count: %d\n",
			__func__, idx, get_pm_runtime_counter(bam_dev));
		pm_runtime_put_sync(bam_dev);
		return ret;
	}
	log_event(1, "%s: pipe connection[%d] success\n", __func__, idx);
@@ -1228,6 +1151,10 @@ static void resume_suspended_pipes(enum usb_ctrl cur_bam)
		start_prod_transfers(pipe_connect);
		info[cur_bam].pipes_suspended--;
		info[cur_bam].pipes_resumed++;
		/* Suspend was aborted, renew pm_runtime vote */
		log_event(1, "%s: PM Runtime GET %d, count: %d\n", __func__,
			  idx, get_pm_runtime_counter(&ctx->usb_bam_pdev->dev));
		pm_runtime_get(&ctx->usb_bam_pdev->dev);
	}
}

@@ -1249,6 +1176,7 @@ static void usb_bam_finish_suspend(enum usb_ctrl cur_bam)
	struct sps_pipe *cons_pipe;
	struct usb_bam_pipe_connect *pipe_connect;
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
	struct device *bam_dev = &ctx->usb_bam_pdev->dev;

	mutex_lock(&info[cur_bam].suspend_resume_mutex);

@@ -1260,6 +1188,9 @@ static void usb_bam_finish_suspend(enum usb_ctrl cur_bam)
		log_event(1, "%s: Cable disconnected\n", __func__);
		return;
	}
	log_event(1, "%s: bam:%s RT GET: %d\n", __func__,
		  bam_enable_strings[cur_bam], get_pm_runtime_counter(bam_dev));
	pm_runtime_get(bam_dev);

	/* If resume was called don't finish this work */
	if (!info[cur_bam].bus_suspend) {
@@ -1308,6 +1239,10 @@ static void usb_bam_finish_suspend(enum usb_ctrl cur_bam)
			info[cur_bam].resume_dst_idx[idx] =
				info[cur_bam].suspend_dst_idx[idx];
			info[cur_bam].pipes_suspended++;

			log_event(1, "%s: PM Runtime PUT %d, count: %d\n",
				__func__, idx, get_pm_runtime_counter(bam_dev));
			pm_runtime_put(&ctx->usb_bam_pdev->dev);
		} else {
			log_event(1, "%s: Pipe is not empty, not going to LPM",
				 __func__);
@@ -1327,11 +1262,13 @@ static void usb_bam_finish_suspend(enum usb_ctrl cur_bam)
			ipa_rm_resource_cons[cur_bam]);
	}

	log_event(1, "%s: Starting LPM on Bus Suspend\n", __func__);

	usb_bam_suspend_core(cur_bam, USB_BAM_DEVICE, 0);
	log_event(1, "%s: Starting LPM on Bus Suspend, RT PUT:%d\n", __func__,
			get_pm_runtime_counter(bam_dev));
	/* Put to match _get at the beginning of this routine */
	pm_runtime_put_sync(bam_dev);

	mutex_unlock(&info[cur_bam].suspend_resume_mutex);

	return;

no_lpm:
@@ -1347,6 +1284,10 @@ no_lpm:
	if (info[cur_bam].cur_cons_state == IPA_RM_RESOURCE_RELEASED)
		ipa_rm_notify_completion(IPA_RM_RESOURCE_RELEASED,
				ipa_rm_resource_cons[cur_bam]);

	/* Put to match _get at the beginning of this routine */
	pm_runtime_put(bam_dev);

	mutex_unlock(&info[cur_bam].suspend_resume_mutex);
}

@@ -1807,7 +1748,6 @@ static void usb_bam_start_suspend(struct usb_bam_ipa_handshake_info *info_ptr)
	}

	spin_lock(&usb_bam_ipa_handshake_info_lock);
	info[cur_bam].lpm_wait_handshake = true;

	/* Start release handshake on the last pipe */
	if (info[cur_bam].pipes_to_suspend * 2 == ctx->pipes_enabled_per_bam) {
@@ -1831,26 +1771,33 @@ static void usb_bam_finish_resume(struct work_struct *w)
	struct usb_bam_ipa_handshake_info *info_ptr;
	struct usb_bam_pipe_connect *pipe_connect;
	struct usb_bam_ctx_type *ctx;
	struct device *bam_dev;
	u32 idx, dst_idx, suspended;

	info_ptr = container_of(w, struct usb_bam_ipa_handshake_info,
			resume_work);
	cur_bam = info_ptr->bam_type;
	ctx = &msm_usb_bam[cur_bam];
	log_event(1, "%s: enter bam=%s\n", __func__,
			bam_enable_strings[cur_bam]);
	bam_dev = &ctx->usb_bam_pdev->dev;

	log_event(1, "%s: enter bam=%s, RT GET: %d\n", __func__,
		  bam_enable_strings[cur_bam], get_pm_runtime_counter(bam_dev));

	pm_runtime_get_sync(bam_dev);

	mutex_lock(&info[cur_bam].suspend_resume_mutex);

	/* Suspend happened in the meantime */
	spin_lock(&usb_bam_ipa_handshake_info_lock);
	if (info[cur_bam].bus_suspend) {
		spin_unlock(&usb_bam_ipa_handshake_info_lock);
		log_event(1, "%s: Bus suspended, not resuming", __func__);
		log_event(1, "%s: Bus suspended, not resuming, RT PUT: %d\n",
				__func__, get_pm_runtime_counter(bam_dev));
		mutex_unlock(&info[cur_bam].suspend_resume_mutex);
		pm_runtime_put_sync(bam_dev);
		return;
	}
	info[cur_bam].pipes_to_suspend = 0;
	info[cur_bam].lpm_wait_handshake = true;

	log_event(1, "Resuming: pipes_suspended =%d",
		 info[cur_bam].pipes_suspended);
@@ -1890,6 +1837,9 @@ static void usb_bam_finish_resume(struct work_struct *w)
		start_prod_transfers(pipe_connect);
		info[cur_bam].pipes_suspended--;
		info[cur_bam].pipes_resumed++;
		log_event(1, "%s: PM Runtime GET %d, count: %d\n",
			  __func__, idx, get_pm_runtime_counter(bam_dev));
		pm_runtime_get(&ctx->usb_bam_pdev->dev);
	}

	if (info[cur_bam].pipes_resumed == ctx->pipes_enabled_per_bam) {
@@ -1903,7 +1853,10 @@ static void usb_bam_finish_resume(struct work_struct *w)

	spin_unlock(&usb_bam_ipa_handshake_info_lock);
	mutex_unlock(&info[cur_bam].suspend_resume_mutex);
	log_event(1, "%s: done", __func__);
	log_event(1, "%s: done..PM Runtime PUT %d, count: %d\n",
			  __func__, idx, get_pm_runtime_counter(bam_dev));
	/* Put to match _get at the beginning of this routine */
	pm_runtime_put(&ctx->usb_bam_pdev->dev);
}

void usb_bam_resume(enum usb_ctrl cur_bam,
@@ -2117,8 +2070,8 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
	enum usb_bam_mode cur_mode;
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
	struct usb_bam_pipe_connect *pipe_connect;
	struct msm_usb_bam_platform_data *pdata =
					ctx->usb_bam_pdev->dev.platform_data;
	struct device *bam_dev = &ctx->usb_bam_pdev->dev;
	struct msm_usb_bam_platform_data *pdata = bam_dev->platform_data;
	int ret;
	bool bam2bam, is_dpl;

@@ -2176,17 +2129,13 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
		if (ctx->pipes_enabled_per_bam == 0) {
			spin_unlock(&ctx->usb_bam_lock);
			spin_lock(&usb_bam_ipa_handshake_info_lock);
			info[cur_bam].lpm_wait_handshake = true;
			info[cur_bam].connect_complete = 0;
			info[cur_bam].disconnected = 0;
			info[cur_bam].pending_lpm = 0;
			info[cur_bam].lpm_wait_pipes = 1;
			info[cur_bam].bus_suspend = 0;
			info[cur_bam].pipes_suspended = 0;
			info[cur_bam].pipes_to_suspend = 0;
			info[cur_bam].pipes_resumed = 0;
			spin_unlock(&usb_bam_ipa_handshake_info_lock);
			usb_bam_resume_core(cur_bam, USB_BAM_DEVICE);
		} else {
			spin_unlock(&ctx->usb_bam_lock);
		}
@@ -2194,6 +2143,10 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
		pipe_connect->prod_stopped = 0;
	}

	log_event(1, "%s: PM Runtime GET %d, count: %d\n",
		  __func__, idx, get_pm_runtime_counter(bam_dev));
	pm_runtime_get_sync(bam_dev);

	 /* Check if BAM requires RESET before connect and reset first pipe */
	 spin_lock(&ctx->usb_bam_lock);
	 if (pdata->reset_on_connect && !ctx->pipes_enabled_per_bam) {
@@ -2230,7 +2183,9 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
	else
		ret = connect_pipe_sys2bam_ipa(cur_bam, idx, ipa_params);
	if (ret) {
		pr_err("%s: pipe connection failure\n", __func__);
		pr_err("%s: pipe connection failure RT PUT: %d\n", __func__,
				get_pm_runtime_counter(bam_dev));
		pm_runtime_put_sync(bam_dev);
		if (cur_mode == USB_BAM_DEVICE)
			mutex_unlock(&info[cur_bam].suspend_resume_mutex);
		return ret;
@@ -2540,6 +2495,7 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)
{
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam_type];
	struct usb_bam_pipe_connect *pipe_connect;
	struct device *bam_dev = &ctx->usb_bam_pdev->dev;
	int ret;
	struct msm_usb_bam_platform_data *pdata =
				ctx->usb_bam_pdev->dev.platform_data;
@@ -2567,6 +2523,7 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)
		ctx->pipes_enabled_per_bam -= 1;
	}
	spin_unlock(&ctx->usb_bam_lock);

	log_event(1, "%s: success disconnecting pipe %d\n", __func__, idx);

	if (pdata->reset_on_disconnect && !ctx->pipes_enabled_per_bam) {
@@ -2583,6 +2540,16 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)
		if (bam_type == CI_CTRL)
			msm_usb_irq_disable(false);
	}
	/* This function is directly called by USB Transport drivers
	 * to disconnect pipes. Drop runtime usage count here. For
	 * IPA, caller takes care of it
	 */
	if (pipe_connect->peer_bam != IPA_P_BAM) {
		log_event(1, "%s: PM Runtime PUT %d, count: %d\n",
			  __func__, idx, get_pm_runtime_counter(bam_dev));
		pm_runtime_put_sync(bam_dev);
	}

	return 0;
}

@@ -2601,10 +2568,11 @@ static bool is_ipa_handle_valid(u32 ipa_handle)
int usb_bam_disconnect_ipa(enum usb_ctrl cur_bam,
			   struct usb_bam_connect_ipa_params *ipa_params)
{
	int ret = 0;
	int ret = 0, pipes_disconncted = 0;
	u8 idx = 0;
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
	struct usb_bam_pipe_connect *pipe_connect;
	struct device *bam_dev = &ctx->usb_bam_pdev->dev;
	enum usb_bam_mode bam_mode;

	if (!is_ipa_handle_valid(ipa_params->prod_clnt_hdl) &&
@@ -2623,12 +2591,6 @@ int usb_bam_disconnect_ipa(enum usb_ctrl cur_bam,
	pipe_connect = &ctx->usb_bam_connections[idx];
	bam_mode = pipe_connect->bam_mode;

	/* Ensure USB device is not in low power mode while disconnecting */
	if (bam_mode == USB_BAM_DEVICE) {
		info[cur_bam].pending_lpm = 1;
		usb_bam_resume_core(cur_bam, bam_mode);
	}

	mutex_lock(&info[cur_bam].suspend_resume_mutex);
	/* Delay USB core to go into lpm before we finish our handshake */
	if (is_ipa_handle_valid(ipa_params->prod_clnt_hdl)) {
@@ -2636,12 +2598,14 @@ int usb_bam_disconnect_ipa(enum usb_ctrl cur_bam,
				cur_bam, bam_mode);
		if (ret)
			goto out;
		pipes_disconncted++;
	}

	if (is_ipa_handle_valid(ipa_params->cons_clnt_hdl)) {
		ret = usb_bam_disconnect_ipa_cons(ipa_params, cur_bam);
		if (ret)
			goto out;
		pipes_disconncted++;
	}

	/* Notify CONS release on the last cons pipe released */
@@ -2656,12 +2620,18 @@ int usb_bam_disconnect_ipa(enum usb_ctrl cur_bam,
	}

out:
	if (!ctx->pipes_enabled_per_bam && bam_mode == USB_BAM_DEVICE) {
		log_event(1, "%s Ended disconnect sequence\n", __func__);
		usb_bam_suspend_core(cur_bam, USB_BAM_DEVICE, 1);
	/* Pipes are connected one by one, but can get disconnected in pairs */
	while (pipes_disconncted--) {
		if (!info[cur_bam].pipes_suspended) {
			log_event(1, "%s: PM Runtime PUT %d, count: %d\n",
					__func__, pipes_disconncted,
					get_pm_runtime_counter(bam_dev));
			pm_runtime_put_sync(&ctx->usb_bam_pdev->dev);
		}
	}

	mutex_unlock(&info[cur_bam].suspend_resume_mutex);

	return ret;
}
EXPORT_SYMBOL(usb_bam_disconnect_ipa);
@@ -3166,12 +3136,15 @@ static int usb_bam_probe(struct platform_device *pdev)
		destroy_workqueue(ctx->usb_bam_wq);
		return ret;
	}
	usb_device = pdev->dev.parent;

	pm_runtime_no_callbacks(&pdev->dev);
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	spin_lock_init(&usb_bam_ipa_handshake_info_lock);
	if (ipa_is_ready())
		usb_bam_ipa_create_resources(bam_type);
	spin_lock_init(&ctx->usb_bam_lock);
	probe_finished = true;

	return ret;
}
@@ -3270,59 +3243,6 @@ int usb_bam_get_bam_type(const char *core_name)
}
EXPORT_SYMBOL(usb_bam_get_bam_type);

static bool msm_bam_device_lpm_ok(enum usb_ctrl bam_type)
{
	log_event(1, "%s: enter bam %s, wait_handshake %d , wait_pipes %d\n",
			__func__, bam_enable_strings[bam_type],
			info[bam_type].lpm_wait_handshake,
			info[bam_type].lpm_wait_pipes);

	/*
	 * There is the possibility of a race between the usb_bam_probe()
	 * function initializing the relevant spinlocks and structures, vs. the
	 * USB controller's suspend function being invoked by the pm module.
	 */
	if (!probe_finished)
		return 0;

	spin_lock(&usb_bam_ipa_handshake_info_lock);
	if (info[bam_type].lpm_wait_handshake ||
		info[bam_type].lpm_wait_pipes) {
		info[bam_type].pending_lpm = 1;
		spin_unlock(&usb_bam_ipa_handshake_info_lock);
		pr_info("%s: Scheduling LPM for later\n", __func__);
		return 0;
	} else {
		info[bam_type].pending_lpm = 0;
		info[bam_type].in_lpm = true;
		spin_unlock(&usb_bam_ipa_handshake_info_lock);
		pr_info("%s: Going to LPM now\n", __func__);
		return 1;
	}
}

void msm_bam_set_qdss_usb_active(bool is_active)
{
	pr_debug("%s: set qdss_usb_active: %d\n", __func__, is_active);
	qdss_usb_active = is_active;
}
EXPORT_SYMBOL(msm_bam_set_qdss_usb_active);

bool msm_bam_usb_lpm_ok(enum usb_ctrl bam)
{
	log_event(1, "%s: enter mode %d on %s\n",
		__func__, info[bam].cur_bam_mode, bam_enable_strings[bam]);

	if (qdss_usb_active)
		return 0;
	if (info[bam].cur_bam_mode == USB_BAM_DEVICE)
		return msm_bam_device_lpm_ok(bam);
	else /* USB_BAM_HOST */ {
		return msm_bam_host_lpm_ok(bam);
	}
}
EXPORT_SYMBOL(msm_bam_usb_lpm_ok);

/**
 * msm_bam_hsic_host_pipe_empty - Check all HSIC host BAM pipe state
 *
@@ -3383,25 +3303,13 @@ bool msm_bam_hsic_lpm_ok(void)
{
	log_event(1, "%s: enter\n", __func__);

	if (info[HSIC_CTRL].cur_bam_mode == USB_BAM_DEVICE)
		return msm_bam_device_lpm_ok(HSIC_CTRL);
	else /* USB_BAM_HOST */ {
	if (info[HSIC_CTRL].cur_bam_mode == USB_BAM_HOST)
		return msm_bam_host_lpm_ok(HSIC_CTRL);
	}
}
EXPORT_SYMBOL(msm_bam_hsic_lpm_ok);

void msm_bam_notify_lpm_resume(enum usb_ctrl bam)
{
	/*
	 * If core was resumed from lpm, just clear the
	 * pending indication, in case it is set.
	*/
	log_event(1, "%s: notifying lpm resume on %s\n",
			__func__, bam_enable_strings[bam]);
	info[bam].pending_lpm = 0;
	/* RuntimPM is used to manage device mode LPM */
	return 0;
}
EXPORT_SYMBOL(msm_bam_notify_lpm_resume);
EXPORT_SYMBOL(msm_bam_hsic_lpm_ok);

static int usb_bam_remove(struct platform_device *pdev)
{
+0 −7
Original line number Diff line number Diff line
@@ -1374,12 +1374,6 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc)
				return -EBUSY;
			}
		}

		if (!msm_bam_usb_lpm_ok(DWC3_CTRL)) {
			dev_dbg(mdwc->dev, "%s: IPA handshake not finished, will suspend when done\n",
					__func__);
			return -EBUSY;
		}
	}

	if (!mdwc->vbus_active && dwc->is_drd &&
@@ -1638,7 +1632,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc)

	atomic_set(&dwc->in_lpm, 0);

	msm_bam_notify_lpm_resume(DWC3_CTRL);
	/* disable wakeup from LPM */
	if (mdwc->pwr_event_irq) {
		disable_irq_wake(mdwc->pwr_event_irq);
+0 −8
Original line number Diff line number Diff line
@@ -504,7 +504,6 @@ static void usb_qdss_disconnect_work(struct work_struct *work)
	if (qdss->port_num >= nr_qdss_ports) {
		pr_err("%s: supporting ports#%u port_id:%u", __func__,
				nr_qdss_ports, portno);
		msm_bam_set_qdss_usb_active(false);
		return;
	}
	pr_debug("usb_qdss_disconnect_work\n");
@@ -557,7 +556,6 @@ static void usb_qdss_disconnect_work(struct work_struct *work)
				xport_to_str(dxport));
	}

	msm_bam_set_qdss_usb_active(false);
	/*
	 * Decrement usage count which was incremented
	 * before calling connect work
@@ -607,7 +605,6 @@ static void qdss_disable(struct usb_function *f)
	spin_unlock_irqrestore(&qdss->lock, flags);
	/*cancell all active xfers*/
	qdss_eps_disable(f);
	msm_bam_set_qdss_usb_active(true);
	if (!gadget_is_dwc3(qdss->cdev->gadget))
		msm_usb_irq_disable(true);
	queue_work(qdss->wq, &qdss->disconnect_w);
@@ -681,7 +678,6 @@ static void usb_qdss_connect_work(struct work_struct *work)
	if (qdss->usb_connected == 0) {
		pr_debug("%s: discard connect_work\n", __func__);
		cancel_work_sync(&qdss->disconnect_w);
		msm_bam_set_qdss_usb_active(false);
		return;
	}

@@ -759,9 +755,6 @@ static void usb_qdss_connect_work(struct work_struct *work)
		pr_err("%s: Un-supported transport: %s\n", __func__,
				xport_to_str(dxport));
	}

	msm_bam_set_qdss_usb_active(false);

}

static int qdss_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
@@ -855,7 +848,6 @@ static int qdss_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
	}
	if (qdss->usb_connected && (ch->app_conn ||
		(dxport == USB_GADGET_XPORT_HSIC))) {
		msm_bam_set_qdss_usb_active(true);
		queue_work(qdss->wq, &qdss->connect_w);
	}
	return 0;
+0 −13
Original line number Diff line number Diff line
@@ -1382,17 +1382,6 @@ static int msm_otg_suspend(struct msm_otg *motg)
	if (atomic_read(&motg->in_lpm))
		return 0;

	/*
	 * Don't allow low power mode if bam pipes are still connected.
	 * Otherwise it could lead to unclocked access when sps driver
	 * accesses USB bam registers as part of disconnecting bam pipes.
	 */
	if (!msm_bam_usb_lpm_ok(CI_CTRL)) {
		msm_otg_dbg_log_event(phy, "BAM NOT READY", 0, 0);
		pm_schedule_suspend(phy->dev, 1000);
		return -EBUSY;
	}

	motg->ui_enabled = 0;
	disable_irq(motg->irq);
lpm_start:
@@ -1726,8 +1715,6 @@ static int msm_otg_resume(struct msm_otg *motg)
		return 0;
	}

	msm_bam_notify_lpm_resume(CI_CTRL);

	if (motg->ui_enabled) {
		motg->ui_enabled = 0;
		disable_irq(motg->irq);
+10 −6
Original line number Diff line number Diff line
@@ -631,8 +631,6 @@ struct usb_ext_notification {
	void *ctxt;
};
#ifdef CONFIG_USB_BAM
bool msm_bam_usb_lpm_ok(enum usb_ctrl ctrl);
void msm_bam_notify_lpm_resume(enum usb_ctrl ctrl);
void msm_bam_set_usb_host_dev(struct device *dev);
void msm_bam_set_hsic_host_dev(struct device *dev);
void msm_bam_wait_for_usb_host_prod_granted(void);
@@ -641,10 +639,7 @@ bool msm_bam_hsic_lpm_ok(void);
void msm_bam_usb_host_notify_on_resume(void);
void msm_bam_hsic_host_notify_on_resume(void);
bool msm_bam_hsic_host_pipe_empty(void);
void msm_bam_set_qdss_usb_active(bool is_active);
#else
static inline bool msm_bam_usb_lpm_ok(enum usb_ctrl ctrl) { return true; }
static inline void msm_bam_notify_lpm_resume(enum usb_ctrl ctrl) {}
static inline void msm_bam_set_usb_host_dev(struct device *dev) {}
static inline void msm_bam_set_hsic_host_dev(struct device *dev) {}
static inline void msm_bam_wait_for_usb_host_prod_granted(void) {}
@@ -653,7 +648,6 @@ static inline bool msm_bam_hsic_lpm_ok(void) { return true; }
static inline void msm_bam_hsic_host_notify_on_resume(void) {}
static inline void msm_bam_usb_host_notify_on_resume(void) {}
static inline bool msm_bam_hsic_host_pipe_empty(void) { return true; }
static inline void msm_bam_set_qdss_usb_active(bool is_active) {}
#endif
#ifdef CONFIG_USB_CI13XXX_MSM
void msm_hw_bam_disable(bool bam_disable);
@@ -667,6 +661,16 @@ static inline void msm_usb_irq_disable(bool disable)
}
#endif

/* CONFIG_PM_RUNTIME */
#ifdef CONFIG_PM_RUNTIME
static inline int get_pm_runtime_counter(struct device *dev)
{
	return atomic_read(&dev->power.usage_count);
}
#else /* !CONFIG_PM_RUNTIME */
static inline int get_pm_runtime_counter(struct device *dev) { return -ENOSYS; }
#endif

#ifdef CONFIG_USB_DWC3_MSM
int msm_ep_config(struct usb_ep *ep);
int msm_ep_unconfig(struct usb_ep *ep);