linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH resend 0/5] phy-sun4i-usb: Add support for phy_set_mode
@ 2016-09-07 20:20 Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 1/5] phy-sun4i-usb: Use bool where appropriate Hans de Goede
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Hans de Goede @ 2016-09-07 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kishon,

There was some discussion about the 6th patch in this set, so I've
dropped this for now (needs a universal dt binding), but the other
5 are still useful without this patch and are ready for merging.

Can you please add these 5 to your next branch ?

Thanks & Regards,

Hans

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH resend 1/5] phy-sun4i-usb: Use bool where appropriate
  2016-09-07 20:20 [PATCH resend 0/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
@ 2016-09-07 20:20 ` Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 2/5] phy-sun4i-usb: Refactor forced session ending Hans de Goede
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Hans de Goede @ 2016-09-07 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

We're using bool as true/false type in most places in phy-sun4i-usb.c
for consistency fixup the remaining uses of ints which are ever only
0 or 1 to be bools too.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-No changes
Changes in v3:
-No changes
---
 drivers/phy/phy-sun4i-usb.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index fcf4d95e..1cb84a8 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -445,7 +445,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
 	struct sun4i_usb_phy_data *data =
 		container_of(work, struct sun4i_usb_phy_data, detect.work);
 	struct phy *phy0 = data->phys[0].phy;
-	int id_det, vbus_det, id_notify = 0, vbus_notify = 0;
+	bool id_notify = false, vbus_notify = false;
+	int id_det, vbus_det;
 
 	if (phy0 == NULL)
 		return;
@@ -474,13 +475,13 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
 		}
 		sun4i_usb_phy0_set_id_detect(phy0, id_det);
 		data->id_det = id_det;
-		id_notify = 1;
+		id_notify = true;
 	}
 
 	if (vbus_det != data->vbus_det) {
 		sun4i_usb_phy0_set_vbus_detect(phy0, vbus_det);
 		data->vbus_det = vbus_det;
-		vbus_notify = 1;
+		vbus_notify = true;
 	}
 
 	mutex_unlock(&phy0->mutex);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH resend 2/5] phy-sun4i-usb: Refactor forced session ending
  2016-09-07 20:20 [PATCH resend 0/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 1/5] phy-sun4i-usb: Use bool where appropriate Hans de Goede
@ 2016-09-07 20:20 ` Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 3/5] phy-sun4i-usb: Simplify missing dr_mode handling Hans de Goede
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Hans de Goede @ 2016-09-07 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

The phy-sun4i-usb code supports forced ending a session on systems
which lack Vbus detection, to allow switching between host and peripheral
mode on such systems.

Role switching via the musb driver "mode" sysfs attribute requires force
ending the session too. This commit refactors the code to allow other
parts of the phy-sun4i-usb code to request a forced session end.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-No changes
Changes in v3:
-No changes
---
 drivers/phy/phy-sun4i-usb.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 1cb84a8..02cb65e 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -133,6 +133,7 @@ struct sun4i_usb_phy_data {
 	struct power_supply *vbus_power_supply;
 	struct notifier_block vbus_power_nb;
 	bool vbus_power_nb_registered;
+	bool force_session_end;
 	int id_det_irq;
 	int vbus_det_irq;
 	int id_det;
@@ -445,7 +446,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
 	struct sun4i_usb_phy_data *data =
 		container_of(work, struct sun4i_usb_phy_data, detect.work);
 	struct phy *phy0 = data->phys[0].phy;
-	bool id_notify = false, vbus_notify = false;
+	bool force_session_end, id_notify = false, vbus_notify = false;
 	int id_det, vbus_det;
 
 	if (phy0 == NULL)
@@ -461,14 +462,17 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
 		return;
 	}
 
