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

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

Merge "USB: pd: Always set selfpowered bit after explicit contract"

parents 1bef9fca daeb5ac7
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -255,6 +255,7 @@ struct dwc3_msm {
	struct notifier_block	id_nb;
	struct notifier_block	eud_event_nb;
	struct notifier_block	host_restart_nb;
	struct notifier_block	self_power_nb;

	struct notifier_block	host_nb;
	bool			xhci_ss_compliance_enable;
@@ -296,6 +297,8 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
						unsigned int value);
static int dwc3_restart_usb_host_mode(struct notifier_block *nb,
					unsigned long event, void *ptr);
static int dwc3_notify_pd_status(struct notifier_block *nb,
				unsigned long event, void *ptr);

/**
 *
@@ -3041,12 +3044,19 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc, int start_idx)
	if (!IS_ERR(edev)) {
		mdwc->extcon_vbus = edev;
		mdwc->vbus_nb.notifier_call = dwc3_msm_vbus_notifier;
		mdwc->self_power_nb.notifier_call = dwc3_notify_pd_status;
		ret = extcon_register_notifier(edev, EXTCON_USB,
				&mdwc->vbus_nb);
		if (ret < 0) {
			dev_err(mdwc->dev, "failed to register notifier for USB\n");
			return ret;
		}
		ret = extcon_register_blocking_notifier(edev, EXTCON_USB,
							&mdwc->self_power_nb);
		if (ret < 0) {
			dev_err(mdwc->dev, "failed to register blocking notifier\n");
			goto err1;
		}
	}

	/*
@@ -4148,6 +4158,28 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
	return 0;
}

static int dwc3_notify_pd_status(struct notifier_block *nb,
				unsigned long event, void *ptr)
{
	struct dwc3_msm *mdwc;
	struct dwc3 *dwc;
	int ret = 0;
	union extcon_property_value val;

	mdwc = container_of(nb, struct dwc3_msm, self_power_nb);
	dwc = platform_get_drvdata(mdwc->dwc3);

	ret = extcon_get_property(mdwc->extcon_vbus, EXTCON_USB,
					EXTCON_PROP_USB_PD_CONTRACT, &val);

	if (!ret)
		dwc->gadget.self_powered = val.intval;
	else
		dwc->gadget.self_powered = 0;

	return ret;
}

/* speed: 0 - USB_SPEED_HIGH, 1 - USB_SPEED_SUPER */
static int dwc3_restart_usb_host_mode(struct notifier_block *nb,
				unsigned long event, void *ptr)
