All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] usb: typec: Registering real device entries for the muxes
@ 2019-04-01 10:15 ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-01 10:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Hans de Goede, linux-usb, stable

Registering real device entries (struct device) for the mode
muxes as well as for the orientation switches.

The Type-C mux code was deliberately attempting to avoid
creation of separate device entries for the orientation
switch and the mode switch (alternate modes) because they
are not physical devices. They are functions of a single
physical multiplexer/demultiplexer switch device.

Unfortunately because of the dependency we still have on the
underlying mux device driver, we had to put in hacks like
the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
care of driver module reference counting") to make sure the
driver does not disappear from underneath us. Even with
those hacks we were still left with a potential NUll pointer
dereference scenario, so just creating the device entries,
and letting the core take care of the dependencies. No more
hacks needed.

Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
 drivers/usb/typec/bus.h             |  15 ++
 drivers/usb/typec/class.c           |  16 ++-
 drivers/usb/typec/mux.c             | 207 +++++++++++++++++++---------
 drivers/usb/typec/mux/pi3usb30532.c |  46 ++++---
 include/linux/usb/typec_mux.h       |  58 ++++----
 5 files changed, 220 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index db40e61d8b72..0c9661c96473 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -35,4 +35,19 @@ extern const struct device_type typec_port_dev_type;
 #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
 #define is_typec_port(_dev_) (_dev_->type == &typec_port_dev_type)
 
+extern struct class typec_mux_class;
+
+struct typec_switch {
+	struct device dev;
+	typec_switch_set_fn_t set;
+};
+
+struct typec_mux {
+	struct device dev;
+	typec_mux_set_fn_t set;
+};
+
+#define to_typec_switch(_dev_) container_of(_dev_, struct typec_switch, dev)
+#define to_typec_mux(_dev_) container_of(_dev_, struct typec_mux, dev)
+
 #endif /* __USB_TYPEC_ALTMODE_H__ */
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 2eb623841847..8f5223879d91 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -1646,13 +1646,25 @@ static int __init typec_init(void)
 	if (ret)
 		return ret;
 
+	ret = class_register(&typec_mux_class);
+	if (ret)
+		goto err_unregister_bus;
+
 	typec_class = class_create(THIS_MODULE, "typec");
 	if (IS_ERR(typec_class)) {
-		bus_unregister(&typec_bus);
-		return PTR_ERR(typec_class);
+		ret = PTR_ERR(typec_class);
+		goto err_unregister_mux_class;
 	}
 
 	return 0;
+
+err_unregister_mux_class:
+	class_unregister(&typec_mux_class);
+
+err_unregister_bus:
+	bus_unregister(&typec_bus);
+
+	return ret;
 }
 subsys_initcall(typec_init);
 
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 2ce54f3fc79c..f945abd23222 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -15,35 +15,35 @@
 #include <linux/slab.h>
 #include <linux/usb/typec_mux.h>
 
-static DEFINE_MUTEX(switch_lock);
-static DEFINE_MUTEX(mux_lock);
-static LIST_HEAD(switch_list);
-static LIST_HEAD(mux_list);
+#include "bus.h"
+
+static int name_match(struct device *dev, const void *name)
+{
+	return !strcmp((const char *)name, dev_name(dev));
+}
+
+static int fwnode_match(struct device *dev, const void *fwnode)
+{
+	return dev_fwnode(dev) == fwnode;
+}
 
 static void *typec_switch_match(struct device_connection *con, int ep,
 				void *data)
 {
-	struct typec_switch *sw;
+	struct device *dev;
 
-	if (!con->fwnode) {
-		list_for_each_entry(sw, &switch_list, entry)
-			if (!strcmp(con->endpoint[ep], dev_name(sw->dev)))
-				return sw;
-		return ERR_PTR(-EPROBE_DEFER);
-	}
-
-	/*
-	 * With OF graph the mux node must have a boolean device property named
-	 * "orientation-switch".
-	 */
-	if (con->id && !fwnode_property_present(con->fwnode, con->id))
-		return NULL;
+	if (con->fwnode) {
+		if (con->id && !fwnode_property_present(con->fwnode, con->id))
+			return NULL;
 
-	list_for_each_entry(sw, &switch_list, entry)
-		if (dev_fwnode(sw->dev) == con->fwnode)
-			return sw;
+		dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
+					fwnode_match);
+	} else {
+		dev = class_find_device(&typec_mux_class, NULL,
+					con->endpoint[ep], name_match);
+	}
 
-	return con->id ? ERR_PTR(-EPROBE_DEFER) : NULL;
+	return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 }
 
 /**
@@ -59,14 +59,10 @@ struct typec_switch *typec_switch_get(struct device *dev)
 {
 	struct typec_switch *sw;
 
-	mutex_lock(&switch_lock);
 	sw = device_connection_find_match(dev, "orientation-switch", NULL,
 					  typec_switch_match);
-	if (!IS_ERR_OR_NULL(sw)) {
-		WARN_ON(!try_module_get(sw->dev->driver->owner));
-		get_device(sw->dev);
-	}
-	mutex_unlock(&switch_lock);
+	if (!IS_ERR_OR_NULL(sw))
+		get_device(&sw->dev);
 
 	return sw;
 }
@@ -80,13 +76,21 @@ EXPORT_SYMBOL_GPL(typec_switch_get);
  */
 void typec_switch_put(struct typec_switch *sw)
 {
-	if (!IS_ERR_OR_NULL(sw)) {
-		module_put(sw->dev->driver->owner);
-		put_device(sw->dev);
-	}
+	if (!IS_ERR_OR_NULL(sw))
+		put_device(&sw->dev);
 }
 EXPORT_SYMBOL_GPL(typec_switch_put);
 
+static void typec_switch_release(struct device *dev)
+{
+	kfree(to_typec_switch(dev));
+}
+
+static const struct device_type typec_switch_dev_type = {
+	.name = "orientation_switch",
+	.release = typec_switch_release,
+};
+
 /**
  * typec_switch_register - Register USB Type-C orientation switch
  * @sw: USB Type-C orientation switch
@@ -96,13 +100,38 @@ EXPORT_SYMBOL_GPL(typec_switch_put);
  * connector to the USB controllers. USB Type-C plugs can be inserted
  * right-side-up or upside-down.
  */
-int typec_switch_register(struct typec_switch *sw)
+struct typec_switch *
+typec_switch_register(struct device *parent,
+		      const struct typec_switch_desc *desc)
 {
-	mutex_lock(&switch_lock);
-	list_add_tail(&sw->entry, &switch_list);
-	mutex_unlock(&switch_lock);
+	struct typec_switch *sw;
+	int ret;
+
+	if (!desc || !desc->set)
+		return ERR_PTR(-EINVAL);
+
+	sw = kzalloc(sizeof(*sw), GFP_KERNEL);
+	if (!sw)
+		return ERR_PTR(-ENOMEM);
+
+	sw->set = desc->set;
+
+	device_initialize(&sw->dev);
+	sw->dev.parent = parent;
+	sw->dev.class = &typec_mux_class;
+	sw->dev.type = &typec_switch_dev_type;
+	sw->dev.driver_data = desc->drvdata;
+	sw->dev.fwnode = desc->fwnode;
+	dev_set_name(&sw->dev, "%s-switch", dev_name(parent));
+
+	ret = device_add(&sw->dev);
+	if (ret) {
+		dev_err(parent, "failed to register switch (%d)\n", ret);
+		put_device(&sw->dev);
+		return ERR_PTR(ret);
+	}
 
-	return 0;
+	return sw;
 }
 EXPORT_SYMBOL_GPL(typec_switch_register);
 
@@ -114,28 +143,33 @@ EXPORT_SYMBOL_GPL(typec_switch_register);
  */
 void typec_switch_unregister(struct typec_switch *sw)
 {
-	mutex_lock(&switch_lock);
-	list_del(&sw->entry);
-	mutex_unlock(&switch_lock);
+	if (!IS_ERR_OR_NULL(sw))
+		device_unregister(&sw->dev);
 }
 EXPORT_SYMBOL_GPL(typec_switch_unregister);
 
