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

Commit 2882823d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: dwc3: dwc3-msm: Handle floating charger PMI notification properly"

parents 2792bdfe d6bae057
Loading
Loading
Loading
Loading
+54 −13
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@
#include "debug.h"
#include "xhci.h"

#define SDP_CONNETION_CHECK_TIME 10000 /* in ms */

/* time out to wait for USB cable status notification (in ms)*/
#define SM_INIT_TIMEOUT 30000

@@ -262,6 +264,7 @@ struct dwc3_msm {
	int pm_qos_latency;
	struct pm_qos_request pm_qos_req_dma;
	struct delayed_work perf_vote_work;
	struct delayed_work sdp_check;
};

#define USB_HSPHY_3P3_VOL_MIN		3050000 /* uV */
@@ -2818,6 +2821,25 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
	return NOTIFY_DONE;
}


static void check_for_sdp_connection(struct work_struct *w)
{
	struct dwc3_msm *mdwc =
		container_of(w, struct dwc3_msm, sdp_check.work);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	if (!mdwc->vbus_active)
		return;

	/* floating D+/D- lines detected */
	if (dwc->gadget.state < USB_STATE_DEFAULT &&
		dwc3_gadget_get_link_state(dwc) != DWC3_LINK_STATE_CMPLY) {
		mdwc->vbus_active = 0;
		dbg_event(0xFF, "Q RW SPD CHK", mdwc->vbus_active);
		queue_work(mdwc->dwc3_wq, &mdwc->resume_work);
	}
}

static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
	unsigned long event, void *ptr)
{
@@ -3104,6 +3126,7 @@ static int dwc3_msm_probe(struct platform_device *pdev)
	INIT_WORK(&mdwc->vbus_draw_work, dwc3_msm_vbus_draw_work);
	INIT_DELAYED_WORK(&mdwc->sm_work, dwc3_otg_sm_work);
	INIT_DELAYED_WORK(&mdwc->perf_vote_work, msm_dwc3_perf_vote_work);
	INIT_DELAYED_WORK(&mdwc->sdp_check, check_for_sdp_connection);

	mdwc->dwc3_wq = alloc_ordered_workqueue("dwc3_wq", 0);
	if (!mdwc->dwc3_wq) {
@@ -3859,34 +3882,46 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
	return 0;
}

static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA)
static int get_psy_type(struct dwc3_msm *mdwc)
{
	union power_supply_propval pval = {0};
	int ret;

	if (mdwc->charging_disabled)
		return 0;

	if (mdwc->max_power == mA)
		return 0;
		return -EINVAL;

	if (!mdwc->usb_psy) {
		mdwc->usb_psy = power_supply_get_by_name("usb");
		if (!mdwc->usb_psy) {
			dev_warn(mdwc->dev, "Could not get usb power_supply\n");
			dev_err(mdwc->dev, "Could not get usb psy\n");
			return -ENODEV;
		}
	}

	power_supply_get_property(mdwc->usb_psy,
			POWER_SUPPLY_PROP_REAL_TYPE, &pval);
	if (pval.intval != POWER_SUPPLY_TYPE_USB)
	power_supply_get_property(mdwc->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE,
			&pval);

	return pval.intval;
}

static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA)
{
	union power_supply_propval pval = {0};
	int ret, psy_type;

	if (mdwc->max_power == mA)
		return 0;

	psy_type = get_psy_type(mdwc);
	if (psy_type == POWER_SUPPLY_TYPE_USB) {
		dev_info(mdwc->dev, "Avail curr from USB = %u\n", mA);

		/* Set max current limit in uA */
		pval.intval = 1000 * mA;
	} else if (psy_type == POWER_SUPPLY_TYPE_USB_FLOAT) {
		pval.intval = -ETIMEDOUT;
	} else {
		return 0;
	}

	ret = power_supply_set_property(mdwc->usb_psy,
				POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
	if (ret) {
@@ -3957,6 +3992,10 @@ static void dwc3_otg_sm_work(struct work_struct *w)
			work = 1;
		} else if (test_bit(B_SESS_VLD, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "b_sess_vld\n");
			if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_FLOAT)
				queue_delayed_work(mdwc->dwc3_wq,
						&mdwc->sdp_check,
				msecs_to_jiffies(SDP_CONNETION_CHECK_TIME));
			/*
			 * Increment pm usage count upon cable connect. Count
			 * is decremented in OTG_STATE_B_PERIPHERAL state on
@@ -3979,6 +4018,7 @@ static void dwc3_otg_sm_work(struct work_struct *w)
				!test_bit(ID, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "!id || !bsv\n");
			mdwc->otg_state = OTG_STATE_B_IDLE;
			cancel_delayed_work_sync(&mdwc->sdp_check);
			dwc3_otg_start_peripheral(mdwc, 0);
			/*
			 * Decrement pm usage count upon cable disconnect
@@ -4011,6 +4051,7 @@ static void dwc3_otg_sm_work(struct work_struct *w)
		if (!test_bit(B_SESS_VLD, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "BSUSP: !bsv\n");
			mdwc->otg_state = OTG_STATE_B_IDLE;
			cancel_delayed_work_sync(&mdwc->sdp_check);
			dwc3_otg_start_peripheral(mdwc, 0);
		} else if (!test_bit(B_SUSPEND, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "BSUSP !susp\n");
+1 −0
Original line number Diff line number Diff line
@@ -926,6 +926,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)

			if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
				pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP ||
				pd->psy_type == POWER_SUPPLY_TYPE_USB_FLOAT ||
				usb_compliance_mode)
				start_usb_peripheral(pd);
		}