+	force_session_end = data->force_session_end;
+	data->force_session_end = false;
+
 	if (id_det != data->id_det) {
-		/*
-		 * When a host cable (id == 0) gets plugged in on systems
-		 * without vbus detection report vbus low for long enough for
-		 * the musb-ip to end the current device session.
-		 */
+		/* id-change, force session end if we've no vbus detection */
 		if (data->dr_mode == USB_DR_MODE_OTG &&
-		    !sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) {
+		    !sun4i_usb_phy0_have_vbus_det(data))
+			force_session_end = true;
+
+		/* When entering host mode (id = 0) force end the session now */
+		if (force_session_end && id_det == 0) {
 			sun4i_usb_phy0_set_vbus_detect(phy0, 0);
 			msleep(200);
 			sun4i_usb_phy0_set_vbus_detect(phy0, 1);
@@ -489,13 +493,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
 	if (id_notify) {
 		extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST,
 					!id_det);
-		/*
-		 * When a host cable gets unplugged (id == 1) on systems
-		 * without vbus detection report vbus low for long enough to
-		 * the musb-ip to end the current host session.
-		 */
-		if (data->dr_mode == USB_DR_MODE_OTG &&
-		    !sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) {
+		/* When leaving host mode force end the session here */
+		if (force_session_end && id_det == 1) {
 			mutex_lock(&phy0->mutex);
 			sun4i_usb_phy0_set_vbus_detect(phy0, 0);
 			msleep(1000);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH resend 3/5] phy-sun4i-usb: Simplify missing dr_mode handling
  2016-09-07 20:20 [PATCH resend 0/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 1/5] phy-sun4i-usb: Use bool where appropriate Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 2/5] phy-sun4i-usb: Refactor forced session ending Hans de Goede
@ 2016-09-07 20:20 ` Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 4/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 5/5] phy-sun4i-usb: Warn when external vbus is detected Hans de Goede
  4 siblings, 0 replies; 6+ messages in thread
From: Hans de Goede @ 2016-09-07 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

If we cannot get dr_mode or no id gpio is specified simply assume
peripheral mode, as this is always safe.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Keep sun4i_usb_phy0_get_id_det() logic as is rather then re-ordering
 the switch-case
Changes in v3:
-No changes
---
 drivers/phy/phy-sun4i-usb.c | 42 ++++++++++++++----------------------------
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 02cb65e..fb2d4f3 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -124,7 +124,6 @@ struct sun4i_usb_phy_data {
 		bool regulator_on;
 		int index;
 	} phys[MAX_PHYS];
-	int first_phy;
 	/* phy0 / otg related variables */
 	struct extcon_dev *extcon;
 	bool phy0_init;
@@ -326,7 +325,10 @@ static int sun4i_usb_phy0_get_id_det(struct sun4i_usb_phy_data *data)
 {
 	switch (data->dr_mode) {
 	case USB_DR_MODE_OTG:
-		return gpiod_get_value_cansleep(data->id_det_gpio);
+		if (data->id_det_gpio)
+			return gpiod_get_value_cansleep(data->id_det_gpio);
+		else
+			return 1; /* Fallback to peripheral mode */
 	case USB_DR_MODE_HOST:
 		return 0;
 	case USB_DR_MODE_PERIPHERAL:
@@ -539,8 +541,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev,
 {
 	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
 
-	if (args->args[0] < data->first_phy ||
-	    args->args[0] >= data->cfg->num_phys)
+	if (args->args[0] >= data->cfg->num_phys)
 		return ERR_PTR(-ENODEV);
 
 	return data->phys[args->args[0]].phy;
@@ -615,33 +616,18 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 	}
 
 	data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0);
-	switch (data->dr_mode) {
-	case USB_DR_MODE_OTG:
-		/* otg without id_det makes no sense, and is not supported */
-		if (!data->id_det_gpio) {
-			dev_err(dev, "usb0_id_det missing or invalid\n");
-			return -ENODEV;
-		}
-		/* fall through */
-	case USB_DR_MODE_HOST:
-	case USB_DR_MODE_PERIPHERAL:
-		data->extcon = devm_extcon_dev_allocate(dev,
-							sun4i_usb_phy0_cable);
-		if (IS_ERR(data->extcon))
-			return PTR_ERR(data->extcon);
 
-		ret = devm_extcon_dev_register(dev, data->extcon);
-		if (ret) {
-			dev_err(dev, "failed to register extcon: %d\n", ret);
-			return ret;
-		}
-		break;
-	default:
-		dev_info(dev, "dr_mode unknown, not registering usb phy0\n");
-		data->first_phy = 1;
+	data->extcon = devm_extcon_dev_allocate(dev, sun4i_usb_phy0_cable);
+	if (IS_ERR(data->extcon))
+		return PTR_ERR(data->extcon);
+
+	ret = devm_extcon_dev_register(dev, data->extcon);
+	if (ret) {
+		dev_err(dev, "failed to register extcon: %d\n", ret);
+		return ret;
 	}
 
-	for (i = data->first_phy; i < data->cfg->num_phys; i++) {
+	for (i = 0; i < data->cfg->num_phys; i++) {
 		struct sun4i_usb_phy *phy = data->phys + i;
 		char name[16];
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH resend 4/5] phy-sun4i-usb: Add support for phy_set_mode
  2016-09-07 20:20 [PATCH resend 0/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
                   ` (2 preceding siblings ...)
  2016-09-07 20:20 ` [PATCH resend 3/5] phy-sun4i-usb: Simplify missing dr_mode handling Hans de Goede
@ 2016-09-07 20:20 ` Hans de Goede
  2016-09-07 20:20 ` [PATCH resend 5/5] phy-sun4i-usb: Warn when external vbus is detected Hans de Goede
  4 siblings, 0 replies; 6+ messages in thread
From: Hans de Goede @ 2016-09-07 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

Together with some musb sunxi glue changes this allows run-time dr_mode
switching support via the "mode" musb sysfs attribute.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-No changes
Changes in v3:
-Fix switch-case code style
---
 drivers/phy/phy-sun4i-usb.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index fb2d4f3..af42f8d 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -427,6 +427,35 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
 	return 0;
 }
 
+static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+
+	if (phy->index != 0)
+		return -EINVAL;
+
+	switch (mode) {
+	case PHY_MODE_USB_HOST:
+		data->dr_mode = USB_DR_MODE_HOST;
+		break;
+	case PHY_MODE_USB_DEVICE:
+		data->dr_mode = USB_DR_MODE_PERIPHERAL;
+		break;
+	case PHY_MODE_USB_OTG:
+		data->dr_mode = USB_DR_MODE_OTG;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	dev_info(&_phy->dev, "Changing dr_mode to %d\n", (int)data->dr_mode);
+	data->force_session_end = true;
+	queue_delayed_work(system_wq, &data->detect, 0);
+
+	return 0;
+}
+
 void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
 {
 	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
@@ -440,6 +469,7 @@ static const struct phy_ops sun4i_usb_phy_ops = {
 	.exit		= sun4i_usb_phy_exit,
 	.power_on	= sun4i_usb_phy_power_on,
 	.power_off	= sun4i_usb_phy_power_off,
+	.set_mode	= sun4i_usb_phy_set_mode,
 	.owner		= THIS_MODULE,
 };
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH resend 5/5] phy-sun4i-usb: Warn when external vbus is detected
  2016-09-07 20:20 [PATCH resend 0/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
                   ` (3 preceding siblings ...)
  2016-09-07 20:20 ` [PATCH resend 4/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
@ 2016-09-07 20:20 ` Hans de Goede
  4 siblings, 0 replies; 6+ messages in thread
From: Hans de Goede @ 2016-09-07 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

Warn when external vbus is detected when we're trying to enable our
own vbus.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-No changes
Changes in v3:
-No changes
---
 drivers/phy/phy-sun4i-usb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index af42f8d..03f030b 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -390,8 +390,10 @@ static int sun4i_usb_phy_power_on(struct phy *_phy)
 
 	/* For phy0 only turn on Vbus if we don't have an ext. Vbus */
 	if (phy->index == 0 && sun4i_usb_phy0_have_vbus_det(data) &&
-				data->vbus_det)
+				data->vbus_det) {
+		dev_warn(&_phy->dev, "External vbus detected, not enabling our own vbus\n");
 		return 0;
+	}
 
 	ret = regulator_enable(phy->vbus);
 	if (ret)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-09-07 20:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-07 20:20 [PATCH resend 0/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
2016-09-07 20:20 ` [PATCH resend 1/5] phy-sun4i-usb: Use bool where appropriate Hans de Goede
2016-09-07 20:20 ` [PATCH resend 2/5] phy-sun4i-usb: Refactor forced session ending Hans de Goede
2016-09-07 20:20 ` [PATCH resend 3/5] phy-sun4i-usb: Simplify missing dr_mode handling Hans de Goede
2016-09-07 20:20 ` [PATCH resend 4/5] phy-sun4i-usb: Add support for phy_set_mode Hans de Goede
2016-09-07 20:20 ` [PATCH resend 5/5] phy-sun4i-usb: Warn when external vbus is detected Hans de Goede

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).