+void *typec_switch_get_drvdata(struct typec_switch *sw)
+{
+	return dev_get_drvdata(&sw->dev);
+}
+EXPORT_SYMBOL_GPL(typec_switch_get_drvdata);
+
 /* ------------------------------------------------------------------------- */
 
 static void *typec_mux_match(struct device_connection *con, int ep, void *data)
 {
 	const struct typec_altmode_desc *desc = data;
-	struct typec_mux *mux;
-	int nval;
+	struct device *dev;
 	bool match;
+	int nval;
 	u16 *val;
 	int i;
 
 	if (!con->fwnode) {
-		list_for_each_entry(mux, &mux_list, entry)
-			if (!strcmp(con->endpoint[ep], dev_name(mux->dev)))
-				return mux;
-		return ERR_PTR(-EPROBE_DEFER);
+		dev = class_find_device(&typec_mux_class, NULL,
+					con->endpoint[ep], name_match);
+
+		return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 	}
 
 	/*
@@ -180,11 +214,10 @@ static void *typec_mux_match(struct device_connection *con, int ep, void *data)
 	return NULL;
 
 find_mux:
-	list_for_each_entry(mux, &mux_list, entry)
-		if (dev_fwnode(mux->dev) == con->fwnode)
-			return mux;
+	dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
+				fwnode_match);
 
-	return ERR_PTR(-EPROBE_DEFER);
+	return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 }
 
 /**
@@ -202,14 +235,10 @@ struct typec_mux *typec_mux_get(struct device *dev,
 {
 	struct typec_mux *mux;
 
-	mutex_lock(&mux_lock);
 	mux = device_connection_find_match(dev, "mode-switch", (void *)desc,
 					   typec_mux_match);
-	if (!IS_ERR_OR_NULL(mux)) {
-		WARN_ON(!try_module_get(mux->dev->driver->owner));
-		get_device(mux->dev);
-	}
-	mutex_unlock(&mux_lock);
+	if (!IS_ERR_OR_NULL(mux))
+		get_device(&mux->dev);
 
 	return mux;
 }
@@ -223,13 +252,21 @@ EXPORT_SYMBOL_GPL(typec_mux_get);
  */
 void typec_mux_put(struct typec_mux *mux)
 {
-	if (!IS_ERR_OR_NULL(mux)) {
-		module_put(mux->dev->driver->owner);
-		put_device(mux->dev);
-	}
+	if (!IS_ERR_OR_NULL(mux))
+		put_device(&mux->dev);
 }
 EXPORT_SYMBOL_GPL(typec_mux_put);
 
+static void typec_mux_release(struct device *dev)
+{
+	kfree(to_typec_mux(dev));
+}
+
+static const struct device_type typec_mux_dev_type = {
+	.name = "mode_switch",
+	.release = typec_mux_release,
+};
+
 /**
  * typec_mux_register - Register Multiplexer routing USB Type-C pins
  * @mux: USB Type-C Connector Multiplexer/DeMultiplexer
@@ -239,13 +276,37 @@ EXPORT_SYMBOL_GPL(typec_mux_put);
  * the pins on the connector need to be reconfigured. This function registers
  * multiplexer switches routing the pins on the connector.
  */
-int typec_mux_register(struct typec_mux *mux)
+struct typec_mux *
+typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
 {
-	mutex_lock(&mux_lock);
-	list_add_tail(&mux->entry, &mux_list);
-	mutex_unlock(&mux_lock);
+	struct typec_mux *mux;
+	int ret;
+
+	if (!desc || !desc->set)
+		return ERR_PTR(-EINVAL);
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	mux->set = desc->set;
+
+	device_initialize(&mux->dev);
+	mux->dev.parent = parent;
+	mux->dev.class = &typec_mux_class;
+	mux->dev.type = &typec_mux_dev_type;
+	mux->dev.fwnode = desc->fwnode;
+	mux->dev.driver_data = desc->drvdata;
+	dev_set_name(&mux->dev, "%s-mux", dev_name(parent));
+
+	ret = device_add(&mux->dev);
+	if (ret) {
+		dev_err(parent, "failed to register mux (%d)\n", ret);
+		put_device(&mux->dev);
+		return ERR_PTR(ret);
+	}
 
-	return 0;
+	return mux;
 }
 EXPORT_SYMBOL_GPL(typec_mux_register);
 
@@ -257,8 +318,18 @@ EXPORT_SYMBOL_GPL(typec_mux_register);
  */
 void typec_mux_unregister(struct typec_mux *mux)
 {
-	mutex_lock(&mux_lock);
-	list_del(&mux->entry);
-	mutex_unlock(&mux_lock);
+	if (!IS_ERR_OR_NULL(mux))
+		device_unregister(&mux->dev);
 }
 EXPORT_SYMBOL_GPL(typec_mux_unregister);
+
+void *typec_mux_get_drvdata(struct typec_mux *mux)
+{
+	return dev_get_drvdata(&mux->dev);
+}
+EXPORT_SYMBOL_GPL(typec_mux_get_drvdata);
+
+struct class typec_mux_class = {
+	.name = "typec_mux",
+	.owner = THIS_MODULE,
+};
diff --git a/drivers/usb/typec/mux/pi3usb30532.c b/drivers/usb/typec/mux/pi3usb30532.c
index 9294e85fd34b..5585b109095b 100644
--- a/drivers/usb/typec/mux/pi3usb30532.c
+++ b/drivers/usb/typec/mux/pi3usb30532.c
@@ -23,8 +23,8 @@
 struct pi3usb30532 {
 	struct i2c_client *client;
 	struct mutex lock; /* protects the cached conf register */
-	struct typec_switch sw;
-	struct typec_mux mux;
+	struct typec_switch *sw;
+	struct typec_mux *mux;
 	u8 conf;
 };
 
@@ -48,7 +48,7 @@ static int pi3usb30532_set_conf(struct pi3usb30532 *pi, u8 new_conf)
 static int pi3usb30532_sw_set(struct typec_switch *sw,
 			      enum typec_orientation orientation)
 {
-	struct pi3usb30532 *pi = container_of(sw, struct pi3usb30532, sw);
+	struct pi3usb30532 *pi = typec_switch_get_drvdata(sw);
 	u8 new_conf;
 	int ret;
 
@@ -75,7 +75,7 @@ static int pi3usb30532_sw_set(struct typec_switch *sw,
 
 static int pi3usb30532_mux_set(struct typec_mux *mux, int state)
 {
-	struct pi3usb30532 *pi = container_of(mux, struct pi3usb30532, mux);
+	struct pi3usb30532 *pi = typec_mux_get_drvdata(mux);
 	u8 new_conf;
 	int ret;
 
@@ -113,6 +113,8 @@ static int pi3usb30532_mux_set(struct typec_mux *mux, int state)
 static int pi3usb30532_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
+	struct typec_switch_desc sw_desc;
+	struct typec_mux_desc mux_desc;
 	struct pi3usb30532 *pi;
 	int ret;
 
@@ -121,10 +123,6 @@ static int pi3usb30532_probe(struct i2c_client *client)
 		return -ENOMEM;
 
 	pi->client = client;
-	pi->sw.dev = dev;
-	pi->sw.set = pi3usb30532_sw_set;
-	pi->mux.dev = dev;
-	pi->mux.set = pi3usb30532_mux_set;
 	mutex_init(&pi->lock);
 
 	ret = i2c_smbus_read_byte_data(client, PI3USB30532_CONF);
@@ -134,17 +132,27 @@ static int pi3usb30532_probe(struct i2c_client *client)
 	}
 	pi->conf = ret;
 
-	ret = typec_switch_register(&pi->sw);
-	if (ret) {
-		dev_err(dev, "Error registering typec switch: %d\n", ret);
-		return ret;
+	sw_desc.drvdata = pi;
+	sw_desc.fwnode = dev->fwnode;
+	sw_desc.set = pi3usb30532_sw_set;
+
+	pi->sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(pi->sw)) {
+		dev_err(dev, "Error registering typec switch: %ld\n",
+			PTR_ERR(pi->sw));
+		return PTR_ERR(pi->sw);
 	}
 
-	ret = typec_mux_register(&pi->mux);
-	if (ret) {
-		typec_switch_unregister(&pi->sw);
-		dev_err(dev, "Error registering typec mux: %d\n", ret);
-		return ret;
+	mux_desc.drvdata = pi;
+	mux_desc.fwnode = dev->fwnode;
+	mux_desc.set = pi3usb30532_mux_set;
+
+	pi->mux = typec_mux_register(dev, &mux_desc);
+	if (IS_ERR(pi->mux)) {
+		typec_switch_unregister(pi->sw);
+		dev_err(dev, "Error registering typec mux: %ld\n",
+			PTR_ERR(pi->mux));
+		return PTR_ERR(pi->mux);
 	}
 
 	i2c_set_clientdata(client, pi);
@@ -155,8 +163,8 @@ static int pi3usb30532_remove(struct i2c_client *client)
 {
 	struct pi3usb30532 *pi = i2c_get_clientdata(client);
 
-	typec_mux_unregister(&pi->mux);
-	typec_switch_unregister(&pi->sw);
+	typec_mux_unregister(pi->mux);
+	typec_switch_unregister(pi->sw);
 	return 0;
 }
 
diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
index 43f40685e53c..621e0811e794 100644
--- a/include/linux/usb/typec_mux.h
+++ b/include/linux/usb/typec_mux.h
@@ -3,54 +3,46 @@
 #ifndef __USB_TYPEC_MUX
 #define __USB_TYPEC_MUX
 
-#include <linux/list.h>
 #include <linux/usb/typec.h>
 
 struct device;
+struct typec_mux;
+struct typec_switch;
+struct fwnode_handle;
 
-/**
- * struct typec_switch - USB Type-C cable orientation switch
- * @dev: Switch device
- * @entry: List entry
- * @set: Callback to the driver for setting the orientation
- *
- * USB Type-C pin flipper switch routing the correct data pairs from the
- * connector to the USB controller depending on the orientation of the cable
- * plug.
- */
-struct typec_switch {
-	struct device *dev;
-	struct list_head entry;
-
-	int (*set)(struct typec_switch *sw, enum typec_orientation orientation);
+typedef int (*typec_switch_set_fn_t)(struct typec_switch *sw,
+				     enum typec_orientation orientation);
+
+struct typec_switch_desc {
+	void *drvdata;
+	struct fwnode_handle *fwnode;
+	typec_switch_set_fn_t set;
 };
 
-/**
- * struct typec_switch - USB Type-C connector pin mux
- * @dev: Mux device
- * @entry: List entry
- * @set: Callback to the driver for setting the state of the mux
- *
- * Pin Multiplexer/DeMultiplexer switch routing the USB Type-C connector pins to
- * different components depending on the requested mode of operation. Used with
- * Accessory/Alternate modes.
- */
-struct typec_mux {
-	struct device *dev;
-	struct list_head entry;
-
-	int (*set)(struct typec_mux *mux, int state);
+typedef int (*typec_mux_set_fn_t)(struct typec_mux *mux, int state);
+
+struct typec_mux_desc {
+	void *drvdata;
+	struct fwnode_handle *fwnode;
+	typec_mux_set_fn_t set;
 };
 
 struct typec_switch *typec_switch_get(struct device *dev);
 void typec_switch_put(struct typec_switch *sw);
-int typec_switch_register(struct typec_switch *sw);
+struct typec_switch *
+typec_switch_register(struct device *parent,
+		      const struct typec_switch_desc *desc);
 void typec_switch_unregister(struct typec_switch *sw);
 
+void *typec_switch_get_drvdata(struct typec_switch *sw);
+
 struct typec_mux *
 typec_mux_get(struct device *dev, const struct typec_altmode_desc *desc);
 void typec_mux_put(struct typec_mux *mux);
-int typec_mux_register(struct typec_mux *mux);
+struct typec_mux *
+typec_mux_register(struct device *parent, const struct typec_mux_desc *desc);
 void typec_mux_unregister(struct typec_mux *mux);
 
+void *typec_mux_get_drvdata(struct typec_mux *mux);
+
 #endif /* __USB_TYPEC_MUX */
-- 
2.20.1


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

* usb: typec: Registering real device entries for the muxes
@ 2019-04-01 10:15 ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-01 10:15 UTC (permalink / raw)
  To: Greg KH; +Cc: Hans de Goede, linux-usb, stable

Registering real device entries (struct device) for the mode
muxes as well as for the orientation switches.

The Type-C mux code was deliberately attempting to avoid
creation of separate device entries for the orientation
switch and the mode switch (alternate modes) because they
are not physical devices. They are functions of a single
physical multiplexer/demultiplexer switch device.

Unfortunately because of the dependency we still have on the
underlying mux device driver, we had to put in hacks like
the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
care of driver module reference counting") to make sure the
driver does not disappear from underneath us. Even with
those hacks we were still left with a potential NUll pointer
dereference scenario, so just creating the device entries,
and letting the core take care of the dependencies. No more
hacks needed.

Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
 drivers/usb/typec/bus.h             |  15 ++
 drivers/usb/typec/class.c           |  16 ++-
 drivers/usb/typec/mux.c             | 207 +++++++++++++++++++---------
 drivers/usb/typec/mux/pi3usb30532.c |  46 ++++---
 include/linux/usb/typec_mux.h       |  58 ++++----
 5 files changed, 220 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index db40e61d8b72..0c9661c96473 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -35,4 +35,19 @@ extern const struct device_type typec_port_dev_type;
 #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
 #define is_typec_port(_dev_) (_dev_->type == &typec_port_dev_type)
 
+extern struct class typec_mux_class;
+
+struct typec_switch {
+	struct device dev;
+	typec_switch_set_fn_t set;
+};
+
+struct typec_mux {
+	struct device dev;
+	typec_mux_set_fn_t set;
+};
+
+#define to_typec_switch(_dev_) container_of(_dev_, struct typec_switch, dev)
+#define to_typec_mux(_dev_) container_of(_dev_, struct typec_mux, dev)
+
 #endif /* __USB_TYPEC_ALTMODE_H__ */
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 2eb623841847..8f5223879d91 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -1646,13 +1646,25 @@ static int __init typec_init(void)
 	if (ret)
 		return ret;
 
+	ret = class_register(&typec_mux_class);
+	if (ret)
+		goto err_unregister_bus;
+
 	typec_class = class_create(THIS_MODULE, "typec");
 	if (IS_ERR(typec_class)) {
-		bus_unregister(&typec_bus);
-		return PTR_ERR(typec_class);
+		ret = PTR_ERR(typec_class);
+		goto err_unregister_mux_class;
 	}
 
 	return 0;
+
+err_unregister_mux_class:
+	class_unregister(&typec_mux_class);
+
+err_unregister_bus:
+	bus_unregister(&typec_bus);
+
+	return ret;
 }
 subsys_initcall(typec_init);
 
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 2ce54f3fc79c..f945abd23222 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -15,35 +15,35 @@
 #include <linux/slab.h>
 #include <linux/usb/typec_mux.h>
 
-static DEFINE_MUTEX(switch_lock);
-static DEFINE_MUTEX(mux_lock);
-static LIST_HEAD(switch_list);
-static LIST_HEAD(mux_list);
+#include "bus.h"
+
+static int name_match(struct device *dev, const void *name)
+{
+	return !strcmp((const char *)name, dev_name(dev));
+}
+
+static int fwnode_match(struct device *dev, const void *fwnode)
+{
+	return dev_fwnode(dev) == fwnode;
+}
 
 static void *typec_switch_match(struct device_connection *con, int ep,
 				void *data)
 {
-	struct typec_switch *sw;
+	struct device *dev;
 
-	if (!con->fwnode) {
-		list_for_each_entry(sw, &switch_list, entry)
-			if (!strcmp(con->endpoint[ep], dev_name(sw->dev)))
-				return sw;
-		return ERR_PTR(-EPROBE_DEFER);
-	}
-
-	/*
-	 * With OF graph the mux node must have a boolean device property named
-	 * "orientation-switch".
-	 */
-	if (con->id && !fwnode_property_present(con->fwnode, con->id))
-		return NULL;
+	if (con->fwnode) {
+		if (con->id && !fwnode_property_present(con->fwnode, con->id))
+			return NULL;
 
-	list_for_each_entry(sw, &switch_list, entry)
-		if (dev_fwnode(sw->dev) == con->fwnode)
-			return sw;
+		dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
+					fwnode_match);
+	} else {
+		dev = class_find_device(&typec_mux_class, NULL,
+					con->endpoint[ep], name_match);
+	}
 
-	return con->id ? ERR_PTR(-EPROBE_DEFER) : NULL;
+	return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 }
 
 /**
@@ -59,14 +59,10 @@ struct typec_switch *typec_switch_get(struct device *dev)
 {
 	struct typec_switch *sw;
 
-	mutex_lock(&switch_lock);
 	sw = device_connection_find_match(dev, "orientation-switch", NULL,
 					  typec_switch_match);
-	if (!IS_ERR_OR_NULL(sw)) {
-		WARN_ON(!try_module_get(sw->dev->driver->owner));
-		get_device(sw->dev);
-	}
-	mutex_unlock(&switch_lock);
+	if (!IS_ERR_OR_NULL(sw))
+		get_device(&sw->dev);
 
 	return sw;
 }
@@ -80,13 +76,21 @@ EXPORT_SYMBOL_GPL(typec_switch_get);
  */
 void typec_switch_put(struct typec_switch *sw)
 {
-	if (!IS_ERR_OR_NULL(sw)) {
-		module_put(sw->dev->driver->owner);
-		put_device(sw->dev);
-	}
+	if (!IS_ERR_OR_NULL(sw))
+		put_device(&sw->dev);
 }
 EXPORT_SYMBOL_GPL(typec_switch_put);
 
+static void typec_switch_release(struct device *dev)
+{
+	kfree(to_typec_switch(dev));
+}
+
+static const struct device_type typec_switch_dev_type = {
+	.name = "orientation_switch",
+	.release = typec_switch_release,
+};
+
 /**
  * typec_switch_register - Register USB Type-C orientation switch
  * @sw: USB Type-C orientation switch
@@ -96,13 +100,38 @@ EXPORT_SYMBOL_GPL(typec_switch_put);
  * connector to the USB controllers. USB Type-C plugs can be inserted
  * right-side-up or upside-down.
  */
-int typec_switch_register(struct typec_switch *sw)
+struct typec_switch *
+typec_switch_register(struct device *parent,
+		      const struct typec_switch_desc *desc)
 {
-	mutex_lock(&switch_lock);
-	list_add_tail(&sw->entry, &switch_list);
-	mutex_unlock(&switch_lock);
+	struct typec_switch *sw;
+	int ret;
+
+	if (!desc || !desc->set)
+		return ERR_PTR(-EINVAL);
+
+	sw = kzalloc(sizeof(*sw), GFP_KERNEL);
+	if (!sw)
+		return ERR_PTR(-ENOMEM);
+
+	sw->set = desc->set;
+
+	device_initialize(&sw->dev);
+	sw->dev.parent = parent;
+	sw->dev.class = &typec_mux_class;
+	sw->dev.type = &typec_switch_dev_type;
+	sw->dev.driver_data = desc->drvdata;
+	sw->dev.fwnode = desc->fwnode;
+	dev_set_name(&sw->dev, "%s-switch", dev_name(parent));
+
+	ret = device_add(&sw->dev);
+	if (ret) {
+		dev_err(parent, "failed to register switch (%d)\n", ret);
+		put_device(&sw->dev);
+		return ERR_PTR(ret);
+	}
 
-	return 0;
+	return sw;
 }
 EXPORT_SYMBOL_GPL(typec_switch_register);
 
@@ -114,28 +143,33 @@ EXPORT_SYMBOL_GPL(typec_switch_register);
  */
 void typec_switch_unregister(struct typec_switch *sw)
 {
-	mutex_lock(&switch_lock);
-	list_del(&sw->entry);
-	mutex_unlock(&switch_lock);
+	if (!IS_ERR_OR_NULL(sw))
+		device_unregister(&sw->dev);
 }
 EXPORT_SYMBOL_GPL(typec_switch_unregister);
 
+void *typec_switch_get_drvdata(struct typec_switch *sw)
+{
+	return dev_get_drvdata(&sw->dev);
+}
+EXPORT_SYMBOL_GPL(typec_switch_get_drvdata);
+
 /* ------------------------------------------------------------------------- */
 
 static void *typec_mux_match(struct device_connection *con, int ep, void *data)
 {
 	const struct typec_altmode_desc *desc = data;
-	struct typec_mux *mux;
-	int nval;
+	struct device *dev;
 	bool match;
+	int nval;
 	u16 *val;
 	int i;
 
 	if (!con->fwnode) {
-		list_for_each_entry(mux, &mux_list, entry)
-			if (!strcmp(con->endpoint[ep], dev_name(mux->dev)))
-				return mux;
-		return ERR_PTR(-EPROBE_DEFER);
+		dev = class_find_device(&typec_mux_class, NULL,
+					con->endpoint[ep], name_match);
+
+		return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 	}
 
 	/*
@@ -180,11 +214,10 @@ static void *typec_mux_match(struct device_connection *con, int ep, void *data)
 	return NULL;
 
 find_mux:
-	list_for_each_entry(mux, &mux_list, entry)
-		if (dev_fwnode(mux->dev) == con->fwnode)
-			return mux;
+	dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
+				fwnode_match);
 
-	return ERR_PTR(-EPROBE_DEFER);
+	return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 }
 
 /**
@@ -202,14 +235,10 @@ struct typec_mux *typec_mux_get(struct device *dev,
 {
 	struct typec_mux *mux;
 
-	mutex_lock(&mux_lock);
 	mux = device_connection_find_match(dev, "mode-switch", (void *)desc,
 					   typec_mux_match);
-	if (!IS_ERR_OR_NULL(mux)) {
-		WARN_ON(!try_module_get(mux->dev->driver->owner));
-		get_device(mux->dev);
-	}
-	mutex_unlock(&mux_lock);
+	if (!IS_ERR_OR_NULL(mux))
+		get_device(&mux->dev);
 
 	return mux;
 }
@@ -223,13 +252,21 @@ EXPORT_SYMBOL_GPL(typec_mux_get);
  */
 void typec_mux_put(struct typec_mux *mux)
 {
-	if (!IS_ERR_OR_NULL(mux)) {
-		module_put(mux->dev->driver->owner);
-		put_device(mux->dev);
-	}
+	if (!IS_ERR_OR_NULL(mux))
+		put_device(&mux->dev);
 }
 EXPORT_SYMBOL_GPL(typec_mux_put);
 
+static void typec_mux_release(struct device *dev)
+{
+	kfree(to_typec_mux(dev));
+}
+
+static const struct device_type typec_mux_dev_type = {
+	.name = "mode_switch",
+	.release = typec_mux_release,
+};
+
 /**
  * typec_mux_register - Register Multiplexer routing USB Type-C pins
  * @mux: USB Type-C Connector Multiplexer/DeMultiplexer
@@ -239,13 +276,37 @@ EXPORT_SYMBOL_GPL(typec_mux_put);
  * the pins on the connector need to be reconfigured. This function registers
  * multiplexer switches routing the pins on the connector.
  */
-int typec_mux_register(struct typec_mux *mux)
+struct typec_mux *
+typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
 {
-	mutex_lock(&mux_lock);
-	list_add_tail(&mux->entry, &mux_list);
-	mutex_unlock(&mux_lock);
+	struct typec_mux *mux;
+	int ret;
+
+	if (!desc || !desc->set)
+		return ERR_PTR(-EINVAL);
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	mux->set = desc->set;
+
+	device_initialize(&mux->dev);
+	mux->dev.parent = parent;
+	mux->dev.class = &typec_mux_class;
+	mux->dev.type = &typec_mux_dev_type;
+	mux->dev.fwnode = desc->fwnode;
+	mux->dev.driver_data = desc->drvdata;
+	dev_set_name(&mux->dev, "%s-mux", dev_name(parent));
+
+	ret = device_add(&mux->dev);
+	if (ret) {
+		dev_err(parent, "failed to register mux (%d)\n", ret);
+		put_device(&mux->dev);
+		return ERR_PTR(ret);
+	}
 
-	return 0;
+	return mux;
 }
 EXPORT_SYMBOL_GPL(typec_mux_register);
 
@@ -257,8 +318,18 @@ EXPORT_SYMBOL_GPL(typec_mux_register);
  */
 void typec_mux_unregister(struct typec_mux *mux)
 {
-	mutex_lock(&mux_lock);
-	list_del(&mux->entry);
-	mutex_unlock(&mux_lock);
+	if (!IS_ERR_OR_NULL(mux))
+		device_unregister(&mux->dev);
 }
 EXPORT_SYMBOL_GPL(typec_mux_unregister);
+
+void *typec_mux_get_drvdata(struct typec_mux *mux)
+{
+	return dev_get_drvdata(&mux->dev);
+}
+EXPORT_SYMBOL_GPL(typec_mux_get_drvdata);
+
+struct class typec_mux_class = {
+	.name = "typec_mux",
+	.owner = THIS_MODULE,
+};
diff --git a/drivers/usb/typec/mux/pi3usb30532.c b/drivers/usb/typec/mux/pi3usb30532.c
index 9294e85fd34b..5585b109095b 100644
--- a/drivers/usb/typec/mux/pi3usb30532.c
+++ b/drivers/usb/typec/mux/pi3usb30532.c
@@ -23,8 +23,8 @@
 struct pi3usb30532 {
 	struct i2c_client *client;
 	struct mutex lock; /* protects the cached conf register */
-	struct typec_switch sw;
-	struct typec_mux mux;
+	struct typec_switch *sw;
+	struct typec_mux *mux;
 	u8 conf;
 };
 
@@ -48,7 +48,7 @@ static int pi3usb30532_set_conf(struct pi3usb30532 *pi, u8 new_conf)
 static int pi3usb30532_sw_set(struct typec_switch *sw,
 			      enum typec_orientation orientation)
 {
-	struct pi3usb30532 *pi = container_of(sw, struct pi3usb30532, sw);
+	struct pi3usb30532 *pi = typec_switch_get_drvdata(sw);
 	u8 new_conf;
 	int ret;
 
@@ -75,7 +75,7 @@ static int pi3usb30532_sw_set(struct typec_switch *sw,
 
 static int pi3usb30532_mux_set(struct typec_mux *mux, int state)
 {
-	struct pi3usb30532 *pi = container_of(mux, struct pi3usb30532, mux);
+	struct pi3usb30532 *pi = typec_mux_get_drvdata(mux);
 	u8 new_conf;
 	int ret;
 
@@ -113,6 +113,8 @@ static int pi3usb30532_mux_set(struct typec_mux *mux, int state)
 static int pi3usb30532_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
+	struct typec_switch_desc sw_desc;
+	struct typec_mux_desc mux_desc;
 	struct pi3usb30532 *pi;
 	int ret;
 
@@ -121,10 +123,6 @@ static int pi3usb30532_probe(struct i2c_client *client)
 		return -ENOMEM;
 
 	pi->client = client;
-	pi->sw.dev = dev;
-	pi->sw.set = pi3usb30532_sw_set;
-	pi->mux.dev = dev;
-	pi->mux.set = pi3usb30532_mux_set;
 	mutex_init(&pi->lock);
 
 	ret = i2c_smbus_read_byte_data(client, PI3USB30532_CONF);
@@ -134,17 +132,27 @@ static int pi3usb30532_probe(struct i2c_client *client)
 	}
 	pi->conf = ret;
 
-	ret = typec_switch_register(&pi->sw);
-	if (ret) {
-		dev_err(dev, "Error registering typec switch: %d\n", ret);
-		return ret;
+	sw_desc.drvdata = pi;
+	sw_desc.fwnode = dev->fwnode;
+	sw_desc.set = pi3usb30532_sw_set;
+
+	pi->sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(pi->sw)) {
+		dev_err(dev, "Error registering typec switch: %ld\n",
+			PTR_ERR(pi->sw));
+		return PTR_ERR(pi->sw);
 	}
 
-	ret = typec_mux_register(&pi->mux);
-	if (ret) {
-		typec_switch_unregister(&pi->sw);
-		dev_err(dev, "Error registering typec mux: %d\n", ret);
-		return ret;
+	mux_desc.drvdata = pi;
+	mux_desc.fwnode = dev->fwnode;
+	mux_desc.set = pi3usb30532_mux_set;
+
+	pi->mux = typec_mux_register(dev, &mux_desc);
+	if (IS_ERR(pi->mux)) {
+		typec_switch_unregister(pi->sw);
+		dev_err(dev, "Error registering typec mux: %ld\n",
+			PTR_ERR(pi->mux));
+		return PTR_ERR(pi->mux);
 	}
 
 	i2c_set_clientdata(client, pi);
@@ -155,8 +163,8 @@ static int pi3usb30532_remove(struct i2c_client *client)
 {
 	struct pi3usb30532 *pi = i2c_get_clientdata(client);
 
-	typec_mux_unregister(&pi->mux);
-	typec_switch_unregister(&pi->sw);
+	typec_mux_unregister(pi->mux);
+	typec_switch_unregister(pi->sw);
 	return 0;
 }
 
diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
index 43f40685e53c..621e0811e794 100644
--- a/include/linux/usb/typec_mux.h
+++ b/include/linux/usb/typec_mux.h
@@ -3,54 +3,46 @@
 #ifndef __USB_TYPEC_MUX
 #define __USB_TYPEC_MUX
 
-#include <linux/list.h>
 #include <linux/usb/typec.h>
 
 struct device;
+struct typec_mux;
+struct typec_switch;
+struct fwnode_handle;
 
-/**
- * struct typec_switch - USB Type-C cable orientation switch
- * @dev: Switch device
- * @entry: List entry
- * @set: Callback to the driver for setting the orientation
- *
- * USB Type-C pin flipper switch routing the correct data pairs from the
- * connector to the USB controller depending on the orientation of the cable
- * plug.
- */
-struct typec_switch {
-	struct device *dev;
-	struct list_head entry;
-
-	int (*set)(struct typec_switch *sw, enum typec_orientation orientation);
+typedef int (*typec_switch_set_fn_t)(struct typec_switch *sw,
+				     enum typec_orientation orientation);
+
+struct typec_switch_desc {
+	void *drvdata;
+	struct fwnode_handle *fwnode;
+	typec_switch_set_fn_t set;
 };
 
-/**
- * struct typec_switch - USB Type-C connector pin mux
- * @dev: Mux device
- * @entry: List entry
- * @set: Callback to the driver for setting the state of the mux
- *
- * Pin Multiplexer/DeMultiplexer switch routing the USB Type-C connector pins to
- * different components depending on the requested mode of operation. Used with
- * Accessory/Alternate modes.
- */
-struct typec_mux {
-	struct device *dev;
-	struct list_head entry;
-
-	int (*set)(struct typec_mux *mux, int state);
+typedef int (*typec_mux_set_fn_t)(struct typec_mux *mux, int state);
+
+struct typec_mux_desc {
+	void *drvdata;
+	struct fwnode_handle *fwnode;
+	typec_mux_set_fn_t set;
 };
 
 struct typec_switch *typec_switch_get(struct device *dev);
 void typec_switch_put(struct typec_switch *sw);
-int typec_switch_register(struct typec_switch *sw);
+struct typec_switch *
+typec_switch_register(struct device *parent,
+		      const struct typec_switch_desc *desc);
 void typec_switch_unregister(struct typec_switch *sw);
 
+void *typec_switch_get_drvdata(struct typec_switch *sw);
+
 struct typec_mux *
 typec_mux_get(struct device *dev, const struct typec_altmode_desc *desc);
 void typec_mux_put(struct typec_mux *mux);
-int typec_mux_register(struct typec_mux *mux);
+struct typec_mux *
+typec_mux_register(struct device *parent, const struct typec_mux_desc *desc);
 void typec_mux_unregister(struct typec_mux *mux);
 
+void *typec_mux_get_drvdata(struct typec_mux *mux);
+
 #endif /* __USB_TYPEC_MUX */

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

* Re: [PATCH] usb: typec: Registering real device entries for the muxes
@ 2019-04-01 10:34   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 14+ messages in thread
From: Greg KH @ 2019-04-01 10:34 UTC (permalink / raw)
  To: Heikki Krogerus; +Cc: Hans de Goede, linux-usb, stable

On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> Registering real device entries (struct device) for the mode
> muxes as well as for the orientation switches.
> 
> The Type-C mux code was deliberately attempting to avoid
> creation of separate device entries for the orientation
> switch and the mode switch (alternate modes) because they
> are not physical devices. They are functions of a single
> physical multiplexer/demultiplexer switch device.
> 
> Unfortunately because of the dependency we still have on the
> underlying mux device driver, we had to put in hacks like
> the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> care of driver module reference counting") to make sure the
> driver does not disappear from underneath us. Even with
> those hacks we were still left with a potential NUll pointer
> dereference scenario, so just creating the device entries,
> and letting the core take care of the dependencies. No more
> hacks needed.
> 
> Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

This looks good to me, nice work!

But, it would be nice if someone who has this hardware can test it to
verify it does actually work :)

thanks,

greg k-h

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

* usb: typec: Registering real device entries for the muxes
@ 2019-04-01 10:34   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 14+ messages in thread
From: Greg Kroah-Hartman @ 2019-04-01 10:34 UTC (permalink / raw)
  To: Heikki Krogerus; +Cc: Hans de Goede, linux-usb, stable

On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> Registering real device entries (struct device) for the mode
> muxes as well as for the orientation switches.
> 
> The Type-C mux code was deliberately attempting to avoid
> creation of separate device entries for the orientation
> switch and the mode switch (alternate modes) because they
> are not physical devices. They are functions of a single
> physical multiplexer/demultiplexer switch device.
> 
> Unfortunately because of the dependency we still have on the
> underlying mux device driver, we had to put in hacks like
> the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> care of driver module reference counting") to make sure the
> driver does not disappear from underneath us. Even with
> those hacks we were still left with a potential NUll pointer
> dereference scenario, so just creating the device entries,
> and letting the core take care of the dependencies. No more
> hacks needed.
> 
> Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

This looks good to me, nice work!

But, it would be nice if someone who has this hardware can test it to
verify it does actually work :)

thanks,

greg k-h

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

* Re: [PATCH] usb: typec: Registering real device entries for the muxes
@ 2019-04-01 12:40     ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-01 12:40 UTC (permalink / raw)
  To: Greg KH; +Cc: Hans de Goede, linux-usb, stable

On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
> On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> > Registering real device entries (struct device) for the mode
> > muxes as well as for the orientation switches.
> > 
> > The Type-C mux code was deliberately attempting to avoid
> > creation of separate device entries for the orientation
> > switch and the mode switch (alternate modes) because they
> > are not physical devices. They are functions of a single
> > physical multiplexer/demultiplexer switch device.
> > 
> > Unfortunately because of the dependency we still have on the
> > underlying mux device driver, we had to put in hacks like
> > the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> > care of driver module reference counting") to make sure the
> > driver does not disappear from underneath us. Even with
> > those hacks we were still left with a potential NUll pointer
> > dereference scenario, so just creating the device entries,
> > and letting the core take care of the dependencies. No more
> > hacks needed.
> > 
> > Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> > Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> 
> This looks good to me, nice work!
> 
> But, it would be nice if someone who has this hardware can test it to
> verify it does actually work :)

This alone does not work on Intel Cherrytrail platforms. I need to make
the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
device names that we now have for the muxes. Sorry for the mistake.

I'll resend this and include the needed modifications to
intel_cht_int33fe.c. Hans should be able to test this once I do that. I
hope he has time.


thanks,

-- 
heikki

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

* usb: typec: Registering real device entries for the muxes
@ 2019-04-01 12:40     ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-01 12:40 UTC (permalink / raw)
  To: Greg KH; +Cc: Hans de Goede, linux-usb, stable

On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
> On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> > Registering real device entries (struct device) for the mode
> > muxes as well as for the orientation switches.
> > 
> > The Type-C mux code was deliberately attempting to avoid
> > creation of separate device entries for the orientation
> > switch and the mode switch (alternate modes) because they
> > are not physical devices. They are functions of a single
> > physical multiplexer/demultiplexer switch device.
> > 
> > Unfortunately because of the dependency we still have on the
> > underlying mux device driver, we had to put in hacks like
> > the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> > care of driver module reference counting") to make sure the
> > driver does not disappear from underneath us. Even with
> > those hacks we were still left with a potential NUll pointer
> > dereference scenario, so just creating the device entries,
> > and letting the core take care of the dependencies. No more
> > hacks needed.
> > 
> > Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> > Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> 
> This looks good to me, nice work!
> 
> But, it would be nice if someone who has this hardware can test it to
> verify it does actually work :)

This alone does not work on Intel Cherrytrail platforms. I need to make
the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
device names that we now have for the muxes. Sorry for the mistake.

I'll resend this and include the needed modifications to
intel_cht_int33fe.c. Hans should be able to test this once I do that. I
hope he has time.


thanks,

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

* Re: [PATCH] usb: typec: Registering real device entries for the muxes
@ 2019-04-01 12:45       ` Hans de Goede
  0 siblings, 0 replies; 14+ messages in thread
From: Hans de Goede @ 2019-04-01 12:45 UTC (permalink / raw)
  To: Heikki Krogerus, Greg KH; +Cc: linux-usb, stable

HI,

On 01-04-19 14:40, Heikki Krogerus wrote:
> On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
>> On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
>>> Registering real device entries (struct device) for the mode
>>> muxes as well as for the orientation switches.
>>>
>>> The Type-C mux code was deliberately attempting to avoid
>>> creation of separate device entries for the orientation
>>> switch and the mode switch (alternate modes) because they
>>> are not physical devices. They are functions of a single
>>> physical multiplexer/demultiplexer switch device.
>>>
>>> Unfortunately because of the dependency we still have on the
>>> underlying mux device driver, we had to put in hacks like
>>> the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
>>> care of driver module reference counting") to make sure the
>>> driver does not disappear from underneath us. Even with
>>> those hacks we were still left with a potential NUll pointer
>>> dereference scenario, so just creating the device entries,
>>> and letting the core take care of the dependencies. No more
>>> hacks needed.
>>>
>>> Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
>>> Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
>>> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
>>
>> This looks good to me, nice work!
>>
>> But, it would be nice if someone who has this hardware can test it to
>> verify it does actually work :)
> 
> This alone does not work on Intel Cherrytrail platforms. I need to make
> the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
> device names that we now have for the muxes. Sorry for the mistake.
> 
> I'll resend this and include the needed modifications to
> intel_cht_int33fe.c. Hans should be able to test this once I do that. I
> hope he has time.

Yes I need to get back to the CherryTrail Type-C stuff we discussed a while
back anyways. On which tree/branch should I test v2 of this patch(series) ?

Regards,

Hans

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

* usb: typec: Registering real device entries for the muxes
@ 2019-04-01 12:45       ` Hans de Goede
  0 siblings, 0 replies; 14+ messages in thread
From: Hans de Goede @ 2019-04-01 12:45 UTC (permalink / raw)
  To: Heikki Krogerus, Greg KH; +Cc: linux-usb, stable

HI,

On 01-04-19 14:40, Heikki Krogerus wrote:
> On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
>> On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
>>> Registering real device entries (struct device) for the mode
>>> muxes as well as for the orientation switches.
>>>
>>> The Type-C mux code was deliberately attempting to avoid
>>> creation of separate device entries for the orientation
>>> switch and the mode switch (alternate modes) because they
>>> are not physical devices. They are functions of a single
>>> physical multiplexer/demultiplexer switch device.
>>>
>>> Unfortunately because of the dependency we still have on the
>>> underlying mux device driver, we had to put in hacks like
>>> the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
>>> care of driver module reference counting") to make sure the
>>> driver does not disappear from underneath us. Even with
>>> those hacks we were still left with a potential NUll pointer
>>> dereference scenario, so just creating the device entries,
>>> and letting the core take care of the dependencies. No more
>>> hacks needed.
>>>
>>> Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
>>> Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
>>> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
>>
>> This looks good to me, nice work!
>>
>> But, it would be nice if someone who has this hardware can test it to
>> verify it does actually work :)
> 
> This alone does not work on Intel Cherrytrail platforms. I need to make
> the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
> device names that we now have for the muxes. Sorry for the mistake.
> 
> I'll resend this and include the needed modifications to
> intel_cht_int33fe.c. Hans should be able to test this once I do that. I
> hope he has time.

Yes I need to get back to the CherryTrail Type-C stuff we discussed a while
back anyways. On which tree/branch should I test v2 of this patch(series) ?

Regards,

Hans

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

* Re: [PATCH] usb: typec: Registering real device entries for the muxes
@ 2019-04-02  7:35   ` kbuild test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2019-04-02  7:35 UTC (permalink / raw)
  To: Heikki Krogerus; +Cc: kbuild-all, Greg KH, Hans de Goede, linux-usb, stable

[-- Attachment #1: Type: text/plain, Size: 30782 bytes --]

Hi Heikki,

I love your patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v5.1-rc3 next-20190401]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Heikki-Krogerus/usb-typec-Registering-real-device-entries-for-the-muxes/20190402-030003
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   WARNING: convert(1) not found, for SVG to PDF conversion install ImageMagick (https://www.imagemagick.org)
   include/linux/generic-radix-tree.h:1: warning: no structured comments found
   kernel/rcu/tree_plugin.h:1: warning: no structured comments found
   kernel/rcu/tree_plugin.h:1: warning: no structured comments found
   include/linux/firmware/intel/stratix10-svc-client.h:1: warning: no structured comments found
   include/linux/gpio/driver.h:371: warning: Function parameter or member 'init_valid_mask' not described in 'gpio_chip'
   include/linux/i2c.h:343: warning: Function parameter or member 'init_irq' not described in 'i2c_client'
   include/linux/iio/hw-consumer.h:1: warning: no structured comments found
   include/linux/input/sparse-keymap.h:46: warning: Function parameter or member 'sw' not described in 'key_entry'
   include/linux/regulator/machine.h:199: warning: Function parameter or member 'max_uV_step' not described in 'regulation_constraints'
   include/linux/regulator/driver.h:228: warning: Function parameter or member 'resume' not described in 'regulator_ops'
   drivers/slimbus/stream.c:1: warning: no structured comments found
   include/linux/spi/spi.h:188: warning: Function parameter or member 'driver_override' not described in 'spi_device'
   drivers/target/target_core_device.c:1: warning: no structured comments found
>> drivers/usb/typec/mux.c:106: warning: Function parameter or member 'parent' not described in 'typec_switch_register'
>> drivers/usb/typec/mux.c:106: warning: Function parameter or member 'desc' not described in 'typec_switch_register'
   drivers/usb/typec/mux.c:106: warning: Excess function parameter 'sw' description in 'typec_switch_register'
>> drivers/usb/typec/mux.c:281: warning: Function parameter or member 'parent' not described in 'typec_mux_register'
>> drivers/usb/typec/mux.c:281: warning: Function parameter or member 'desc' not described in 'typec_mux_register'
   drivers/usb/typec/mux.c:281: warning: Excess function parameter 'mux' description in 'typec_mux_register'
   drivers/usb/typec/bus.c:1: warning: no structured comments found
   drivers/usb/typec/class.c:1: warning: no structured comments found
   include/linux/w1.h:281: warning: Function parameter or member 'of_match_table' not described in 'w1_family'
   fs/direct-io.c:257: warning: Excess function parameter 'offset' description in 'dio_complete'
   fs/file_table.c:1: warning: no structured comments found
   fs/libfs.c:477: warning: Excess function parameter 'available' description in 'simple_write_end'
   fs/posix_acl.c:646: warning: Function parameter or member 'inode' not described in 'posix_acl_update_mode'
   fs/posix_acl.c:646: warning: Function parameter or member 'mode_p' not described in 'posix_acl_update_mode'
   fs/posix_acl.c:646: warning: Function parameter or member 'acl' not described in 'posix_acl_update_mode'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:294: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:294: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:294: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:343: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:343: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:343: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:183: warning: Function parameter or member 'blockable' not described in 'amdgpu_mn_read_lock'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Function parameter or member 'range' not described in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Function parameter or member 'range' not described in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:374: warning: cannot understand function prototype: 'struct amdgpu_vm_pt_cursor '
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:375: warning: cannot understand function prototype: 'struct amdgpu_vm_pt_cursor '
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'adev' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'vm' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'start' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'end' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'cursor' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'adev' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'vm' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'cursor' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'entry' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:868: warning: Function parameter or member 'level' not described in 'amdgpu_vm_bo_param'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'params' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'bo' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'pe' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'addr' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'count' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'incr' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'flags' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'params' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'bo' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'level' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'pe' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'addr' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'count' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'incr' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'flags' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:3107: warning: Function parameter or member 'pasid' not described in 'amdgpu_vm_make_compute'
   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:375: warning: Excess function parameter 'entry' description in 'amdgpu_irq_dispatch'
   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:376: warning: Function parameter or member 'ih' not described in 'amdgpu_irq_dispatch'
   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:376: warning: Excess function parameter 'entry' description in 'amdgpu_irq_dispatch'
   drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:1: warning: no structured comments found
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:128: warning: Incorrect use of kernel-doc format: Documentation Makefile include scripts source @atomic_obj
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'atomic_obj' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'atomic_obj_lock' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'backlight_link' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'backlight_caps' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'freesync_module' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'fw_dmcu' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'dmcu_fw_version' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:1: warning: no structured comments found
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_pin' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_unpin' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_res_obj' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_get_sg_table' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_import_sg_table' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_vmap' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_vunmap' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_mmap' not described in 'drm_driver'
   include/drm/drm_atomic_state_helper.h:1: warning: no structured comments found
   drivers/gpu/drm/scheduler/sched_main.c:376: warning: Excess function parameter 'bad' description in 'drm_sched_stop'
   drivers/gpu/drm/scheduler/sched_main.c:377: warning: Excess function parameter 'bad' description in 'drm_sched_stop'
   drivers/gpu/drm/scheduler/sched_main.c:420: warning: Function parameter or member 'full_recovery' not described in 'drm_sched_start'
   drivers/gpu/drm/i915/i915_vma.h:50: warning: cannot understand function prototype: 'struct i915_vma '
   drivers/gpu/drm/i915/i915_vma.h:1: warning: no structured comments found
   drivers/gpu/drm/i915/intel_guc_fwif.h:536: warning: cannot understand function prototype: 'struct guc_log_buffer_state '
   drivers/gpu/drm/i915/i915_trace.h:1: warning: no structured comments found
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:126: warning: Function parameter or member 'hw_id' not described in 'komeda_component'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:126: warning: Function parameter or member 'max_active_outputs' not described in 'komeda_component'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:126: warning: Function parameter or member 'supported_outputs' not described in 'komeda_component'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:142: warning: Function parameter or member 'output_port' not described in 'komeda_component_output'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'component' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'crtc' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'plane' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'wb_conn' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'changed_active_inputs' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'affected_inputs' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'n_layers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'layers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'n_scalers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'scalers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'compiz' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'wb_layer' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'improc' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'ctrlr' not described in 'komeda_pipeline'

vim +106 drivers/usb/typec/mux.c

e900bf53 Heikki Krogerus 2019-04-01   93  
bdecb33a Heikki Krogerus 2018-03-20   94  /**
bdecb33a Heikki Krogerus 2018-03-20   95   * typec_switch_register - Register USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20   96   * @sw: USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20   97   *
bdecb33a Heikki Krogerus 2018-03-20   98   * This function registers a switch that can be used for routing the correct
bdecb33a Heikki Krogerus 2018-03-20   99   * data pairs depending on the cable plug orientation from the USB Type-C
bdecb33a Heikki Krogerus 2018-03-20  100   * connector to the USB controllers. USB Type-C plugs can be inserted
bdecb33a Heikki Krogerus 2018-03-20  101   * right-side-up or upside-down.
bdecb33a Heikki Krogerus 2018-03-20  102   */
e900bf53 Heikki Krogerus 2019-04-01  103  struct typec_switch *
e900bf53 Heikki Krogerus 2019-04-01  104  typec_switch_register(struct device *parent,
e900bf53 Heikki Krogerus 2019-04-01  105  		      const struct typec_switch_desc *desc)
bdecb33a Heikki Krogerus 2018-03-20 @106  {
e900bf53 Heikki Krogerus 2019-04-01  107  	struct typec_switch *sw;
e900bf53 Heikki Krogerus 2019-04-01  108  	int ret;
e900bf53 Heikki Krogerus 2019-04-01  109  
e900bf53 Heikki Krogerus 2019-04-01  110  	if (!desc || !desc->set)
e900bf53 Heikki Krogerus 2019-04-01  111  		return ERR_PTR(-EINVAL);
e900bf53 Heikki Krogerus 2019-04-01  112  
e900bf53 Heikki Krogerus 2019-04-01  113  	sw = kzalloc(sizeof(*sw), GFP_KERNEL);
e900bf53 Heikki Krogerus 2019-04-01  114  	if (!sw)
e900bf53 Heikki Krogerus 2019-04-01  115  		return ERR_PTR(-ENOMEM);
e900bf53 Heikki Krogerus 2019-04-01  116  
e900bf53 Heikki Krogerus 2019-04-01  117  	sw->set = desc->set;
e900bf53 Heikki Krogerus 2019-04-01  118  
e900bf53 Heikki Krogerus 2019-04-01  119  	device_initialize(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  120  	sw->dev.parent = parent;
e900bf53 Heikki Krogerus 2019-04-01  121  	sw->dev.class = &typec_mux_class;
e900bf53 Heikki Krogerus 2019-04-01  122  	sw->dev.type = &typec_switch_dev_type;
e900bf53 Heikki Krogerus 2019-04-01  123  	sw->dev.driver_data = desc->drvdata;
e900bf53 Heikki Krogerus 2019-04-01  124  	sw->dev.fwnode = desc->fwnode;
e900bf53 Heikki Krogerus 2019-04-01  125  	dev_set_name(&sw->dev, "%s-switch", dev_name(parent));
e900bf53 Heikki Krogerus 2019-04-01  126  
e900bf53 Heikki Krogerus 2019-04-01  127  	ret = device_add(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  128  	if (ret) {
e900bf53 Heikki Krogerus 2019-04-01  129  		dev_err(parent, "failed to register switch (%d)\n", ret);
e900bf53 Heikki Krogerus 2019-04-01  130  		put_device(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  131  		return ERR_PTR(ret);
e900bf53 Heikki Krogerus 2019-04-01  132  	}
bdecb33a Heikki Krogerus 2018-03-20  133  
e900bf53 Heikki Krogerus 2019-04-01  134  	return sw;
bdecb33a Heikki Krogerus 2018-03-20  135  }
bdecb33a Heikki Krogerus 2018-03-20  136  EXPORT_SYMBOL_GPL(typec_switch_register);
bdecb33a Heikki Krogerus 2018-03-20  137  
bdecb33a Heikki Krogerus 2018-03-20  138  /**
bdecb33a Heikki Krogerus 2018-03-20  139   * typec_switch_unregister - Unregister USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20  140   * @sw: USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20  141   *
bdecb33a Heikki Krogerus 2018-03-20  142   * Unregister switch that was registered with typec_switch_register().
bdecb33a Heikki Krogerus 2018-03-20  143   */
bdecb33a Heikki Krogerus 2018-03-20  144  void typec_switch_unregister(struct typec_switch *sw)
bdecb33a Heikki Krogerus 2018-03-20  145  {
e900bf53 Heikki Krogerus 2019-04-01  146  	if (!IS_ERR_OR_NULL(sw))
e900bf53 Heikki Krogerus 2019-04-01  147  		device_unregister(&sw->dev);
bdecb33a Heikki Krogerus 2018-03-20  148  }
bdecb33a Heikki Krogerus 2018-03-20  149  EXPORT_SYMBOL_GPL(typec_switch_unregister);
bdecb33a Heikki Krogerus 2018-03-20  150  
e900bf53 Heikki Krogerus 2019-04-01  151  void *typec_switch_get_drvdata(struct typec_switch *sw)
e900bf53 Heikki Krogerus 2019-04-01  152  {
e900bf53 Heikki Krogerus 2019-04-01  153  	return dev_get_drvdata(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  154  }
e900bf53 Heikki Krogerus 2019-04-01  155  EXPORT_SYMBOL_GPL(typec_switch_get_drvdata);
e900bf53 Heikki Krogerus 2019-04-01  156  
bdecb33a Heikki Krogerus 2018-03-20  157  /* ------------------------------------------------------------------------- */
bdecb33a Heikki Krogerus 2018-03-20  158  
bdecb33a Heikki Krogerus 2018-03-20  159  static void *typec_mux_match(struct device_connection *con, int ep, void *data)
bdecb33a Heikki Krogerus 2018-03-20  160  {
96a6d031 Heikki Krogerus 2019-02-13  161  	const struct typec_altmode_desc *desc = data;
e900bf53 Heikki Krogerus 2019-04-01  162  	struct device *dev;
96a6d031 Heikki Krogerus 2019-02-13  163  	bool match;
e900bf53 Heikki Krogerus 2019-04-01  164  	int nval;
96a6d031 Heikki Krogerus 2019-02-13  165  	u16 *val;
96a6d031 Heikki Krogerus 2019-02-13  166  	int i;
bdecb33a Heikki Krogerus 2018-03-20  167  
96a6d031 Heikki Krogerus 2019-02-13  168  	if (!con->fwnode) {
e900bf53 Heikki Krogerus 2019-04-01  169  		dev = class_find_device(&typec_mux_class, NULL,
e900bf53 Heikki Krogerus 2019-04-01  170  					con->endpoint[ep], name_match);
e900bf53 Heikki Krogerus 2019-04-01  171  
e900bf53 Heikki Krogerus 2019-04-01  172  		return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
96a6d031 Heikki Krogerus 2019-02-13  173  	}
bdecb33a Heikki Krogerus 2018-03-20  174  
bdecb33a Heikki Krogerus 2018-03-20  175  	/*
96a6d031 Heikki Krogerus 2019-02-13  176  	 * Check has the identifier already been "consumed". If it
96a6d031 Heikki Krogerus 2019-02-13  177  	 * has, no need to do any extra connection identification.
bdecb33a Heikki Krogerus 2018-03-20  178  	 */
96a6d031 Heikki Krogerus 2019-02-13  179  	match = !con->id;
96a6d031 Heikki Krogerus 2019-02-13  180  	if (match)
96a6d031 Heikki Krogerus 2019-02-13  181  		goto find_mux;
96a6d031 Heikki Krogerus 2019-02-13  182  
96a6d031 Heikki Krogerus 2019-02-13  183  	/* Accessory Mode muxes */
96a6d031 Heikki Krogerus 2019-02-13  184  	if (!desc) {
96a6d031 Heikki Krogerus 2019-02-13  185  		match = fwnode_property_present(con->fwnode, "accessory");
96a6d031 Heikki Krogerus 2019-02-13  186  		if (match)
96a6d031 Heikki Krogerus 2019-02-13  187  			goto find_mux;
96a6d031 Heikki Krogerus 2019-02-13  188  		return NULL;
96a6d031 Heikki Krogerus 2019-02-13  189  	}
96a6d031 Heikki Krogerus 2019-02-13  190  
96a6d031 Heikki Krogerus 2019-02-13  191  	/* Alternate Mode muxes */
96a6d031 Heikki Krogerus 2019-02-13  192  	nval = fwnode_property_read_u16_array(con->fwnode, "svid", NULL, 0);
96a6d031 Heikki Krogerus 2019-02-13  193  	if (nval <= 0)
96a6d031 Heikki Krogerus 2019-02-13  194  		return NULL;
96a6d031 Heikki Krogerus 2019-02-13  195  
96a6d031 Heikki Krogerus 2019-02-13  196  	val = kcalloc(nval, sizeof(*val), GFP_KERNEL);
96a6d031 Heikki Krogerus 2019-02-13  197  	if (!val)
96a6d031 Heikki Krogerus 2019-02-13  198  		return ERR_PTR(-ENOMEM);
96a6d031 Heikki Krogerus 2019-02-13  199  
96a6d031 Heikki Krogerus 2019-02-13  200  	nval = fwnode_property_read_u16_array(con->fwnode, "svid", val, nval);
96a6d031 Heikki Krogerus 2019-02-13  201  	if (nval < 0) {
96a6d031 Heikki Krogerus 2019-02-13  202  		kfree(val);
96a6d031 Heikki Krogerus 2019-02-13  203  		return ERR_PTR(nval);
96a6d031 Heikki Krogerus 2019-02-13  204  	}
96a6d031 Heikki Krogerus 2019-02-13  205  
96a6d031 Heikki Krogerus 2019-02-13  206  	for (i = 0; i < nval; i++) {
96a6d031 Heikki Krogerus 2019-02-13  207  		match = val[i] == desc->svid;
96a6d031 Heikki Krogerus 2019-02-13  208  		if (match) {
96a6d031 Heikki Krogerus 2019-02-13  209  			kfree(val);
96a6d031 Heikki Krogerus 2019-02-13  210  			goto find_mux;
96a6d031 Heikki Krogerus 2019-02-13  211  		}
96a6d031 Heikki Krogerus 2019-02-13  212  	}
96a6d031 Heikki Krogerus 2019-02-13  213  	kfree(val);
96a6d031 Heikki Krogerus 2019-02-13  214  	return NULL;
96a6d031 Heikki Krogerus 2019-02-13  215  
96a6d031 Heikki Krogerus 2019-02-13  216  find_mux:
e900bf53 Heikki Krogerus 2019-04-01  217  	dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
e900bf53 Heikki Krogerus 2019-04-01  218  				fwnode_match);
96a6d031 Heikki Krogerus 2019-02-13  219  
e900bf53 Heikki Krogerus 2019-04-01  220  	return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
bdecb33a Heikki Krogerus 2018-03-20  221  }
bdecb33a Heikki Krogerus 2018-03-20  222  
bdecb33a Heikki Krogerus 2018-03-20  223  /**
bdecb33a Heikki Krogerus 2018-03-20  224   * typec_mux_get - Find USB Type-C Multiplexer
bdecb33a Heikki Krogerus 2018-03-20  225   * @dev: The caller device
540bfab7 Heikki Krogerus 2019-02-13  226   * @desc: Alt Mode description
bdecb33a Heikki Krogerus 2018-03-20  227   *
bdecb33a Heikki Krogerus 2018-03-20  228   * Finds a mux linked to the caller. This function is primarily meant for the
bdecb33a Heikki Krogerus 2018-03-20  229   * Type-C drivers. Returns a reference to the mux on success, NULL if no
bdecb33a Heikki Krogerus 2018-03-20  230   * matching connection was found, or ERR_PTR(-EPROBE_DEFER) when a connection
bdecb33a Heikki Krogerus 2018-03-20  231   * was found but the mux has not been enumerated yet.
bdecb33a Heikki Krogerus 2018-03-20  232   */
540bfab7 Heikki Krogerus 2019-02-13  233  struct typec_mux *typec_mux_get(struct device *dev,
540bfab7 Heikki Krogerus 2019-02-13  234  				const struct typec_altmode_desc *desc)
bdecb33a Heikki Krogerus 2018-03-20  235  {
bdecb33a Heikki Krogerus 2018-03-20  236  	struct typec_mux *mux;
bdecb33a Heikki Krogerus 2018-03-20  237  
540bfab7 Heikki Krogerus 2019-02-13  238  	mux = device_connection_find_match(dev, "mode-switch", (void *)desc,
540bfab7 Heikki Krogerus 2019-02-13  239  					   typec_mux_match);
e900bf53 Heikki Krogerus 2019-04-01  240  	if (!IS_ERR_OR_NULL(mux))
e900bf53 Heikki Krogerus 2019-04-01  241  		get_device(&mux->dev);
bdecb33a Heikki Krogerus 2018-03-20  242  
bdecb33a Heikki Krogerus 2018-03-20  243  	return mux;
bdecb33a Heikki Krogerus 2018-03-20  244  }
bdecb33a Heikki Krogerus 2018-03-20  245  EXPORT_SYMBOL_GPL(typec_mux_get);
bdecb33a Heikki Krogerus 2018-03-20  246  
bdecb33a Heikki Krogerus 2018-03-20  247  /**
bdecb33a Heikki Krogerus 2018-03-20  248   * typec_mux_put - Release handle to a Multiplexer
bdecb33a Heikki Krogerus 2018-03-20  249   * @mux: USB Type-C Connector Multiplexer/DeMultiplexer
bdecb33a Heikki Krogerus 2018-03-20  250   *
bdecb33a Heikki Krogerus 2018-03-20  251   * Decrements reference count for @mux.
bdecb33a Heikki Krogerus 2018-03-20  252   */
bdecb33a Heikki Krogerus 2018-03-20  253  void typec_mux_put(struct typec_mux *mux)
bdecb33a Heikki Krogerus 2018-03-20  254  {
e900bf53 Heikki Krogerus 2019-04-01  255  	if (!IS_ERR_OR_NULL(mux))
e900bf53 Heikki Krogerus 2019-04-01  256  		put_device(&mux->dev);
3e3b8196 Heikki Krogerus 2018-09-19  257  }
bdecb33a Heikki Krogerus 2018-03-20  258  EXPORT_SYMBOL_GPL(typec_mux_put);
bdecb33a Heikki Krogerus 2018-03-20  259  
e900bf53 Heikki Krogerus 2019-04-01  260  static void typec_mux_release(struct device *dev)
e900bf53 Heikki Krogerus 2019-04-01  261  {
e900bf53 Heikki Krogerus 2019-04-01  262  	kfree(to_typec_mux(dev));
e900bf53 Heikki Krogerus 2019-04-01  263  }
e900bf53 Heikki Krogerus 2019-04-01  264  
e900bf53 Heikki Krogerus 2019-04-01  265  static const struct device_type typec_mux_dev_type = {
e900bf53 Heikki Krogerus 2019-04-01  266  	.name = "mode_switch",
e900bf53 Heikki Krogerus 2019-04-01  267  	.release = typec_mux_release,
e900bf53 Heikki Krogerus 2019-04-01  268  };
e900bf53 Heikki Krogerus 2019-04-01  269  
bdecb33a Heikki Krogerus 2018-03-20  270  /**
bdecb33a Heikki Krogerus 2018-03-20  271   * typec_mux_register - Register Multiplexer routing USB Type-C pins
bdecb33a Heikki Krogerus 2018-03-20  272   * @mux: USB Type-C Connector Multiplexer/DeMultiplexer
bdecb33a Heikki Krogerus 2018-03-20  273   *
bdecb33a Heikki Krogerus 2018-03-20  274   * USB Type-C connectors can be used for alternate modes of operation besides
bdecb33a Heikki Krogerus 2018-03-20  275   * USB when Accessory/Alternate Modes are supported. With some of those modes,
bdecb33a Heikki Krogerus 2018-03-20  276   * the pins on the connector need to be reconfigured. This function registers
bdecb33a Heikki Krogerus 2018-03-20  277   * multiplexer switches routing the pins on the connector.
bdecb33a Heikki Krogerus 2018-03-20  278   */
e900bf53 Heikki Krogerus 2019-04-01  279  struct typec_mux *
e900bf53 Heikki Krogerus 2019-04-01  280  typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
bdecb33a Heikki Krogerus 2018-03-20 @281  {
e900bf53 Heikki Krogerus 2019-04-01  282  	struct typec_mux *mux;
e900bf53 Heikki Krogerus 2019-04-01  283  	int ret;
e900bf53 Heikki Krogerus 2019-04-01  284  
e900bf53 Heikki Krogerus 2019-04-01  285  	if (!desc || !desc->set)
e900bf53 Heikki Krogerus 2019-04-01  286  		return ERR_PTR(-EINVAL);
bdecb33a Heikki Krogerus 2018-03-20  287  
e900bf53 Heikki Krogerus 2019-04-01  288  	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
e900bf53 Heikki Krogerus 2019-04-01  289  	if (!mux)
e900bf53 Heikki Krogerus 2019-04-01  290  		return ERR_PTR(-ENOMEM);
e900bf53 Heikki Krogerus 2019-04-01  291  
e900bf53 Heikki Krogerus 2019-04-01  292  	mux->set = desc->set;
e900bf53 Heikki Krogerus 2019-04-01  293  
e900bf53 Heikki Krogerus 2019-04-01  294  	device_initialize(&mux->dev);
e900bf53 Heikki Krogerus 2019-04-01  295  	mux->dev.parent = parent;
e900bf53 Heikki Krogerus 2019-04-01  296  	mux->dev.class = &typec_mux_class;
e900bf53 Heikki Krogerus 2019-04-01  297  	mux->dev.type = &typec_mux_dev_type;
e900bf53 Heikki Krogerus 2019-04-01  298  	mux->dev.fwnode = desc->fwnode;
e900bf53 Heikki Krogerus 2019-04-01  299  	mux->dev.driver_data = desc->drvdata;
e900bf53 Heikki Krogerus 2019-04-01  300  	dev_set_name(&mux->dev, "%s-mux", dev_name(parent));
e900bf53 Heikki Krogerus 2019-04-01  301  
e900bf53 Heikki Krogerus 2019-04-01  302  	ret = device_add(&mux->dev);
e900bf53 Heikki Krogerus 2019-04-01  303  	if (ret) {
e900bf53 Heikki Krogerus 2019-04-01  304  		dev_err(parent, "failed to register mux (%d)\n", ret);
e900bf53 Heikki Krogerus 2019-04-01  305  		put_device(&mux->dev);
e900bf53 Heikki Krogerus 2019-04-01  306  		return ERR_PTR(ret);
e900bf53 Heikki Krogerus 2019-04-01  307  	}
e900bf53 Heikki Krogerus 2019-04-01  308  
e900bf53 Heikki Krogerus 2019-04-01  309  	return mux;
bdecb33a Heikki Krogerus 2018-03-20  310  }
bdecb33a Heikki Krogerus 2018-03-20  311  EXPORT_SYMBOL_GPL(typec_mux_register);
bdecb33a Heikki Krogerus 2018-03-20  312  

:::::: The code at line 106 was first introduced by commit
:::::: bdecb33af34f79cbfbb656661210f77c8b8b5b5f usb: typec: API for controlling USB Type-C Multiplexers

:::::: TO: Heikki Krogerus <heikki.krogerus@linux.intel.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6696 bytes --]

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

* usb: typec: Registering real device entries for the muxes
@ 2019-04-02  7:35   ` kbuild test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2019-04-02  7:35 UTC (permalink / raw)
  To: Heikki Krogerus; +Cc: kbuild-all, Greg KH, Hans de Goede, linux-usb, stable

Hi Heikki,

I love your patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v5.1-rc3 next-20190401]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Heikki-Krogerus/usb-typec-Registering-real-device-entries-for-the-muxes/20190402-030003
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   WARNING: convert(1) not found, for SVG to PDF conversion install ImageMagick (https://www.imagemagick.org)
   include/linux/generic-radix-tree.h:1: warning: no structured comments found
   kernel/rcu/tree_plugin.h:1: warning: no structured comments found
   kernel/rcu/tree_plugin.h:1: warning: no structured comments found
   include/linux/firmware/intel/stratix10-svc-client.h:1: warning: no structured comments found
   include/linux/gpio/driver.h:371: warning: Function parameter or member 'init_valid_mask' not described in 'gpio_chip'
   include/linux/i2c.h:343: warning: Function parameter or member 'init_irq' not described in 'i2c_client'
   include/linux/iio/hw-consumer.h:1: warning: no structured comments found
   include/linux/input/sparse-keymap.h:46: warning: Function parameter or member 'sw' not described in 'key_entry'
   include/linux/regulator/machine.h:199: warning: Function parameter or member 'max_uV_step' not described in 'regulation_constraints'
   include/linux/regulator/driver.h:228: warning: Function parameter or member 'resume' not described in 'regulator_ops'
   drivers/slimbus/stream.c:1: warning: no structured comments found
   include/linux/spi/spi.h:188: warning: Function parameter or member 'driver_override' not described in 'spi_device'
   drivers/target/target_core_device.c:1: warning: no structured comments found
>> drivers/usb/typec/mux.c:106: warning: Function parameter or member 'parent' not described in 'typec_switch_register'
>> drivers/usb/typec/mux.c:106: warning: Function parameter or member 'desc' not described in 'typec_switch_register'
   drivers/usb/typec/mux.c:106: warning: Excess function parameter 'sw' description in 'typec_switch_register'
>> drivers/usb/typec/mux.c:281: warning: Function parameter or member 'parent' not described in 'typec_mux_register'
>> drivers/usb/typec/mux.c:281: warning: Function parameter or member 'desc' not described in 'typec_mux_register'
   drivers/usb/typec/mux.c:281: warning: Excess function parameter 'mux' description in 'typec_mux_register'
   drivers/usb/typec/bus.c:1: warning: no structured comments found
   drivers/usb/typec/class.c:1: warning: no structured comments found
   include/linux/w1.h:281: warning: Function parameter or member 'of_match_table' not described in 'w1_family'
   fs/direct-io.c:257: warning: Excess function parameter 'offset' description in 'dio_complete'
   fs/file_table.c:1: warning: no structured comments found
   fs/libfs.c:477: warning: Excess function parameter 'available' description in 'simple_write_end'
   fs/posix_acl.c:646: warning: Function parameter or member 'inode' not described in 'posix_acl_update_mode'
   fs/posix_acl.c:646: warning: Function parameter or member 'mode_p' not described in 'posix_acl_update_mode'
   fs/posix_acl.c:646: warning: Function parameter or member 'acl' not described in 'posix_acl_update_mode'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:294: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:294: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:294: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:343: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:343: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:343: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:183: warning: Function parameter or member 'blockable' not described in 'amdgpu_mn_read_lock'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Function parameter or member 'range' not described in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:295: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_start_hsa'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Function parameter or member 'range' not described in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Excess function parameter 'mm' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Excess function parameter 'start' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:344: warning: Excess function parameter 'end' description in 'amdgpu_mn_invalidate_range_end'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:374: warning: cannot understand function prototype: 'struct amdgpu_vm_pt_cursor '
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:375: warning: cannot understand function prototype: 'struct amdgpu_vm_pt_cursor '
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'adev' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'vm' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'start' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'end' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:547: warning: Function parameter or member 'cursor' not described in 'for_each_amdgpu_vm_pt_leaf'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'adev' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'vm' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'cursor' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:595: warning: Function parameter or member 'entry' not described in 'for_each_amdgpu_vm_pt_dfs_safe'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:868: warning: Function parameter or member 'level' not described in 'amdgpu_vm_bo_param'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'params' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'bo' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'pe' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'addr' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'count' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'incr' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1348: warning: Function parameter or member 'flags' not described in 'amdgpu_vm_update_func'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'params' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'bo' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'level' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'pe' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'addr' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'count' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'incr' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1516: warning: Function parameter or member 'flags' not described in 'amdgpu_vm_update_flags'
   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:3107: warning: Function parameter or member 'pasid' not described in 'amdgpu_vm_make_compute'
   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:375: warning: Excess function parameter 'entry' description in 'amdgpu_irq_dispatch'
   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:376: warning: Function parameter or member 'ih' not described in 'amdgpu_irq_dispatch'
   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:376: warning: Excess function parameter 'entry' description in 'amdgpu_irq_dispatch'
   drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:1: warning: no structured comments found
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:128: warning: Incorrect use of kernel-doc format: Documentation Makefile include scripts source @atomic_obj
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'atomic_obj' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'atomic_obj_lock' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'backlight_link' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'backlight_caps' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'freesync_module' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'fw_dmcu' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h:203: warning: Function parameter or member 'dmcu_fw_version' not described in 'amdgpu_display_manager'
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:1: warning: no structured comments found
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_pin' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_unpin' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_res_obj' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_get_sg_table' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_import_sg_table' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_vmap' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_vunmap' not described in 'drm_driver'
   include/drm/drm_drv.h:715: warning: Function parameter or member 'gem_prime_mmap' not described in 'drm_driver'
   include/drm/drm_atomic_state_helper.h:1: warning: no structured comments found
   drivers/gpu/drm/scheduler/sched_main.c:376: warning: Excess function parameter 'bad' description in 'drm_sched_stop'
   drivers/gpu/drm/scheduler/sched_main.c:377: warning: Excess function parameter 'bad' description in 'drm_sched_stop'
   drivers/gpu/drm/scheduler/sched_main.c:420: warning: Function parameter or member 'full_recovery' not described in 'drm_sched_start'
   drivers/gpu/drm/i915/i915_vma.h:50: warning: cannot understand function prototype: 'struct i915_vma '
   drivers/gpu/drm/i915/i915_vma.h:1: warning: no structured comments found
   drivers/gpu/drm/i915/intel_guc_fwif.h:536: warning: cannot understand function prototype: 'struct guc_log_buffer_state '
   drivers/gpu/drm/i915/i915_trace.h:1: warning: no structured comments found
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:126: warning: Function parameter or member 'hw_id' not described in 'komeda_component'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:126: warning: Function parameter or member 'max_active_outputs' not described in 'komeda_component'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:126: warning: Function parameter or member 'supported_outputs' not described in 'komeda_component'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:142: warning: Function parameter or member 'output_port' not described in 'komeda_component_output'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'component' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'crtc' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'plane' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'wb_conn' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'changed_active_inputs' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:196: warning: Function parameter or member 'affected_inputs' not described in 'komeda_component_state'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'n_layers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'layers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'n_scalers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'scalers' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'compiz' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'wb_layer' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'improc' not described in 'komeda_pipeline'
   drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h:300: warning: Function parameter or member 'ctrlr' not described in 'komeda_pipeline'

vim +106 drivers/usb/typec/mux.c

e900bf53 Heikki Krogerus 2019-04-01   93  
bdecb33a Heikki Krogerus 2018-03-20   94  /**
bdecb33a Heikki Krogerus 2018-03-20   95   * typec_switch_register - Register USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20   96   * @sw: USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20   97   *
bdecb33a Heikki Krogerus 2018-03-20   98   * This function registers a switch that can be used for routing the correct
bdecb33a Heikki Krogerus 2018-03-20   99   * data pairs depending on the cable plug orientation from the USB Type-C
bdecb33a Heikki Krogerus 2018-03-20  100   * connector to the USB controllers. USB Type-C plugs can be inserted
bdecb33a Heikki Krogerus 2018-03-20  101   * right-side-up or upside-down.
bdecb33a Heikki Krogerus 2018-03-20  102   */
e900bf53 Heikki Krogerus 2019-04-01  103  struct typec_switch *
e900bf53 Heikki Krogerus 2019-04-01  104  typec_switch_register(struct device *parent,
e900bf53 Heikki Krogerus 2019-04-01  105  		      const struct typec_switch_desc *desc)
bdecb33a Heikki Krogerus 2018-03-20 @106  {
e900bf53 Heikki Krogerus 2019-04-01  107  	struct typec_switch *sw;
e900bf53 Heikki Krogerus 2019-04-01  108  	int ret;
e900bf53 Heikki Krogerus 2019-04-01  109  
e900bf53 Heikki Krogerus 2019-04-01  110  	if (!desc || !desc->set)
e900bf53 Heikki Krogerus 2019-04-01  111  		return ERR_PTR(-EINVAL);
e900bf53 Heikki Krogerus 2019-04-01  112  
e900bf53 Heikki Krogerus 2019-04-01  113  	sw = kzalloc(sizeof(*sw), GFP_KERNEL);
e900bf53 Heikki Krogerus 2019-04-01  114  	if (!sw)
e900bf53 Heikki Krogerus 2019-04-01  115  		return ERR_PTR(-ENOMEM);
e900bf53 Heikki Krogerus 2019-04-01  116  
e900bf53 Heikki Krogerus 2019-04-01  117  	sw->set = desc->set;
e900bf53 Heikki Krogerus 2019-04-01  118  
e900bf53 Heikki Krogerus 2019-04-01  119  	device_initialize(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  120  	sw->dev.parent = parent;
e900bf53 Heikki Krogerus 2019-04-01  121  	sw->dev.class = &typec_mux_class;
e900bf53 Heikki Krogerus 2019-04-01  122  	sw->dev.type = &typec_switch_dev_type;
e900bf53 Heikki Krogerus 2019-04-01  123  	sw->dev.driver_data = desc->drvdata;
e900bf53 Heikki Krogerus 2019-04-01  124  	sw->dev.fwnode = desc->fwnode;
e900bf53 Heikki Krogerus 2019-04-01  125  	dev_set_name(&sw->dev, "%s-switch", dev_name(parent));
e900bf53 Heikki Krogerus 2019-04-01  126  
e900bf53 Heikki Krogerus 2019-04-01  127  	ret = device_add(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  128  	if (ret) {
e900bf53 Heikki Krogerus 2019-04-01  129  		dev_err(parent, "failed to register switch (%d)\n", ret);
e900bf53 Heikki Krogerus 2019-04-01  130  		put_device(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  131  		return ERR_PTR(ret);
e900bf53 Heikki Krogerus 2019-04-01  132  	}
bdecb33a Heikki Krogerus 2018-03-20  133  
e900bf53 Heikki Krogerus 2019-04-01  134  	return sw;
bdecb33a Heikki Krogerus 2018-03-20  135  }
bdecb33a Heikki Krogerus 2018-03-20  136  EXPORT_SYMBOL_GPL(typec_switch_register);
bdecb33a Heikki Krogerus 2018-03-20  137  
bdecb33a Heikki Krogerus 2018-03-20  138  /**
bdecb33a Heikki Krogerus 2018-03-20  139   * typec_switch_unregister - Unregister USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20  140   * @sw: USB Type-C orientation switch
bdecb33a Heikki Krogerus 2018-03-20  141   *
bdecb33a Heikki Krogerus 2018-03-20  142   * Unregister switch that was registered with typec_switch_register().
bdecb33a Heikki Krogerus 2018-03-20  143   */
bdecb33a Heikki Krogerus 2018-03-20  144  void typec_switch_unregister(struct typec_switch *sw)
bdecb33a Heikki Krogerus 2018-03-20  145  {
e900bf53 Heikki Krogerus 2019-04-01  146  	if (!IS_ERR_OR_NULL(sw))
e900bf53 Heikki Krogerus 2019-04-01  147  		device_unregister(&sw->dev);
bdecb33a Heikki Krogerus 2018-03-20  148  }
bdecb33a Heikki Krogerus 2018-03-20  149  EXPORT_SYMBOL_GPL(typec_switch_unregister);
bdecb33a Heikki Krogerus 2018-03-20  150  
e900bf53 Heikki Krogerus 2019-04-01  151  void *typec_switch_get_drvdata(struct typec_switch *sw)
e900bf53 Heikki Krogerus 2019-04-01  152  {
e900bf53 Heikki Krogerus 2019-04-01  153  	return dev_get_drvdata(&sw->dev);
e900bf53 Heikki Krogerus 2019-04-01  154  }
e900bf53 Heikki Krogerus 2019-04-01  155  EXPORT_SYMBOL_GPL(typec_switch_get_drvdata);
e900bf53 Heikki Krogerus 2019-04-01  156  
bdecb33a Heikki Krogerus 2018-03-20  157  /* ------------------------------------------------------------------------- */
bdecb33a Heikki Krogerus 2018-03-20  158  
bdecb33a Heikki Krogerus 2018-03-20  159  static void *typec_mux_match(struct device_connection *con, int ep, void *data)
bdecb33a Heikki Krogerus 2018-03-20  160  {
96a6d031 Heikki Krogerus 2019-02-13  161  	const struct typec_altmode_desc *desc = data;
e900bf53 Heikki Krogerus 2019-04-01  162  	struct device *dev;
96a6d031 Heikki Krogerus 2019-02-13  163  	bool match;
e900bf53 Heikki Krogerus 2019-04-01  164  	int nval;
96a6d031 Heikki Krogerus 2019-02-13  165  	u16 *val;
96a6d031 Heikki Krogerus 2019-02-13  166  	int i;
bdecb33a Heikki Krogerus 2018-03-20  167  
96a6d031 Heikki Krogerus 2019-02-13  168  	if (!con->fwnode) {
e900bf53 Heikki Krogerus 2019-04-01  169  		dev = class_find_device(&typec_mux_class, NULL,
e900bf53 Heikki Krogerus 2019-04-01  170  					con->endpoint[ep], name_match);
e900bf53 Heikki Krogerus 2019-04-01  171  
e900bf53 Heikki Krogerus 2019-04-01  172  		return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
96a6d031 Heikki Krogerus 2019-02-13  173  	}
bdecb33a Heikki Krogerus 2018-03-20  174  
bdecb33a Heikki Krogerus 2018-03-20  175  	/*
96a6d031 Heikki Krogerus 2019-02-13  176  	 * Check has the identifier already been "consumed". If it
96a6d031 Heikki Krogerus 2019-02-13  177  	 * has, no need to do any extra connection identification.
bdecb33a Heikki Krogerus 2018-03-20  178  	 */
96a6d031 Heikki Krogerus 2019-02-13  179  	match = !con->id;
96a6d031 Heikki Krogerus 2019-02-13  180  	if (match)
96a6d031 Heikki Krogerus 2019-02-13  181  		goto find_mux;
96a6d031 Heikki Krogerus 2019-02-13  182  
96a6d031 Heikki Krogerus 2019-02-13  183  	/* Accessory Mode muxes */
96a6d031 Heikki Krogerus 2019-02-13  184  	if (!desc) {
96a6d031 Heikki Krogerus 2019-02-13  185  		match = fwnode_property_present(con->fwnode, "accessory");
96a6d031 Heikki Krogerus 2019-02-13  186  		if (match)
96a6d031 Heikki Krogerus 2019-02-13  187  			goto find_mux;
96a6d031 Heikki Krogerus 2019-02-13  188  		return NULL;
96a6d031 Heikki Krogerus 2019-02-13  189  	}
96a6d031 Heikki Krogerus 2019-02-13  190  
96a6d031 Heikki Krogerus 2019-02-13  191  	/* Alternate Mode muxes */
96a6d031 Heikki Krogerus 2019-02-13  192  	nval = fwnode_property_read_u16_array(con->fwnode, "svid", NULL, 0);
96a6d031 Heikki Krogerus 2019-02-13  193  	if (nval <= 0)
96a6d031 Heikki Krogerus 2019-02-13  194  		return NULL;
96a6d031 Heikki Krogerus 2019-02-13  195  
96a6d031 Heikki Krogerus 2019-02-13  196  	val = kcalloc(nval, sizeof(*val), GFP_KERNEL);
96a6d031 Heikki Krogerus 2019-02-13  197  	if (!val)
96a6d031 Heikki Krogerus 2019-02-13  198  		return ERR_PTR(-ENOMEM);
96a6d031 Heikki Krogerus 2019-02-13  199  
96a6d031 Heikki Krogerus 2019-02-13  200  	nval = fwnode_property_read_u16_array(con->fwnode, "svid", val, nval);
96a6d031 Heikki Krogerus 2019-02-13  201  	if (nval < 0) {
96a6d031 Heikki Krogerus 2019-02-13  202  		kfree(val);
96a6d031 Heikki Krogerus 2019-02-13  203  		return ERR_PTR(nval);
96a6d031 Heikki Krogerus 2019-02-13  204  	}
96a6d031 Heikki Krogerus 2019-02-13  205  
96a6d031 Heikki Krogerus 2019-02-13  206  	for (i = 0; i < nval; i++) {
96a6d031 Heikki Krogerus 2019-02-13  207  		match = val[i] == desc->svid;
96a6d031 Heikki Krogerus 2019-02-13  208  		if (match) {
96a6d031 Heikki Krogerus 2019-02-13  209  			kfree(val);
96a6d031 Heikki Krogerus 2019-02-13  210  			goto find_mux;
96a6d031 Heikki Krogerus 2019-02-13  211  		}
96a6d031 Heikki Krogerus 2019-02-13  212  	}
96a6d031 Heikki Krogerus 2019-02-13  213  	kfree(val);
96a6d031 Heikki Krogerus 2019-02-13  214  	return NULL;
96a6d031 Heikki Krogerus 2019-02-13  215  
96a6d031 Heikki Krogerus 2019-02-13  216  find_mux:
e900bf53 Heikki Krogerus 2019-04-01  217  	dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
e900bf53 Heikki Krogerus 2019-04-01  218  				fwnode_match);
96a6d031 Heikki Krogerus 2019-02-13  219  
e900bf53 Heikki Krogerus 2019-04-01  220  	return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
bdecb33a Heikki Krogerus 2018-03-20  221  }
bdecb33a Heikki Krogerus 2018-03-20  222  
bdecb33a Heikki Krogerus 2018-03-20  223  /**
bdecb33a Heikki Krogerus 2018-03-20  224   * typec_mux_get - Find USB Type-C Multiplexer
bdecb33a Heikki Krogerus 2018-03-20  225   * @dev: The caller device
540bfab7 Heikki Krogerus 2019-02-13  226   * @desc: Alt Mode description
bdecb33a Heikki Krogerus 2018-03-20  227   *
bdecb33a Heikki Krogerus 2018-03-20  228   * Finds a mux linked to the caller. This function is primarily meant for the
bdecb33a Heikki Krogerus 2018-03-20  229   * Type-C drivers. Returns a reference to the mux on success, NULL if no
bdecb33a Heikki Krogerus 2018-03-20  230   * matching connection was found, or ERR_PTR(-EPROBE_DEFER) when a connection
bdecb33a Heikki Krogerus 2018-03-20  231   * was found but the mux has not been enumerated yet.
bdecb33a Heikki Krogerus 2018-03-20  232   */
540bfab7 Heikki Krogerus 2019-02-13  233  struct typec_mux *typec_mux_get(struct device *dev,
540bfab7 Heikki Krogerus 2019-02-13  234  				const struct typec_altmode_desc *desc)
bdecb33a Heikki Krogerus 2018-03-20  235  {
bdecb33a Heikki Krogerus 2018-03-20  236  	struct typec_mux *mux;
bdecb33a Heikki Krogerus 2018-03-20  237  
540bfab7 Heikki Krogerus 2019-02-13  238  	mux = device_connection_find_match(dev, "mode-switch", (void *)desc,
540bfab7 Heikki Krogerus 2019-02-13  239  					   typec_mux_match);
e900bf53 Heikki Krogerus 2019-04-01  240  	if (!IS_ERR_OR_NULL(mux))
e900bf53 Heikki Krogerus 2019-04-01  241  		get_device(&mux->dev);
bdecb33a Heikki Krogerus 2018-03-20  242  
bdecb33a Heikki Krogerus 2018-03-20  243  	return mux;
bdecb33a Heikki Krogerus 2018-03-20  244  }
bdecb33a Heikki Krogerus 2018-03-20  245  EXPORT_SYMBOL_GPL(typec_mux_get);
bdecb33a Heikki Krogerus 2018-03-20  246  
bdecb33a Heikki Krogerus 2018-03-20  247  /**
bdecb33a Heikki Krogerus 2018-03-20  248   * typec_mux_put - Release handle to a Multiplexer
bdecb33a Heikki Krogerus 2018-03-20  249   * @mux: USB Type-C Connector Multiplexer/DeMultiplexer
bdecb33a Heikki Krogerus 2018-03-20  250   *
bdecb33a Heikki Krogerus 2018-03-20  251   * Decrements reference count for @mux.
bdecb33a Heikki Krogerus 2018-03-20  252   */
bdecb33a Heikki Krogerus 2018-03-20  253  void typec_mux_put(struct typec_mux *mux)
bdecb33a Heikki Krogerus 2018-03-20  254  {
e900bf53 Heikki Krogerus 2019-04-01  255  	if (!IS_ERR_OR_NULL(mux))
e900bf53 Heikki Krogerus 2019-04-01  256  		put_device(&mux->dev);
3e3b8196 Heikki Krogerus 2018-09-19  257  }
bdecb33a Heikki Krogerus 2018-03-20  258  EXPORT_SYMBOL_GPL(typec_mux_put);
bdecb33a Heikki Krogerus 2018-03-20  259  
e900bf53 Heikki Krogerus 2019-04-01  260  static void typec_mux_release(struct device *dev)
e900bf53 Heikki Krogerus 2019-04-01  261  {
e900bf53 Heikki Krogerus 2019-04-01  262  	kfree(to_typec_mux(dev));
e900bf53 Heikki Krogerus 2019-04-01  263  }
e900bf53 Heikki Krogerus 2019-04-01  264  
e900bf53 Heikki Krogerus 2019-04-01  265  static const struct device_type typec_mux_dev_type = {
e900bf53 Heikki Krogerus 2019-04-01  266  	.name = "mode_switch",
e900bf53 Heikki Krogerus 2019-04-01  267  	.release = typec_mux_release,
e900bf53 Heikki Krogerus 2019-04-01  268  };
e900bf53 Heikki Krogerus 2019-04-01  269  
bdecb33a Heikki Krogerus 2018-03-20  270  /**
bdecb33a Heikki Krogerus 2018-03-20  271   * typec_mux_register - Register Multiplexer routing USB Type-C pins
bdecb33a Heikki Krogerus 2018-03-20  272   * @mux: USB Type-C Connector Multiplexer/DeMultiplexer
bdecb33a Heikki Krogerus 2018-03-20  273   *
bdecb33a Heikki Krogerus 2018-03-20  274   * USB Type-C connectors can be used for alternate modes of operation besides
bdecb33a Heikki Krogerus 2018-03-20  275   * USB when Accessory/Alternate Modes are supported. With some of those modes,
bdecb33a Heikki Krogerus 2018-03-20  276   * the pins on the connector need to be reconfigured. This function registers
bdecb33a Heikki Krogerus 2018-03-20  277   * multiplexer switches routing the pins on the connector.
bdecb33a Heikki Krogerus 2018-03-20  278   */
e900bf53 Heikki Krogerus 2019-04-01  279  struct typec_mux *
e900bf53 Heikki Krogerus 2019-04-01  280  typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
bdecb33a Heikki Krogerus 2018-03-20 @281  {
e900bf53 Heikki Krogerus 2019-04-01  282  	struct typec_mux *mux;
e900bf53 Heikki Krogerus 2019-04-01  283  	int ret;
e900bf53 Heikki Krogerus 2019-04-01  284  
e900bf53 Heikki Krogerus 2019-04-01  285  	if (!desc || !desc->set)
e900bf53 Heikki Krogerus 2019-04-01  286  		return ERR_PTR(-EINVAL);
bdecb33a Heikki Krogerus 2018-03-20  287  
e900bf53 Heikki Krogerus 2019-04-01  288  	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
e900bf53 Heikki Krogerus 2019-04-01  289  	if (!mux)
e900bf53 Heikki Krogerus 2019-04-01  290  		return ERR_PTR(-ENOMEM);
e900bf53 Heikki Krogerus 2019-04-01  291  
e900bf53 Heikki Krogerus 2019-04-01  292  	mux->set = desc->set;
e900bf53 Heikki Krogerus 2019-04-01  293  
e900bf53 Heikki Krogerus 2019-04-01  294  	device_initialize(&mux->dev);
e900bf53 Heikki Krogerus 2019-04-01  295  	mux->dev.parent = parent;
e900bf53 Heikki Krogerus 2019-04-01  296  	mux->dev.class = &typec_mux_class;
e900bf53 Heikki Krogerus 2019-04-01  297  	mux->dev.type = &typec_mux_dev_type;
e900bf53 Heikki Krogerus 2019-04-01  298  	mux->dev.fwnode = desc->fwnode;
e900bf53 Heikki Krogerus 2019-04-01  299  	mux->dev.driver_data = desc->drvdata;
e900bf53 Heikki Krogerus 2019-04-01  300  	dev_set_name(&mux->dev, "%s-mux", dev_name(parent));
e900bf53 Heikki Krogerus 2019-04-01  301  
e900bf53 Heikki Krogerus 2019-04-01  302  	ret = device_add(&mux->dev);
e900bf53 Heikki Krogerus 2019-04-01  303  	if (ret) {
e900bf53 Heikki Krogerus 2019-04-01  304  		dev_err(parent, "failed to register mux (%d)\n", ret);
e900bf53 Heikki Krogerus 2019-04-01  305  		put_device(&mux->dev);
e900bf53 Heikki Krogerus 2019-04-01  306  		return ERR_PTR(ret);
e900bf53 Heikki Krogerus 2019-04-01  307  	}
e900bf53 Heikki Krogerus 2019-04-01  308  
e900bf53 Heikki Krogerus 2019-04-01  309  	return mux;
bdecb33a Heikki Krogerus 2018-03-20  310  }
bdecb33a Heikki Krogerus 2018-03-20  311  EXPORT_SYMBOL_GPL(typec_mux_register);
bdecb33a Heikki Krogerus 2018-03-20  312  

:::::: The code at line 106 was first introduced by commit
:::::: bdecb33af34f79cbfbb656661210f77c8b8b5b5f usb: typec: API for controlling USB Type-C Multiplexers

:::::: TO: Heikki Krogerus <heikki.krogerus@linux.intel.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

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

* Re: [PATCH] usb: typec: Registering real device entries for the muxes
@ 2019-04-02 12:47         ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-02 12:47 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Greg KH, linux-usb, stable

On Mon, Apr 01, 2019 at 02:45:11PM +0200, Hans de Goede wrote:
> HI,
> 
> On 01-04-19 14:40, Heikki Krogerus wrote:
> > On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
> > > On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> > > > Registering real device entries (struct device) for the mode
> > > > muxes as well as for the orientation switches.
> > > > 
> > > > The Type-C mux code was deliberately attempting to avoid
> > > > creation of separate device entries for the orientation
> > > > switch and the mode switch (alternate modes) because they
> > > > are not physical devices. They are functions of a single
> > > > physical multiplexer/demultiplexer switch device.
> > > > 
> > > > Unfortunately because of the dependency we still have on the
> > > > underlying mux device driver, we had to put in hacks like
> > > > the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> > > > care of driver module reference counting") to make sure the
> > > > driver does not disappear from underneath us. Even with
> > > > those hacks we were still left with a potential NUll pointer
> > > > dereference scenario, so just creating the device entries,
> > > > and letting the core take care of the dependencies. No more
> > > > hacks needed.
> > > > 
> > > > Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> > > > Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> > > > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > 
> > > This looks good to me, nice work!
> > > 
> > > But, it would be nice if someone who has this hardware can test it to
> > > verify it does actually work :)
> > 
> > This alone does not work on Intel Cherrytrail platforms. I need to make
> > the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
> > device names that we now have for the muxes. Sorry for the mistake.
> > 
> > I'll resend this and include the needed modifications to
> > intel_cht_int33fe.c. Hans should be able to test this once I do that. I
> > hope he has time.
> 
> Yes I need to get back to the CherryTrail Type-C stuff we discussed a while
> back anyways. On which tree/branch should I test v2 of this patch(series) ?

Greg's usb-next.

thanks,

-- 
heikki

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

* usb: typec: Registering real device entries for the muxes
@ 2019-04-02 12:47         ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-02 12:47 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Greg KH, linux-usb, stable

On Mon, Apr 01, 2019 at 02:45:11PM +0200, Hans de Goede wrote:
> HI,
> 
> On 01-04-19 14:40, Heikki Krogerus wrote:
> > On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
> > > On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> > > > Registering real device entries (struct device) for the mode
> > > > muxes as well as for the orientation switches.
> > > > 
> > > > The Type-C mux code was deliberately attempting to avoid
> > > > creation of separate device entries for the orientation
> > > > switch and the mode switch (alternate modes) because they
> > > > are not physical devices. They are functions of a single
> > > > physical multiplexer/demultiplexer switch device.
> > > > 
> > > > Unfortunately because of the dependency we still have on the
> > > > underlying mux device driver, we had to put in hacks like
> > > > the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> > > > care of driver module reference counting") to make sure the
> > > > driver does not disappear from underneath us. Even with
> > > > those hacks we were still left with a potential NUll pointer
> > > > dereference scenario, so just creating the device entries,
> > > > and letting the core take care of the dependencies. No more
> > > > hacks needed.
> > > > 
> > > > Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> > > > Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> > > > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > 
> > > This looks good to me, nice work!
> > > 
> > > But, it would be nice if someone who has this hardware can test it to
> > > verify it does actually work :)
> > 
> > This alone does not work on Intel Cherrytrail platforms. I need to make
> > the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
> > device names that we now have for the muxes. Sorry for the mistake.
> > 
> > I'll resend this and include the needed modifications to
> > intel_cht_int33fe.c. Hans should be able to test this once I do that. I
> > hope he has time.
> 
> Yes I need to get back to the CherryTrail Type-C stuff we discussed a while
> back anyways. On which tree/branch should I test v2 of this patch(series) ?

Greg's usb-next.

thanks,

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

* Re: [PATCH] usb: typec: Registering real device entries for the muxes
@ 2019-04-03 10:29           ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-03 10:29 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Greg KH, linux-usb, stable

On Tue, Apr 02, 2019 at 03:47:47PM +0300, Heikki Krogerus wrote:
> On Mon, Apr 01, 2019 at 02:45:11PM +0200, Hans de Goede wrote:
> > HI,
> > 
> > On 01-04-19 14:40, Heikki Krogerus wrote:
> > > On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
> > > > On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> > > > > Registering real device entries (struct device) for the mode
> > > > > muxes as well as for the orientation switches.
> > > > > 
> > > > > The Type-C mux code was deliberately attempting to avoid
> > > > > creation of separate device entries for the orientation
> > > > > switch and the mode switch (alternate modes) because they
> > > > > are not physical devices. They are functions of a single
> > > > > physical multiplexer/demultiplexer switch device.
> > > > > 
> > > > > Unfortunately because of the dependency we still have on the
> > > > > underlying mux device driver, we had to put in hacks like
> > > > > the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> > > > > care of driver module reference counting") to make sure the
> > > > > driver does not disappear from underneath us. Even with
> > > > > those hacks we were still left with a potential NUll pointer
> > > > > dereference scenario, so just creating the device entries,
> > > > > and letting the core take care of the dependencies. No more
> > > > > hacks needed.
> > > > > 
> > > > > Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> > > > > Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> > > > > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > > 
> > > > This looks good to me, nice work!
> > > > 
> > > > But, it would be nice if someone who has this hardware can test it to
> > > > verify it does actually work :)
> > > 
> > > This alone does not work on Intel Cherrytrail platforms. I need to make
> > > the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
> > > device names that we now have for the muxes. Sorry for the mistake.
> > > 
> > > I'll resend this and include the needed modifications to
> > > intel_cht_int33fe.c. Hans should be able to test this once I do that. I
> > > hope he has time.
> > 
> > Yes I need to get back to the CherryTrail Type-C stuff we discussed a while
> > back anyways. On which tree/branch should I test v2 of this patch(series) ?
> 
> Greg's usb-next.

I just realized that the potential NULL pointer dereference that this
patch is meant to fix can't happen until my "software node reference"
modifications [1] have been applied. I don't think this needs to be
considered a fix.

I think the correct way to handle this patch is to make just it part
of that series. I'll resend the series, and include this patch in it.

[1] https://lkml.org/lkml/2019/3/15/457


thanks,

-- 
heikki

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

* usb: typec: Registering real device entries for the muxes
@ 2019-04-03 10:29           ` Heikki Krogerus
  0 siblings, 0 replies; 14+ messages in thread
From: Heikki Krogerus @ 2019-04-03 10:29 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Greg KH, linux-usb, stable

On Tue, Apr 02, 2019 at 03:47:47PM +0300, Heikki Krogerus wrote:
> On Mon, Apr 01, 2019 at 02:45:11PM +0200, Hans de Goede wrote:
> > HI,
> > 
> > On 01-04-19 14:40, Heikki Krogerus wrote:
> > > On Mon, Apr 01, 2019 at 12:34:29PM +0200, Greg KH wrote:
> > > > On Mon, Apr 01, 2019 at 01:15:53PM +0300, Heikki Krogerus wrote:
> > > > > Registering real device entries (struct device) for the mode
> > > > > muxes as well as for the orientation switches.
> > > > > 
> > > > > The Type-C mux code was deliberately attempting to avoid
> > > > > creation of separate device entries for the orientation
> > > > > switch and the mode switch (alternate modes) because they
> > > > > are not physical devices. They are functions of a single
> > > > > physical multiplexer/demultiplexer switch device.
> > > > > 
> > > > > Unfortunately because of the dependency we still have on the
> > > > > underlying mux device driver, we had to put in hacks like
> > > > > the one in the commit 3e3b81965cbf ("usb: typec: mux: Take
> > > > > care of driver module reference counting") to make sure the
> > > > > driver does not disappear from underneath us. Even with
> > > > > those hacks we were still left with a potential NUll pointer
> > > > > dereference scenario, so just creating the device entries,
> > > > > and letting the core take care of the dependencies. No more
> > > > > hacks needed.
> > > > > 
> > > > > Fixes: 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting")
> > > > > Cc: v4.19.x <stable@vger.kernel.org> # v4.19.x+
> > > > > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > > 
> > > > This looks good to me, nice work!
> > > > 
> > > > But, it would be nice if someone who has this hardware can test it to
> > > > verify it does actually work :)
> > > 
> > > This alone does not work on Intel Cherrytrail platforms. I need to make
> > > the Intel Cherrytrail MFD driver (intel_cht_int33fe.c) to use the new
> > > device names that we now have for the muxes. Sorry for the mistake.
> > > 
> > > I'll resend this and include the needed modifications to
> > > intel_cht_int33fe.c. Hans should be able to test this once I do that. I
> > > hope he has time.
> > 
> > Yes I need to get back to the CherryTrail Type-C stuff we discussed a while
> > back anyways. On which tree/branch should I test v2 of this patch(series) ?
> 
> Greg's usb-next.

I just realized that the potential NULL pointer dereference that this
patch is meant to fix can't happen until my "software node reference"
modifications [1] have been applied. I don't think this needs to be
considered a fix.

I think the correct way to handle this patch is to make just it part
of that series. I'll resend the series, and include this patch in it.

[1] https://lkml.org/lkml/2019/3/15/457


thanks,

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

end of thread, other threads:[~2019-04-03 10:29 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-01 10:15 [PATCH] usb: typec: Registering real device entries for the muxes Heikki Krogerus
2019-04-01 10:15 ` Heikki Krogerus
2019-04-01 10:34 ` [PATCH] " Greg KH
2019-04-01 10:34   ` Greg Kroah-Hartman
2019-04-01 12:40   ` [PATCH] " Heikki Krogerus
2019-04-01 12:40     ` Heikki Krogerus
2019-04-01 12:45     ` [PATCH] " Hans de Goede
2019-04-01 12:45       ` Hans de Goede
2019-04-02 12:47       ` [PATCH] " Heikki Krogerus
2019-04-02 12:47         ` Heikki Krogerus
2019-04-03 10:29         ` [PATCH] " Heikki Krogerus
2019-04-03 10:29           ` Heikki Krogerus
2019-04-02  7:35 ` [PATCH] " kbuild test robot
2019-04-02  7:35   ` kbuild test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.