+4 −0
Original line number Diff line number Diff line
@@ -594,6 +594,10 @@ static int config_buf(struct usb_configuration *config,
	c->iConfiguration = config->iConfiguration;
	c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
	c->bMaxPower = encode_bMaxPower(speed, config);
	if (config->cdev->gadget->self_powered) {
		c->bmAttributes |= USB_CONFIG_ATT_SELFPOWER;
		c->bMaxPower = 0;
	}

	/* There may be e.g. OTG descriptors */
	if (config->descriptors) {
+26 −0
Original line number Diff line number Diff line
@@ -533,6 +533,22 @@ static inline void start_usb_peripheral(struct usbpd *pd)
	extcon_set_state_sync(pd->extcon, EXTCON_USB, 1);
}

static void notify_pd_contract_status(struct usbpd *pd)
{
	int ret = 0;
	union extcon_property_value val;

	if (!pd)
		return;

	val.intval = pd->in_explicit_contract;
	extcon_set_property(pd->extcon, EXTCON_USB,
			EXTCON_PROP_USB_PD_CONTRACT, val);
	ret = extcon_blocking_sync(pd->extcon, EXTCON_USB, 0);
	if (ret)
		usbpd_err(&pd->dev, "err(%d) while notifying pd status", ret);
}

/**
 * This API allows client driver to request for releasing SS lanes. It should
 * not be called from atomic context.
@@ -1252,6 +1268,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)

	case PE_SRC_READY:
		pd->in_explicit_contract = true;
		notify_pd_contract_status(pd);

		if (pd->vdm_tx)
			kick_sm(pd, 0);
@@ -1398,6 +1415,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)

	case PE_SNK_READY:
		pd->in_explicit_contract = true;
		notify_pd_contract_status(pd);

		if (pd->vdm_tx)
			kick_sm(pd, 0);
@@ -1433,6 +1451,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
				POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);

		pd->in_explicit_contract = false;
		notify_pd_contract_status(pd);

		/*
		 * need to update PR bit in message header so that
@@ -2012,6 +2031,7 @@ static void usbpd_sm(struct work_struct *w)
		pd->in_pr_swap = false;
		pd->pd_connected = false;
		pd->in_explicit_contract = false;
		notify_pd_contract_status(pd);
		pd->hard_reset_recvd = false;
		pd->caps_count = 0;
		pd->hard_reset_count = 0;
@@ -2095,6 +2115,7 @@ static void usbpd_sm(struct work_struct *w)
				POWER_SUPPLY_PROP_PR_SWAP, &val);

		pd->in_explicit_contract = false;
		notify_pd_contract_status(pd);
		pd->selected_pdo = pd->requested_pdo = 0;
		pd->rdo = 0;
		rx_msg_cleanup(pd);
@@ -2318,6 +2339,7 @@ static void usbpd_sm(struct work_struct *w)

		pd_send_hard_reset(pd);
		pd->in_explicit_contract = false;
		notify_pd_contract_status(pd);
		pd->rdo = 0;
		rx_msg_cleanup(pd);
		reset_vdm_state(pd);
@@ -2768,6 +2790,7 @@ static void usbpd_sm(struct work_struct *w)

		pd_send_hard_reset(pd);
		pd->in_explicit_contract = false;
		notify_pd_contract_status(pd);
		pd->selected_pdo = pd->requested_pdo = 0;
		pd->rdo = 0;
		reset_vdm_state(pd);
@@ -2799,6 +2822,7 @@ static void usbpd_sm(struct work_struct *w)
		power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_PR_SWAP, &val);
		pd->in_explicit_contract = false;
		notify_pd_contract_status(pd);

		if (pd->vbus_enabled) {
			regulator_disable(pd->vbus);
@@ -4005,6 +4029,8 @@ struct usbpd *usbpd_create(struct device *parent)
	/* Support reporting polarity and speed via properties */
	extcon_set_property_capability(pd->extcon, EXTCON_USB,
			EXTCON_PROP_USB_TYPEC_POLARITY);
	extcon_set_property_capability(pd->extcon, EXTCON_USB,
			EXTCON_PROP_USB_PD_CONTRACT);
	extcon_set_property_capability(pd->extcon, EXTCON_USB,
			EXTCON_PROP_USB_SS);
	extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST,
+6 −1
Original line number Diff line number Diff line
@@ -113,14 +113,19 @@
 * @type:       integer (intval)
 * @value:      0 (USB/USB2) or 1 (USB3)
 * @default:    0 (USB/USB2)
 * -EXTCON_PROP_USB_PD_CONTRACT
 * @type:	integer (intval)
 * @value:	0 (bus powered) or 1 (self powered)
 * @default:	0 (bus powered)
 *
 */
#define EXTCON_PROP_USB_VBUS		0
#define EXTCON_PROP_USB_TYPEC_POLARITY	1
#define EXTCON_PROP_USB_SS		2
#define EXTCON_PROP_USB_PD_CONTRACT	3

#define EXTCON_PROP_USB_MIN		0
#define EXTCON_PROP_USB_MAX		2
#define EXTCON_PROP_USB_MAX		3
#define EXTCON_PROP_USB_CNT	(EXTCON_PROP_USB_MAX - EXTCON_PROP_USB_MIN + 1)

/* Properties of EXTCON_TYPE_CHG. */
+1 −0
Original line number Diff line number Diff line
@@ -539,6 +539,7 @@ struct usb_gadget {
	u32				extra_buf_alloc;
	bool				l1_supported;
	bool				is_chipidea;
	bool				self_powered;
};
#define work_to_gadget(w)	(container_of((w), struct usb_gadget, work))