linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/2] drm/dsi: DSI for devices with different control bus
@ 2015-06-30  5:24 Archit Taneja
  2015-06-30  5:24 ` [RFC 1/2] drm/dsi: Create dummy DSI devices Archit Taneja
                   ` (3 more replies)
  0 siblings, 4 replies; 84+ messages in thread
From: Archit Taneja @ 2015-06-30  5:24 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-arm-msm, treding, inki.dae, a.hajda, linux-kernel, airlied,
	daniel, jani.nikula, Archit Taneja

We are currently restricted when it comes to supporting DSI on devices
that have a non-DSI control bus. For example, DSI encoder chips are
available in the market that are configured via i2c. Configuring their
registers via DSI bus is either optional or not available at all.

These devices still need to pass DSI parameters (data lanes, mode flags
etc) to the DSI host they are connected to. We don't have a way to do
that at the moment.

The method presented in these patches is to provide an API to create a
'dummy' mipi_dsi_device. This device is populated with the desired DSI
params, which are passed on to the host via mipi_dsi_attach().

This method will require the device driver to get a phandle to the DSI
host since there is no parent-child relation between the two.

Is there a better way to do this? Please let me know!

Archit Taneja (2):
  drm/dsi: Create dummy DSI devices
  drm/dsi: Get DSI host by DT device node

 drivers/gpu/drm/drm_mipi_dsi.c | 108 ++++++++++++++++++++++++++++++++++++++++-
 include/drm/drm_mipi_dsi.h     |   4 ++
 2 files changed, 110 insertions(+), 2 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [RFC 1/2] drm/dsi: Create dummy DSI devices
  2015-06-30  5:24 [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
@ 2015-06-30  5:24 ` Archit Taneja
  2015-08-19  8:10   ` Andrzej Hajda
  2015-06-30  5:24 ` [RFC 2/2] drm/dsi: Get DSI host by DT device node Archit Taneja
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-06-30  5:24 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-arm-msm, treding, inki.dae, a.hajda, linux-kernel, airlied,
	daniel, jani.nikula, Archit Taneja

We can have devices where the data bus is MIPI DSI, but the control bus
is something else (i2c, spi etc). A typical example is i2c controlled
encoder bridge chips.

Such devices too require passing DSI specific parameters (number of data
lanes, DSI mode flags, color format etc) to their DSI host. For a device
that isn't 'mipi_dsi_device', there is no way of passing such parameters.

Provide the option of creating a dummy DSI device. The main purpose of
this would be to attach to a DSI host by calling mipi_dsi_attach, and
pass DSI params.

Create mipi_dsi_new_dummy for creating a dummy dsi device. The driver
calling this needs to be aware of the mipi_dsi_host it wants to attach
to, and also the DSI virtual channel the DSI device intends to use.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 78 ++++++++++++++++++++++++++++++++++++++++--
 include/drm/drm_mipi_dsi.h     |  2 ++
 2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 2d5ca8ee..9bfe215 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -47,7 +47,14 @@
 
 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
 {
-	return of_driver_match_device(dev, drv);
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
+	if (!strcmp(drv->name, "mipi_dsi_dummy") &&
+			strstr(dev_name(dev), "dummy_dev"))
+		return 1;
+
+	return 0;
 }
 
 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
@@ -171,6 +178,67 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 	return dsi;
 }
 
+static int dummy_probe(struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static int dummy_remove(struct mipi_dsi_device *dsi)
+{
+	return 0;
+}
+
+static void dummy_shutdown(struct mipi_dsi_device *dsi)
+{
+}
+
+static struct mipi_dsi_driver dummy_dsi_driver = {
+	.probe = dummy_probe,
+	.remove = dummy_remove,
+	.shutdown = dummy_shutdown,
+	.driver.name = "mipi_dsi_dummy",
+};
+
+static int mipi_dsi_device_add_dummy(struct mipi_dsi_device *dsi)
+{
+	struct mipi_dsi_host *host = dsi->host;
+
+	dev_set_name(&dsi->dev, "%s.dummy_dev.%d", dev_name(host->dev),
+			dsi->channel);
+
+	return device_add(&dsi->dev);
+}
+
+struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg)
+{
+	struct mipi_dsi_device *dsi;
+	struct device *dev = host->dev;
+	int ret;
+
+	if (reg > 3) {
+		dev_err(dev, "invalid reg property %u\n", reg);
+		return ERR_PTR(-EINVAL);
+	}
+
+	dsi = mipi_dsi_device_alloc(host);
+	if (IS_ERR(dsi)) {
+		dev_err(dev, "failed to allocate dummy DSI device %ld\n",
+			PTR_ERR(dsi));
+		return dsi;
+	}
+
+	dsi->channel = reg;
+
+	ret = mipi_dsi_device_add_dummy(dsi);
+	if (ret) {
+		dev_err(dev, "failed to add dummy DSI device %d\n", ret);
+		kfree(dsi);
+		return ERR_PTR(ret);
+	}
+
+	return dsi;
+}
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
 	struct device_node *node;
@@ -924,7 +992,13 @@ EXPORT_SYMBOL(mipi_dsi_driver_unregister);
 
 static int __init mipi_dsi_bus_init(void)
 {
-	return bus_register(&mipi_dsi_bus_type);
+	int ret;
+
+	ret = bus_register(&mipi_dsi_bus_type);
+	if (ret < 0)
+		return ret;
+
+	return mipi_dsi_driver_register(&dummy_dsi_driver);
 }
 postcore_initcall(mipi_dsi_bus_init);
 
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index f1d8d0d..d06ba99 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -174,6 +174,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
+struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg);
+
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [RFC 2/2] drm/dsi: Get DSI host by DT device node
  2015-06-30  5:24 [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
  2015-06-30  5:24 ` [RFC 1/2] drm/dsi: Create dummy DSI devices Archit Taneja
@ 2015-06-30  5:24 ` Archit Taneja
  2015-08-19  8:46   ` Andrzej Hajda
  2015-08-19  5:07 ` [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
  3 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-06-30  5:24 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-arm-msm, treding, inki.dae, a.hajda, linux-kernel, airlied,
	daniel, jani.nikula, Archit Taneja

mipi_dsi_devices are inherently aware of their host because they
share a parent-child hierarchy in the device tree.

Non-dsi drivers that create a dummy dsi device don't have this data.
In order to get this information, they require to a phandle to the dsi
host in the device tree.

Maintain a list of all the hosts DSI that are currently registered.

This list will be used to find the mipi_dsi_host corresponding to the
device_node passed in of_find_mipi_dsi_host_by_node.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 30 ++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 9bfe215..81ddb73 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -239,6 +239,28 @@ struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg)
 	return dsi;
 }
 
+static DEFINE_MUTEX(host_lock);
+static LIST_HEAD(host_list);
+
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
+{
+	struct mipi_dsi_host *host;
+
+	mutex_lock(&host_lock);
+
+	list_for_each_entry(host, &host_list, list) {
+		if (host->dev->of_node == node) {
+			mutex_unlock(&host_lock);
+			return host;
+		}
+	}
+
+	mutex_unlock(&host_lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
 	struct device_node *node;
@@ -250,6 +272,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
 		of_mipi_dsi_device_add(host, node);
 	}
 
+	mutex_lock(&host_lock);
+	list_add_tail(&host->list, &host_list);
+	mutex_unlock(&host_lock);
+
 	return 0;
 }
 EXPORT_SYMBOL(mipi_dsi_host_register);
@@ -266,6 +292,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
 {
 	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
+
+	mutex_lock(&host_lock);
+	list_del_init(&host->list);
+	mutex_unlock(&host_lock);
 }
 EXPORT_SYMBOL(mipi_dsi_host_unregister);
 
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index d06ba99..1684a0e 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -100,10 +100,12 @@ struct mipi_dsi_host_ops {
 struct mipi_dsi_host {
 	struct device *dev;
 	const struct mipi_dsi_host_ops *ops;
+	struct list_head list;
 };
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host);
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 
 /* DSI mode flags */
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-06-30  5:24 [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
  2015-06-30  5:24 ` [RFC 1/2] drm/dsi: Create dummy DSI devices Archit Taneja
  2015-06-30  5:24 ` [RFC 2/2] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2015-08-19  5:07 ` Archit Taneja
  2015-08-19 13:13   ` Thierry Reding
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
  3 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-08-19  5:07 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-arm-msm, treding, inki.dae, a.hajda, linux-kernel, airlied,
	daniel, jani.nikula

Hi,

On 06/30/2015 10:54 AM, Archit Taneja wrote:
> We are currently restricted when it comes to supporting DSI on devices
> that have a non-DSI control bus. For example, DSI encoder chips are
> available in the market that are configured via i2c. Configuring their
> registers via DSI bus is either optional or not available at all.
>
> These devices still need to pass DSI parameters (data lanes, mode flags
> etc) to the DSI host they are connected to. We don't have a way to do
> that at the moment.
>
> The method presented in these patches is to provide an API to create a
> 'dummy' mipi_dsi_device. This device is populated with the desired DSI
> params, which are passed on to the host via mipi_dsi_attach().
>
> This method will require the device driver to get a phandle to the DSI
> host since there is no parent-child relation between the two.
>
> Is there a better way to do this? Please let me know!

Any comments on this?

Archit

>
> Archit Taneja (2):
>    drm/dsi: Create dummy DSI devices
>    drm/dsi: Get DSI host by DT device node
>
>   drivers/gpu/drm/drm_mipi_dsi.c | 108 ++++++++++++++++++++++++++++++++++++++++-
>   include/drm/drm_mipi_dsi.h     |   4 ++
>   2 files changed, 110 insertions(+), 2 deletions(-)
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 1/2] drm/dsi: Create dummy DSI devices
  2015-06-30  5:24 ` [RFC 1/2] drm/dsi: Create dummy DSI devices Archit Taneja
@ 2015-08-19  8:10   ` Andrzej Hajda
  2015-08-19  9:30     ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Andrzej Hajda @ 2015-08-19  8:10 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-arm-msm, treding, inki.dae, linux-kernel, airlied, daniel,
	jani.nikula

On 06/30/2015 07:24 AM, Archit Taneja wrote:
> We can have devices where the data bus is MIPI DSI, but the control bus
> is something else (i2c, spi etc). A typical example is i2c controlled
> encoder bridge chips.
>
> Such devices too require passing DSI specific parameters (number of data
> lanes, DSI mode flags, color format etc) to their DSI host. For a device
> that isn't 'mipi_dsi_device', there is no way of passing such parameters.
>
> Provide the option of creating a dummy DSI device. The main purpose of
> this would be to attach to a DSI host by calling mipi_dsi_attach, and
> pass DSI params.
>
> Create mipi_dsi_new_dummy for creating a dummy dsi device. The driver
> calling this needs to be aware of the mipi_dsi_host it wants to attach
> to, and also the DSI virtual channel the DSI device intends to use.
>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 78 ++++++++++++++++++++++++++++++++++++++++--
>  include/drm/drm_mipi_dsi.h     |  2 ++
>  2 files changed, 78 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 2d5ca8ee..9bfe215 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -47,7 +47,14 @@
>  
>  static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
>  {
> -	return of_driver_match_device(dev, drv);
> +	if (of_driver_match_device(dev, drv))
> +		return 1;
> +
> +	if (!strcmp(drv->name, "mipi_dsi_dummy") &&
> +			strstr(dev_name(dev), "dummy_dev"))
> +		return 1;

Is this kind of fuzzy matching used in other dummy devs? It looks little bit
scary. You
can at least replace

strstr(dev_name(dev), "dummy_dev"))

with

strstr(dev_name(dev), ".dummy_dev."))

Anyway, currently it should not break anything, am I right?

> +
> +	return 0;
>  }
>  
>  static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
> @@ -171,6 +178,67 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  	return dsi;
>  }
>  
> +static int dummy_probe(struct mipi_dsi_device *dsi)
> +{
> +	return 0;
> +}
> +
> +static int dummy_remove(struct mipi_dsi_device *dsi)
> +{
> +	return 0;
> +}
> +
> +static void dummy_shutdown(struct mipi_dsi_device *dsi)
> +{
> +}

I suppose these callbacks are optional, so you can omit them.

> +
> +static struct mipi_dsi_driver dummy_dsi_driver = {
> +	.probe = dummy_probe,
> +	.remove = dummy_remove,
> +	.shutdown = dummy_shutdown,
> +	.driver.name = "mipi_dsi_dummy",
> +};
> +
> +static int mipi_dsi_device_add_dummy(struct mipi_dsi_device *dsi)
> +{
> +	struct mipi_dsi_host *host = dsi->host;
> +
> +	dev_set_name(&dsi->dev, "%s.dummy_dev.%d", dev_name(host->dev),
> +			dsi->channel);
> +
> +	return device_add(&dsi->dev);
> +}
> +
> +struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg)
> +{
> +	struct mipi_dsi_device *dsi;
> +	struct device *dev = host->dev;
> +	int ret;
> +
> +	if (reg > 3) {
> +		dev_err(dev, "invalid reg property %u\n", reg);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	dsi = mipi_dsi_device_alloc(host);
> +	if (IS_ERR(dsi)) {
> +		dev_err(dev, "failed to allocate dummy DSI device %ld\n",
> +			PTR_ERR(dsi));
> +		return dsi;
> +	}
> +
> +	dsi->channel = reg;
> +
> +	ret = mipi_dsi_device_add_dummy(dsi);
> +	if (ret) {
> +		dev_err(dev, "failed to add dummy DSI device %d\n", ret);
> +		kfree(dsi);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return dsi;
> +}
> +
>  int mipi_dsi_host_register(struct mipi_dsi_host *host)
>  {
>  	struct device_node *node;
> @@ -924,7 +992,13 @@ EXPORT_SYMBOL(mipi_dsi_driver_unregister);
>  
>  static int __init mipi_dsi_bus_init(void)
>  {
> -	return bus_register(&mipi_dsi_bus_type);
> +	int ret;
> +
> +	ret = bus_register(&mipi_dsi_bus_type);
> +	if (ret < 0)
> +		return ret;
> +
> +	return mipi_dsi_driver_register(&dummy_dsi_driver);
>  }
>  postcore_initcall(mipi_dsi_bus_init);
>  
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index f1d8d0d..d06ba99 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -174,6 +174,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
>  ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>  			      size_t num_params, void *data, size_t size);
>  
> +struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg);
> +
>  /**
>   * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
>   * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking


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

* Re: [RFC 2/2] drm/dsi: Get DSI host by DT device node
  2015-06-30  5:24 ` [RFC 2/2] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2015-08-19  8:46   ` Andrzej Hajda
  0 siblings, 0 replies; 84+ messages in thread
From: Andrzej Hajda @ 2015-08-19  8:46 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-arm-msm, treding, inki.dae, linux-kernel, airlied, daniel,
	jani.nikula

On 06/30/2015 07:24 AM, Archit Taneja wrote:
> mipi_dsi_devices are inherently aware of their host because they
> share a parent-child hierarchy in the device tree.
>
> Non-dsi drivers that create a dummy dsi device don't have this data.
> In order to get this information, they require to a phandle to the dsi
> host in the device tree.
>
> Maintain a list of all the hosts DSI that are currently registered.
>
> This list will be used to find the mipi_dsi_host corresponding to the
> device_node passed in of_find_mipi_dsi_host_by_node.

The lock protects only the list, there is no guarantee that mipi_dsi_host
returned by of_find_mipi_dsi_host_by_node is still valid, or will be valid long
enough.

But this issue affects many kernel frameworks so I am not sure if it should
block this
particular patch.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>

Regards
Andrzej

>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 30 ++++++++++++++++++++++++++++++
>  include/drm/drm_mipi_dsi.h     |  2 ++
>  2 files changed, 32 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 9bfe215..81ddb73 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -239,6 +239,28 @@ struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg)
>  	return dsi;
>  }
>  
> +static DEFINE_MUTEX(host_lock);
> +static LIST_HEAD(host_list);
> +
> +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
> +{
> +	struct mipi_dsi_host *host;
> +
> +	mutex_lock(&host_lock);
> +
> +	list_for_each_entry(host, &host_list, list) {
> +		if (host->dev->of_node == node) {
> +			mutex_unlock(&host_lock);
> +			return host;
> +		}
> +	}
> +
> +	mutex_unlock(&host_lock);
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
> +
>  int mipi_dsi_host_register(struct mipi_dsi_host *host)
>  {
>  	struct device_node *node;
> @@ -250,6 +272,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
>  		of_mipi_dsi_device_add(host, node);
>  	}
>  
> +	mutex_lock(&host_lock);
> +	list_add_tail(&host->list, &host_list);
> +	mutex_unlock(&host_lock);
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(mipi_dsi_host_register);
> @@ -266,6 +292,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
>  void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
>  {
>  	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
> +
> +	mutex_lock(&host_lock);
> +	list_del_init(&host->list);
> +	mutex_unlock(&host_lock);
>  }
>  EXPORT_SYMBOL(mipi_dsi_host_unregister);
>  
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index d06ba99..1684a0e 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -100,10 +100,12 @@ struct mipi_dsi_host_ops {
>  struct mipi_dsi_host {
>  	struct device *dev;
>  	const struct mipi_dsi_host_ops *ops;
> +	struct list_head list;
>  };
>  
>  int mipi_dsi_host_register(struct mipi_dsi_host *host);
>  void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
> +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
>  
>  /* DSI mode flags */
>  


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

* Re: [RFC 1/2] drm/dsi: Create dummy DSI devices
  2015-08-19  8:10   ` Andrzej Hajda
@ 2015-08-19  9:30     ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-08-19  9:30 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: linux-arm-msm, treding, inki.dae, linux-kernel, airlied, daniel,
	jani.nikula

Hi,

On 08/19/2015 01:40 PM, Andrzej Hajda wrote:
> On 06/30/2015 07:24 AM, Archit Taneja wrote:
>> We can have devices where the data bus is MIPI DSI, but the control bus
>> is something else (i2c, spi etc). A typical example is i2c controlled
>> encoder bridge chips.
>>
>> Such devices too require passing DSI specific parameters (number of data
>> lanes, DSI mode flags, color format etc) to their DSI host. For a device
>> that isn't 'mipi_dsi_device', there is no way of passing such parameters.
>>
>> Provide the option of creating a dummy DSI device. The main purpose of
>> this would be to attach to a DSI host by calling mipi_dsi_attach, and
>> pass DSI params.
>>
>> Create mipi_dsi_new_dummy for creating a dummy dsi device. The driver
>> calling this needs to be aware of the mipi_dsi_host it wants to attach
>> to, and also the DSI virtual channel the DSI device intends to use.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 78 ++++++++++++++++++++++++++++++++++++++++--
>>   include/drm/drm_mipi_dsi.h     |  2 ++
>>   2 files changed, 78 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index 2d5ca8ee..9bfe215 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -47,7 +47,14 @@
>>
>>   static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
>>   {
>> -	return of_driver_match_device(dev, drv);
>> +	if (of_driver_match_device(dev, drv))
>> +		return 1;
>> +
>> +	if (!strcmp(drv->name, "mipi_dsi_dummy") &&
>> +			strstr(dev_name(dev), "dummy_dev"))
>> +		return 1;
>
> Is this kind of fuzzy matching used in other dummy devs? It looks little bit
> scary. You
> can at least replace
>
> strstr(dev_name(dev), "dummy_dev"))
>
> with
>
> strstr(dev_name(dev), ".dummy_dev."))
>
> Anyway, currently it should not break anything, am I right?

I took i2c's dummy dev creation as reference. The i2c_driver struct has
an id_table param, that allows the match function (i2c_device_match) to
not have a special case to check for a dummy device.

We could a 'id_table' entry in mipi_dsi_driver, and a 'name' entry in
mipi_dsi_device. But that would be a bit of an overkill just to support
dummy devices.

I could make the check more thorough by adding a func which does
something similar to 'i2c_verify_client', but I think we would
still need the above string.

I will change "dummy_dev" to ".dummy_dev.". I grepped the kernel for
devices named "dummy_dev", but didn't find anything as such, so it
shouldn't really break anything.

>
>> +
>> +	return 0;
>>   }
>>
>>   static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
>> @@ -171,6 +178,67 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>   	return dsi;
>>   }
>>
>> +static int dummy_probe(struct mipi_dsi_device *dsi)
>> +{
>> +	return 0;
>> +}
>> +
>> +static int dummy_remove(struct mipi_dsi_device *dsi)
>> +{
>> +	return 0;
>> +}
>> +
>> +static void dummy_shutdown(struct mipi_dsi_device *dsi)
>> +{
>> +}
>
> I suppose these callbacks are optional, so you can omit them.

Right. I will remove these.

Thanks for the review.

Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-19  5:07 ` [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
@ 2015-08-19 13:13   ` Thierry Reding
  2015-08-19 14:17     ` Lucas Stach
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2015-08-19 13:13 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, linux-arm-msm, inki.dae, a.hajda, linux-kernel,
	airlied, daniel, jani.nikula

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

On Wed, Aug 19, 2015 at 10:37:54AM +0530, Archit Taneja wrote:
> Hi,
> 
> On 06/30/2015 10:54 AM, Archit Taneja wrote:
> >We are currently restricted when it comes to supporting DSI on devices
> >that have a non-DSI control bus. For example, DSI encoder chips are
> >available in the market that are configured via i2c. Configuring their
> >registers via DSI bus is either optional or not available at all.
> >
> >These devices still need to pass DSI parameters (data lanes, mode flags
> >etc) to the DSI host they are connected to. We don't have a way to do
> >that at the moment.
> >
> >The method presented in these patches is to provide an API to create a
> >'dummy' mipi_dsi_device. This device is populated with the desired DSI
> >params, which are passed on to the host via mipi_dsi_attach().
> >
> >This method will require the device driver to get a phandle to the DSI
> >host since there is no parent-child relation between the two.
> >
> >Is there a better way to do this? Please let me know!
> 
> Any comments on this?

Perhaps a better way would be to invert this relationship. According to
your proposal we'd have to have DT like this:

	i2c@... {
		...

		dsi-device@... {
			...
			dsi-bus = <&dsi>;
			...
		};

		...
	};

	dsi@... {
		...
	};

Inversing the relationship would become something like this:

	i2c@... {
		...
	};

	dsi@... {
		...

		peripheral@... {
			...
			i2c-bus = <&i2c>;
			...
		};

		...
	};

Both of those aren't fundamentally different, and they both have the
disavantage of lacking ways to transport configuration data that the
other bus needs to instantiate the dummy device (such as the reg
property for example, denoting the I2C slave address or the DSI VC).

So how about we create two devices in the device tree and fuse them at
the driver level:

	i2c@... {
		...

		i2cdsi: dsi-device@... {
			...
		};

		...
	};

	dsi@... {
		...

		peripheral@... {
			...
			control = <&i2cdsi>;
			...
		};

		...
	};

This way we'll get both an I2C device and a DSI device that we can fully
describe using the standard device tree bindings. At driver time we can
get the I2C device from the phandle in the control property of the DSI
device and use it to execute I2C transactions.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-19 13:13   ` Thierry Reding
@ 2015-08-19 14:17     ` Lucas Stach
  2015-08-19 14:34       ` Thierry Reding
  0 siblings, 1 reply; 84+ messages in thread
From: Lucas Stach @ 2015-08-19 14:17 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Archit Taneja, linux-arm-msm, linux-kernel, dri-devel, a.hajda

Hi Thierry, Archit,

Am Mittwoch, den 19.08.2015, 15:13 +0200 schrieb Thierry Reding:
> On Wed, Aug 19, 2015 at 10:37:54AM +0530, Archit Taneja wrote:
> > Hi,
> > 
> > On 06/30/2015 10:54 AM, Archit Taneja wrote:
> > >We are currently restricted when it comes to supporting DSI on devices
> > >that have a non-DSI control bus. For example, DSI encoder chips are
> > >available in the market that are configured via i2c. Configuring their
> > >registers via DSI bus is either optional or not available at all.
> > >
> > >These devices still need to pass DSI parameters (data lanes, mode flags
> > >etc) to the DSI host they are connected to. We don't have a way to do
> > >that at the moment.
> > >
> > >The method presented in these patches is to provide an API to create a
> > >'dummy' mipi_dsi_device. This device is populated with the desired DSI
> > >params, which are passed on to the host via mipi_dsi_attach().
> > >
> > >This method will require the device driver to get a phandle to the DSI
> > >host since there is no parent-child relation between the two.
> > >
> > >Is there a better way to do this? Please let me know!
> > 
> > Any comments on this?
> 
> Perhaps a better way would be to invert this relationship. According to
> your proposal we'd have to have DT like this:
> 
> 	i2c@... {
> 		...
> 
> 		dsi-device@... {
> 			...
> 			dsi-bus = <&dsi>;
> 			...
> 		};
> 
> 		...
> 	};
> 
> 	dsi@... {
> 		...
> 	};
> 
> Inversing the relationship would become something like this:
> 
> 	i2c@... {
> 		...
> 	};
> 
> 	dsi@... {
> 		...
> 
> 		peripheral@... {
> 			...
> 			i2c-bus = <&i2c>;
> 			...
> 		};
> 
> 		...
> 	};
> 
> Both of those aren't fundamentally different, and they both have the
> disavantage of lacking ways to transport configuration data that the
> other bus needs to instantiate the dummy device (such as the reg
> property for example, denoting the I2C slave address or the DSI VC).
> 
> So how about we create two devices in the device tree and fuse them at
> the driver level:
> 
> 	i2c@... {
> 		...
> 
> 		i2cdsi: dsi-device@... {
> 			...
> 		};
> 
> 		...
> 	};
> 
> 	dsi@... {
> 		...
> 
> 		peripheral@... {
> 			...
> 			control = <&i2cdsi>;
> 			...
> 		};
> 
> 		...
> 	};
> 
> This way we'll get both an I2C device and a DSI device that we can fully
> describe using the standard device tree bindings. At driver time we can
> get the I2C device from the phandle in the control property of the DSI
> device and use it to execute I2C transactions.
> 
I don't really like to see that you are inventing yet-another-way to
handle devices connected to multiple buses.

Devicetree is structured along the control buses, even if the devices
are connected to multiple buses, in the DT they are always children of
the bus that is used to control their registers from the CPUs
perspective. So a DSI encoder that is controlled through i2c is clearly
a child of the i2c master controller and only of that one.

If you need to model connections between devices that are not reflected
through the control bus hierarchy you should really consider using the
standardized of-graph bindings.
(Documentation/devicetree/bindings/graph.txt)

Multiple device drivers in both the media and DRM universe have shown
that they are a working way to represent those data bus connections
between devices.
I know this might make things a bit more complicated for Tegra DRM,
where you have a nice parent<->child relationship between the components
even on the control path so far, but we should really move into the
direction of more drivers using the standardized bindings for this
stuff, instead of doing another round of NIH.

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-19 14:17     ` Lucas Stach
@ 2015-08-19 14:34       ` Thierry Reding
  2015-08-19 14:52         ` Lucas Stach
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2015-08-19 14:34 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Archit Taneja, linux-arm-msm, linux-kernel, dri-devel, a.hajda

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

On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
> Hi Thierry, Archit,
> 
> Am Mittwoch, den 19.08.2015, 15:13 +0200 schrieb Thierry Reding:
> > On Wed, Aug 19, 2015 at 10:37:54AM +0530, Archit Taneja wrote:
> > > Hi,
> > > 
> > > On 06/30/2015 10:54 AM, Archit Taneja wrote:
> > > >We are currently restricted when it comes to supporting DSI on devices
> > > >that have a non-DSI control bus. For example, DSI encoder chips are
> > > >available in the market that are configured via i2c. Configuring their
> > > >registers via DSI bus is either optional or not available at all.
> > > >
> > > >These devices still need to pass DSI parameters (data lanes, mode flags
> > > >etc) to the DSI host they are connected to. We don't have a way to do
> > > >that at the moment.
> > > >
> > > >The method presented in these patches is to provide an API to create a
> > > >'dummy' mipi_dsi_device. This device is populated with the desired DSI
> > > >params, which are passed on to the host via mipi_dsi_attach().
> > > >
> > > >This method will require the device driver to get a phandle to the DSI
> > > >host since there is no parent-child relation between the two.
> > > >
> > > >Is there a better way to do this? Please let me know!
> > > 
> > > Any comments on this?
> > 
> > Perhaps a better way would be to invert this relationship. According to
> > your proposal we'd have to have DT like this:
> > 
> > 	i2c@... {
> > 		...
> > 
> > 		dsi-device@... {
> > 			...
> > 			dsi-bus = <&dsi>;
> > 			...
> > 		};
> > 
> > 		...
> > 	};
> > 
> > 	dsi@... {
> > 		...
> > 	};
> > 
> > Inversing the relationship would become something like this:
> > 
> > 	i2c@... {
> > 		...
> > 	};
> > 
> > 	dsi@... {
> > 		...
> > 
> > 		peripheral@... {
> > 			...
> > 			i2c-bus = <&i2c>;
> > 			...
> > 		};
> > 
> > 		...
> > 	};
> > 
> > Both of those aren't fundamentally different, and they both have the
> > disavantage of lacking ways to transport configuration data that the
> > other bus needs to instantiate the dummy device (such as the reg
> > property for example, denoting the I2C slave address or the DSI VC).
> > 
> > So how about we create two devices in the device tree and fuse them at
> > the driver level:
> > 
> > 	i2c@... {
> > 		...
> > 
> > 		i2cdsi: dsi-device@... {
> > 			...
> > 		};
> > 
> > 		...
> > 	};
> > 
> > 	dsi@... {
> > 		...
> > 
> > 		peripheral@... {
> > 			...
> > 			control = <&i2cdsi>;
> > 			...
> > 		};
> > 
> > 		...
> > 	};
> > 
> > This way we'll get both an I2C device and a DSI device that we can fully
> > describe using the standard device tree bindings. At driver time we can
> > get the I2C device from the phandle in the control property of the DSI
> > device and use it to execute I2C transactions.
> > 
> I don't really like to see that you are inventing yet-another-way to
> handle devices connected to multiple buses.
> 
> Devicetree is structured along the control buses, even if the devices
> are connected to multiple buses, in the DT they are always children of
> the bus that is used to control their registers from the CPUs
> perspective. So a DSI encoder that is controlled through i2c is clearly
> a child of the i2c master controller and only of that one.

I think that's a flawed interpretation of what's going on here. The
device in fact has two interfaces: one is I2C, the other is DSI. In my
opinion that's reason enough to represent it as two logical devices.

> If you need to model connections between devices that are not reflected
> through the control bus hierarchy you should really consider using the
> standardized of-graph bindings.
> (Documentation/devicetree/bindings/graph.txt)

The problem is that the original proposal would instantiate a dummy
device, so it wouldn't be represented in DT at all. So unless you do add
two logical devices to DT (one for each bus interface), you don't have
anything to glue together with an OF graph.

> Multiple device drivers in both the media and DRM universe have shown
> that they are a working way to represent those data bus connections
> between devices.
> I know this might make things a bit more complicated for Tegra DRM,
> where you have a nice parent<->child relationship between the components
> even on the control path so far, but we should really move into the
> direction of more drivers using the standardized bindings for this
> stuff, instead of doing another round of NIH.

Why are you bringing up Tegra DRM? I don't see how it's relevant in any
way to this discussion.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-19 14:34       ` Thierry Reding
@ 2015-08-19 14:52         ` Lucas Stach
  2015-08-19 15:02           ` Thierry Reding
  0 siblings, 1 reply; 84+ messages in thread
From: Lucas Stach @ 2015-08-19 14:52 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Archit Taneja, linux-arm-msm, linux-kernel, dri-devel, a.hajda

Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
> > Hi Thierry, Archit,
> > 
[...]
> > > Perhaps a better way would be to invert this relationship. According to
> > > your proposal we'd have to have DT like this:
> > > 
> > > 	i2c@... {
> > > 		...
> > > 
> > > 		dsi-device@... {
> > > 			...
> > > 			dsi-bus = <&dsi>;
> > > 			...
> > > 		};
> > > 
> > > 		...
> > > 	};
> > > 
> > > 	dsi@... {
> > > 		...
> > > 	};
> > > 
> > > Inversing the relationship would become something like this:
> > > 
> > > 	i2c@... {
> > > 		...
> > > 	};
> > > 
> > > 	dsi@... {
> > > 		...
> > > 
> > > 		peripheral@... {
> > > 			...
> > > 			i2c-bus = <&i2c>;
> > > 			...
> > > 		};
> > > 
> > > 		...
> > > 	};
> > > 
> > > Both of those aren't fundamentally different, and they both have the
> > > disavantage of lacking ways to transport configuration data that the
> > > other bus needs to instantiate the dummy device (such as the reg
> > > property for example, denoting the I2C slave address or the DSI VC).
> > > 
> > > So how about we create two devices in the device tree and fuse them at
> > > the driver level:
> > > 
> > > 	i2c@... {
> > > 		...
> > > 
> > > 		i2cdsi: dsi-device@... {
> > > 			...
> > > 		};
> > > 
> > > 		...
> > > 	};
> > > 
> > > 	dsi@... {
> > > 		...
> > > 
> > > 		peripheral@... {
> > > 			...
> > > 			control = <&i2cdsi>;
> > > 			...
> > > 		};
> > > 
> > > 		...
> > > 	};
> > > 
> > > This way we'll get both an I2C device and a DSI device that we can fully
> > > describe using the standard device tree bindings. At driver time we can
> > > get the I2C device from the phandle in the control property of the DSI
> > > device and use it to execute I2C transactions.
> > > 
> > I don't really like to see that you are inventing yet-another-way to
> > handle devices connected to multiple buses.
> > 
> > Devicetree is structured along the control buses, even if the devices
> > are connected to multiple buses, in the DT they are always children of
> > the bus that is used to control their registers from the CPUs
> > perspective. So a DSI encoder that is controlled through i2c is clearly
> > a child of the i2c master controller and only of that one.
> 
> I think that's a flawed interpretation of what's going on here. The
> device in fact has two interfaces: one is I2C, the other is DSI. In my
> opinion that's reason enough to represent it as two logical devices.
> 
Does it really have 2 control interfaces that are used at the same time?
Or is the DSI connection a passive data bus if the register control
happens through i2c?

> > If you need to model connections between devices that are not reflected
> > through the control bus hierarchy you should really consider using the
> > standardized of-graph bindings.
> > (Documentation/devicetree/bindings/graph.txt)
> 
> The problem is that the original proposal would instantiate a dummy
> device, so it wouldn't be represented in DT at all. So unless you do add
> two logical devices to DT (one for each bus interface), you don't have
> anything to glue together with an OF graph.
> 
I see that the having dummy device is the least desirable solution. But
if there is only one control bus to the device I think it should be one
device sitting beneath the control bus.

You can then use of-graph to model the data path between the DSI encoder
and device.

> > Multiple device drivers in both the media and DRM universe have shown
> > that they are a working way to represent those data bus connections
> > between devices.
> > I know this might make things a bit more complicated for Tegra DRM,
> > where you have a nice parent<->child relationship between the components
> > even on the control path so far, but we should really move into the
> > direction of more drivers using the standardized bindings for this
> > stuff, instead of doing another round of NIH.
> 
> Why are you bringing up Tegra DRM? I don't see how it's relevant in any
> way to this discussion.
> 
Just disregard this comment then. Lets concentrate on the points above.

Regards,
Lucas 
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-19 14:52         ` Lucas Stach
@ 2015-08-19 15:02           ` Thierry Reding
  2015-08-19 15:39             ` Jani Nikula
  2015-08-20  4:16             ` Archit Taneja
  0 siblings, 2 replies; 84+ messages in thread
From: Thierry Reding @ 2015-08-19 15:02 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Archit Taneja, linux-arm-msm, linux-kernel, dri-devel, a.hajda

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

On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
> > On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
> > > Hi Thierry, Archit,
> > > 
> [...]
> > > > Perhaps a better way would be to invert this relationship. According to
> > > > your proposal we'd have to have DT like this:
> > > > 
> > > > 	i2c@... {
> > > > 		...
> > > > 
> > > > 		dsi-device@... {
> > > > 			...
> > > > 			dsi-bus = <&dsi>;
> > > > 			...
> > > > 		};
> > > > 
> > > > 		...
> > > > 	};
> > > > 
> > > > 	dsi@... {
> > > > 		...
> > > > 	};
> > > > 
> > > > Inversing the relationship would become something like this:
> > > > 
> > > > 	i2c@... {
> > > > 		...
> > > > 	};
> > > > 
> > > > 	dsi@... {
> > > > 		...
> > > > 
> > > > 		peripheral@... {
> > > > 			...
> > > > 			i2c-bus = <&i2c>;
> > > > 			...
> > > > 		};
> > > > 
> > > > 		...
> > > > 	};
> > > > 
> > > > Both of those aren't fundamentally different, and they both have the
> > > > disavantage of lacking ways to transport configuration data that the
> > > > other bus needs to instantiate the dummy device (such as the reg
> > > > property for example, denoting the I2C slave address or the DSI VC).
> > > > 
> > > > So how about we create two devices in the device tree and fuse them at
> > > > the driver level:
> > > > 
> > > > 	i2c@... {
> > > > 		...
> > > > 
> > > > 		i2cdsi: dsi-device@... {
> > > > 			...
> > > > 		};
> > > > 
> > > > 		...
> > > > 	};
> > > > 
> > > > 	dsi@... {
> > > > 		...
> > > > 
> > > > 		peripheral@... {
> > > > 			...
> > > > 			control = <&i2cdsi>;
> > > > 			...
> > > > 		};
> > > > 
> > > > 		...
> > > > 	};
> > > > 
> > > > This way we'll get both an I2C device and a DSI device that we can fully
> > > > describe using the standard device tree bindings. At driver time we can
> > > > get the I2C device from the phandle in the control property of the DSI
> > > > device and use it to execute I2C transactions.
> > > > 
> > > I don't really like to see that you are inventing yet-another-way to
> > > handle devices connected to multiple buses.
> > > 
> > > Devicetree is structured along the control buses, even if the devices
> > > are connected to multiple buses, in the DT they are always children of
> > > the bus that is used to control their registers from the CPUs
> > > perspective. So a DSI encoder that is controlled through i2c is clearly
> > > a child of the i2c master controller and only of that one.
> > 
> > I think that's a flawed interpretation of what's going on here. The
> > device in fact has two interfaces: one is I2C, the other is DSI. In my
> > opinion that's reason enough to represent it as two logical devices.
> > 
> Does it really have 2 control interfaces that are used at the same time?
> Or is the DSI connection a passive data bus if the register control
> happens through i2c?

The interfaces may not be used at the same time, and the DSI interface
may even be crippled, but the device is still addressable from the DSI
host controller, if for nothing else than for routing the video stream.

> > > If you need to model connections between devices that are not reflected
> > > through the control bus hierarchy you should really consider using the
> > > standardized of-graph bindings.
> > > (Documentation/devicetree/bindings/graph.txt)
> > 
> > The problem is that the original proposal would instantiate a dummy
> > device, so it wouldn't be represented in DT at all. So unless you do add
> > two logical devices to DT (one for each bus interface), you don't have
> > anything to glue together with an OF graph.
> > 
> I see that the having dummy device is the least desirable solution. But
> if there is only one control bus to the device I think it should be one
> device sitting beneath the control bus.
> 
> You can then use of-graph to model the data path between the DSI encoder
> and device.

But you will be needing a device below the DSI host controller to
represent that endpoint of the connection. The DSI host controller
itself is in no way connected to the I2C adapter. You would have to
add some sort of quirk to the DSI controller binding to allow it to
hook up with a control endpoint. And then you'll need more quirks
to describe what kind of DSI device this is.

On the other hand if you properly instantiate the DSI device you can
easily write a driver for it, and the driver will set up the correct
properties as implied by the compatible string. Once you have that you
can easily hook it up to the I2C control interface in whatever way you
like, be that an OF graph or just a simple unidirectional link by
phandle.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-19 15:02           ` Thierry Reding
@ 2015-08-19 15:39             ` Jani Nikula
  2015-08-20  4:16             ` Archit Taneja
  1 sibling, 0 replies; 84+ messages in thread
From: Jani Nikula @ 2015-08-19 15:39 UTC (permalink / raw)
  To: Thierry Reding, Lucas Stach
  Cc: linux-arm-msm, linux-kernel, dri-devel, a.hajda

On Wed, 19 Aug 2015, Thierry Reding <treding@nvidia.com> wrote:
> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>> > I think that's a flawed interpretation of what's going on here. The
>> > device in fact has two interfaces: one is I2C, the other is DSI. In my
>> > opinion that's reason enough to represent it as two logical devices.
>> > 
>> Does it really have 2 control interfaces that are used at the same time?
>> Or is the DSI connection a passive data bus if the register control
>> happens through i2c?
>
> The interfaces may not be used at the same time, and the DSI interface
> may even be crippled, but the device is still addressable from the DSI
> host controller, if for nothing else than for routing the video stream.

As a drive-by comment, the Toshiba TC358764XBG/65XBG chip can be
configured via both DSI and I2C. The I2C interface requires DSI clock on
the DSI interface to operate. You may not use the interfaces
simultaneously, but provided you protect against races in register
access, both interfaces can be operational at the same time.

Sorry I couldn't find a public spec of the chip to share.

HTH,
Jani.


-- 
Jani Nikula, Intel Open Source Technology Center

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-19 15:02           ` Thierry Reding
  2015-08-19 15:39             ` Jani Nikula
@ 2015-08-20  4:16             ` Archit Taneja
  2015-08-20 11:48               ` Thierry Reding
  1 sibling, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-08-20  4:16 UTC (permalink / raw)
  To: Thierry Reding, Lucas Stach
  Cc: linux-arm-msm, linux-kernel, dri-devel, a.hajda, lars, Jani Nikula

Hi Thierry, Lucas,


On 08/19/2015 08:32 PM, Thierry Reding wrote:
> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>> Hi Thierry, Archit,
>>>>
>> [...]
>>>>> Perhaps a better way would be to invert this relationship. According to
>>>>> your proposal we'd have to have DT like this:
>>>>>
>>>>> 	i2c@... {
>>>>> 		...
>>>>>
>>>>> 		dsi-device@... {
>>>>> 			...
>>>>> 			dsi-bus = <&dsi>;
>>>>> 			...
>>>>> 		};
>>>>>
>>>>> 		...
>>>>> 	};
>>>>>
>>>>> 	dsi@... {
>>>>> 		...
>>>>> 	};
>>>>>
>>>>> Inversing the relationship would become something like this:
>>>>>
>>>>> 	i2c@... {
>>>>> 		...
>>>>> 	};
>>>>>
>>>>> 	dsi@... {
>>>>> 		...
>>>>>
>>>>> 		peripheral@... {
>>>>> 			...
>>>>> 			i2c-bus = <&i2c>;
>>>>> 			...
>>>>> 		};
>>>>>
>>>>> 		...
>>>>> 	};
>>>>>
>>>>> Both of those aren't fundamentally different, and they both have the
>>>>> disavantage of lacking ways to transport configuration data that the
>>>>> other bus needs to instantiate the dummy device (such as the reg
>>>>> property for example, denoting the I2C slave address or the DSI VC).
>>>>>
>>>>> So how about we create two devices in the device tree and fuse them at
>>>>> the driver level:
>>>>>
>>>>> 	i2c@... {
>>>>> 		...
>>>>>
>>>>> 		i2cdsi: dsi-device@... {
>>>>> 			...
>>>>> 		};
>>>>>
>>>>> 		...
>>>>> 	};
>>>>>
>>>>> 	dsi@... {
>>>>> 		...
>>>>>
>>>>> 		peripheral@... {
>>>>> 			...
>>>>> 			control = <&i2cdsi>;
>>>>> 			...
>>>>> 		};
>>>>>
>>>>> 		...
>>>>> 	};
>>>>>
>>>>> This way we'll get both an I2C device and a DSI device that we can fully
>>>>> describe using the standard device tree bindings. At driver time we can
>>>>> get the I2C device from the phandle in the control property of the DSI
>>>>> device and use it to execute I2C transactions.
>>>>>
>>>> I don't really like to see that you are inventing yet-another-way to
>>>> handle devices connected to multiple buses.
>>>>
>>>> Devicetree is structured along the control buses, even if the devices
>>>> are connected to multiple buses, in the DT they are always children of
>>>> the bus that is used to control their registers from the CPUs
>>>> perspective. So a DSI encoder that is controlled through i2c is clearly
>>>> a child of the i2c master controller and only of that one.
>>>
>>> I think that's a flawed interpretation of what's going on here. The
>>> device in fact has two interfaces: one is I2C, the other is DSI. In my
>>> opinion that's reason enough to represent it as two logical devices.
>>>
>> Does it really have 2 control interfaces that are used at the same time?
>> Or is the DSI connection a passive data bus if the register control
>> happens through i2c?
>
> The interfaces may not be used at the same time, and the DSI interface
> may even be crippled, but the device is still addressable from the DSI
> host controller, if for nothing else than for routing the video stream.
>
>>>> If you need to model connections between devices that are not reflected
>>>> through the control bus hierarchy you should really consider using the
>>>> standardized of-graph bindings.
>>>> (Documentation/devicetree/bindings/graph.txt)
>>>
>>> The problem is that the original proposal would instantiate a dummy
>>> device, so it wouldn't be represented in DT at all. So unless you do add
>>> two logical devices to DT (one for each bus interface), you don't have
>>> anything to glue together with an OF graph.
>>>
>> I see that the having dummy device is the least desirable solution. But
>> if there is only one control bus to the device I think it should be one
>> device sitting beneath the control bus.
>>
>> You can then use of-graph to model the data path between the DSI encoder
>> and device.
>
> But you will be needing a device below the DSI host controller to
> represent that endpoint of the connection. The DSI host controller
> itself is in no way connected to the I2C adapter. You would have to
> add some sort of quirk to the DSI controller binding to allow it to

Thanks for the review.

I implemented this to support ADV7533 DSI to HDMI encoder chip, which
has a DSI video bus and an i2c control bus.

There weren't any quirks as such in the device tree when I tried to
implement this. The DT seems to manage fine without a node
corresponding to a mipi_dsi_device:

i2c_adap@.. {
	adv7533@.. {

		port {
			adv_in: endpoint {
				remote-endpoint = <&dsi_out>;
			};
		};
	};
};

dsi_host@.. {
	...
	...

	port {
		dsi_out: endpoint {
			remote-endpoint = <&adv_in>;
		}
	};
};

It's the i2c driver's job to parse the graph and retrieve the
phandle to the dsi host. Using this, it can proceed with
registering itself to this host using the new dsi funcs. This
patch does the same for the adv7533 i2c driver:

http://www.spinics.net/lists/dri-devel/msg86840.html

> hook up with a control endpoint. And then you'll need more quirks
> to describe what kind of DSI device this is.

Could you explain what you meant by this? I.e. describing the kind
of DSI device?

The dsi device created isn't really a dummy device as such. It's
dummy in the sense that there isn't a real dsi driver associated
with it. The dsi device is still used to attach to a mipi dsi host,
the way normal dsi devices do.

>
> On the other hand if you properly instantiate the DSI device you can
> easily write a driver for it, and the driver will set up the correct
> properties as implied by the compatible string. Once you have that you
> can easily hook it up to the I2C control interface in whatever way you
> like, be that an OF graph or just a simple unidirectional link by
> phandle.
>

With the fused approach you suggested, we would have 2 drivers: one i2c
and the other dsi. The i2c client driver would be more or less minimal,
preparing an i2c_client device for the dsi driver to use. Is my
understanding correct?

We can do without dummy dsi devices with this method. But, representing
a device with 2 DT nodes seems a bit off. We'd also need to compatible
strings for the same device, one for the i2c part, and the other for
the dsi part.

 From an adv75xx driver perspective, it should also support the ADV7511
chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
DSI DT node. It would be a bit inconsistent to have the bindings
require both DSI and I2C nodes for one chip, and only I2C node for the
other, with both chips being supported by the same driver.

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-20  4:16             ` Archit Taneja
@ 2015-08-20 11:48               ` Thierry Reding
  2015-08-21  6:09                 ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2015-08-20 11:48 UTC (permalink / raw)
  To: Archit Taneja
  Cc: Lucas Stach, linux-arm-msm, linux-kernel, dri-devel, a.hajda,
	lars, Jani Nikula

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

On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
> Hi Thierry, Lucas,
> 
> 
> On 08/19/2015 08:32 PM, Thierry Reding wrote:
> >On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
> >>Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
> >>>On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
> >>>>Hi Thierry, Archit,
> >>>>
> >>[...]
> >>>>>Perhaps a better way would be to invert this relationship. According to
> >>>>>your proposal we'd have to have DT like this:
> >>>>>
> >>>>>	i2c@... {
> >>>>>		...
> >>>>>
> >>>>>		dsi-device@... {
> >>>>>			...
> >>>>>			dsi-bus = <&dsi>;
> >>>>>			...
> >>>>>		};
> >>>>>
> >>>>>		...
> >>>>>	};
> >>>>>
> >>>>>	dsi@... {
> >>>>>		...
> >>>>>	};
> >>>>>
> >>>>>Inversing the relationship would become something like this:
> >>>>>
> >>>>>	i2c@... {
> >>>>>		...
> >>>>>	};
> >>>>>
> >>>>>	dsi@... {
> >>>>>		...
> >>>>>
> >>>>>		peripheral@... {
> >>>>>			...
> >>>>>			i2c-bus = <&i2c>;
> >>>>>			...
> >>>>>		};
> >>>>>
> >>>>>		...
> >>>>>	};
> >>>>>
> >>>>>Both of those aren't fundamentally different, and they both have the
> >>>>>disavantage of lacking ways to transport configuration data that the
> >>>>>other bus needs to instantiate the dummy device (such as the reg
> >>>>>property for example, denoting the I2C slave address or the DSI VC).
> >>>>>
> >>>>>So how about we create two devices in the device tree and fuse them at
> >>>>>the driver level:
> >>>>>
> >>>>>	i2c@... {
> >>>>>		...
> >>>>>
> >>>>>		i2cdsi: dsi-device@... {
> >>>>>			...
> >>>>>		};
> >>>>>
> >>>>>		...
> >>>>>	};
> >>>>>
> >>>>>	dsi@... {
> >>>>>		...
> >>>>>
> >>>>>		peripheral@... {
> >>>>>			...
> >>>>>			control = <&i2cdsi>;
> >>>>>			...
> >>>>>		};
> >>>>>
> >>>>>		...
> >>>>>	};
> >>>>>
> >>>>>This way we'll get both an I2C device and a DSI device that we can fully
> >>>>>describe using the standard device tree bindings. At driver time we can
> >>>>>get the I2C device from the phandle in the control property of the DSI
> >>>>>device and use it to execute I2C transactions.
> >>>>>
> >>>>I don't really like to see that you are inventing yet-another-way to
> >>>>handle devices connected to multiple buses.
> >>>>
> >>>>Devicetree is structured along the control buses, even if the devices
> >>>>are connected to multiple buses, in the DT they are always children of
> >>>>the bus that is used to control their registers from the CPUs
> >>>>perspective. So a DSI encoder that is controlled through i2c is clearly
> >>>>a child of the i2c master controller and only of that one.
> >>>
> >>>I think that's a flawed interpretation of what's going on here. The
> >>>device in fact has two interfaces: one is I2C, the other is DSI. In my
> >>>opinion that's reason enough to represent it as two logical devices.
> >>>
> >>Does it really have 2 control interfaces that are used at the same time?
> >>Or is the DSI connection a passive data bus if the register control
> >>happens through i2c?
> >
> >The interfaces may not be used at the same time, and the DSI interface
> >may even be crippled, but the device is still addressable from the DSI
> >host controller, if for nothing else than for routing the video stream.
> >
> >>>>If you need to model connections between devices that are not reflected
> >>>>through the control bus hierarchy you should really consider using the
> >>>>standardized of-graph bindings.
> >>>>(Documentation/devicetree/bindings/graph.txt)
> >>>
> >>>The problem is that the original proposal would instantiate a dummy
> >>>device, so it wouldn't be represented in DT at all. So unless you do add
> >>>two logical devices to DT (one for each bus interface), you don't have
> >>>anything to glue together with an OF graph.
> >>>
> >>I see that the having dummy device is the least desirable solution. But
> >>if there is only one control bus to the device I think it should be one
> >>device sitting beneath the control bus.
> >>
> >>You can then use of-graph to model the data path between the DSI encoder
> >>and device.
> >
> >But you will be needing a device below the DSI host controller to
> >represent that endpoint of the connection. The DSI host controller
> >itself is in no way connected to the I2C adapter. You would have to
> >add some sort of quirk to the DSI controller binding to allow it to
> 
> Thanks for the review.
> 
> I implemented this to support ADV7533 DSI to HDMI encoder chip, which
> has a DSI video bus and an i2c control bus.
> 
> There weren't any quirks as such in the device tree when I tried to
> implement this. The DT seems to manage fine without a node
> corresponding to a mipi_dsi_device:
> 
> i2c_adap@.. {
> 	adv7533@.. {
> 
> 		port {
> 			adv_in: endpoint {
> 				remote-endpoint = <&dsi_out>;
> 			};
> 		};
> 	};
> };
> 
> dsi_host@.. {
> 	...
> 	...
> 
> 	port {
> 		dsi_out: endpoint {
> 			remote-endpoint = <&adv_in>;
> 		}
> 	};
> };
> 
> It's the i2c driver's job to parse the graph and retrieve the
> phandle to the dsi host. Using this, it can proceed with
> registering itself to this host using the new dsi funcs. This
> patch does the same for the adv7533 i2c driver:
> 
> http://www.spinics.net/lists/dri-devel/msg86840.html
> 
> >hook up with a control endpoint. And then you'll need more quirks
> >to describe what kind of DSI device this is.
> 
> Could you explain what you meant by this? I.e. describing the kind
> of DSI device?

Describing the number of lanes, specifying the virtual channel, mode
flags, etc. You could probably set the number of lanes and mode flags
via the I2C driver, but especially the virtual channel cannot be set
because it isn't known to the I2C DT branch of the device.

> The dsi device created isn't really a dummy device as such. It's
> dummy in the sense that there isn't a real dsi driver associated
> with it. The dsi device is still used to attach to a mipi dsi host,
> the way normal dsi devices do.

I understand, but I don't see why it has to be instantiated by the I2C
driver, that's what I find backwards. There is already a standard way
for instantiating DSI devices, why not use it?

> >On the other hand if you properly instantiate the DSI device you can
> >easily write a driver for it, and the driver will set up the correct
> >properties as implied by the compatible string. Once you have that you
> >can easily hook it up to the I2C control interface in whatever way you
> >like, be that an OF graph or just a simple unidirectional link by
> >phandle.
> >
> 
> With the fused approach you suggested, we would have 2 drivers: one i2c
> and the other dsi. The i2c client driver would be more or less minimal,
> preparing an i2c_client device for the dsi driver to use. Is my
> understanding correct?

Correct. That's kind of similar to the way an HDMI encoder driver would
use an I2C adapter to query EDID. The i2c_client device would be a means
for the DSI driver to access the control interface.

> We can do without dummy dsi devices with this method. But, representing
> a device with 2 DT nodes seems a bit off. We'd also need to compatible
> strings for the same device, one for the i2c part, and the other for
> the dsi part.

I agree that this somewhat stretches the capabilities of device tree.
Another alternative I guess would be to not have a compatible string for
the I2C device at all (that's technically not valid, I guess) because we
really don't need an I2C driver for the device. What we really need is a
DSI driver with a means to talk over some I2C bus with some other part
of its device.

> From an adv75xx driver perspective, it should also support the ADV7511
> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
> DSI DT node. It would be a bit inconsistent to have the bindings
> require both DSI and I2C nodes for one chip, and only I2C node for the
> other, with both chips being supported by the same driver.

Why would that be inconsistent? That sounds like the most accurate
representation of the hardware to me.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-20 11:48               ` Thierry Reding
@ 2015-08-21  6:09                 ` Archit Taneja
  2015-09-07 11:46                   ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-08-21  6:09 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Lucas Stach, linux-arm-msm, linux-kernel, dri-devel, a.hajda,
	lars, Jani Nikula, devicetree



On 08/20/2015 05:18 PM, Thierry Reding wrote:
> On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
>> Hi Thierry, Lucas,
>>
>>
>> On 08/19/2015 08:32 PM, Thierry Reding wrote:
>>> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>>>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>>>> Hi Thierry, Archit,
>>>>>>
>>>> [...]
>>>>>>> Perhaps a better way would be to invert this relationship. According to
>>>>>>> your proposal we'd have to have DT like this:
>>>>>>>
>>>>>>> 	i2c@... {
>>>>>>> 		...
>>>>>>>
>>>>>>> 		dsi-device@... {
>>>>>>> 			...
>>>>>>> 			dsi-bus = <&dsi>;
>>>>>>> 			...
>>>>>>> 		};
>>>>>>>
>>>>>>> 		...
>>>>>>> 	};
>>>>>>>
>>>>>>> 	dsi@... {
>>>>>>> 		...
>>>>>>> 	};
>>>>>>>
>>>>>>> Inversing the relationship would become something like this:
>>>>>>>
>>>>>>> 	i2c@... {
>>>>>>> 		...
>>>>>>> 	};
>>>>>>>
>>>>>>> 	dsi@... {
>>>>>>> 		...
>>>>>>>
>>>>>>> 		peripheral@... {
>>>>>>> 			...
>>>>>>> 			i2c-bus = <&i2c>;
>>>>>>> 			...
>>>>>>> 		};
>>>>>>>
>>>>>>> 		...
>>>>>>> 	};
>>>>>>>
>>>>>>> Both of those aren't fundamentally different, and they both have the
>>>>>>> disavantage of lacking ways to transport configuration data that the
>>>>>>> other bus needs to instantiate the dummy device (such as the reg
>>>>>>> property for example, denoting the I2C slave address or the DSI VC).
>>>>>>>
>>>>>>> So how about we create two devices in the device tree and fuse them at
>>>>>>> the driver level:
>>>>>>>
>>>>>>> 	i2c@... {
>>>>>>> 		...
>>>>>>>
>>>>>>> 		i2cdsi: dsi-device@... {
>>>>>>> 			...
>>>>>>> 		};
>>>>>>>
>>>>>>> 		...
>>>>>>> 	};
>>>>>>>
>>>>>>> 	dsi@... {
>>>>>>> 		...
>>>>>>>
>>>>>>> 		peripheral@... {
>>>>>>> 			...
>>>>>>> 			control = <&i2cdsi>;
>>>>>>> 			...
>>>>>>> 		};
>>>>>>>
>>>>>>> 		...
>>>>>>> 	};
>>>>>>>
>>>>>>> This way we'll get both an I2C device and a DSI device that we can fully
>>>>>>> describe using the standard device tree bindings. At driver time we can
>>>>>>> get the I2C device from the phandle in the control property of the DSI
>>>>>>> device and use it to execute I2C transactions.
>>>>>>>
>>>>>> I don't really like to see that you are inventing yet-another-way to
>>>>>> handle devices connected to multiple buses.
>>>>>>
>>>>>> Devicetree is structured along the control buses, even if the devices
>>>>>> are connected to multiple buses, in the DT they are always children of
>>>>>> the bus that is used to control their registers from the CPUs
>>>>>> perspective. So a DSI encoder that is controlled through i2c is clearly
>>>>>> a child of the i2c master controller and only of that one.
>>>>>
>>>>> I think that's a flawed interpretation of what's going on here. The
>>>>> device in fact has two interfaces: one is I2C, the other is DSI. In my
>>>>> opinion that's reason enough to represent it as two logical devices.
>>>>>
>>>> Does it really have 2 control interfaces that are used at the same time?
>>>> Or is the DSI connection a passive data bus if the register control
>>>> happens through i2c?
>>>
>>> The interfaces may not be used at the same time, and the DSI interface
>>> may even be crippled, but the device is still addressable from the DSI
>>> host controller, if for nothing else than for routing the video stream.
>>>
>>>>>> If you need to model connections between devices that are not reflected
>>>>>> through the control bus hierarchy you should really consider using the
>>>>>> standardized of-graph bindings.
>>>>>> (Documentation/devicetree/bindings/graph.txt)
>>>>>
>>>>> The problem is that the original proposal would instantiate a dummy
>>>>> device, so it wouldn't be represented in DT at all. So unless you do add
>>>>> two logical devices to DT (one for each bus interface), you don't have
>>>>> anything to glue together with an OF graph.
>>>>>
>>>> I see that the having dummy device is the least desirable solution. But
>>>> if there is only one control bus to the device I think it should be one
>>>> device sitting beneath the control bus.
>>>>
>>>> You can then use of-graph to model the data path between the DSI encoder
>>>> and device.
>>>
>>> But you will be needing a device below the DSI host controller to
>>> represent that endpoint of the connection. The DSI host controller
>>> itself is in no way connected to the I2C adapter. You would have to
>>> add some sort of quirk to the DSI controller binding to allow it to
>>
>> Thanks for the review.
>>
>> I implemented this to support ADV7533 DSI to HDMI encoder chip, which
>> has a DSI video bus and an i2c control bus.
>>
>> There weren't any quirks as such in the device tree when I tried to
>> implement this. The DT seems to manage fine without a node
>> corresponding to a mipi_dsi_device:
>>
>> i2c_adap@.. {
>> 	adv7533@.. {
>>
>> 		port {
>> 			adv_in: endpoint {
>> 				remote-endpoint = <&dsi_out>;
>> 			};
>> 		};
>> 	};
>> };
>>
>> dsi_host@.. {
>> 	...
>> 	...
>>
>> 	port {
>> 		dsi_out: endpoint {
>> 			remote-endpoint = <&adv_in>;
>> 		}
>> 	};
>> };
>>
>> It's the i2c driver's job to parse the graph and retrieve the
>> phandle to the dsi host. Using this, it can proceed with
>> registering itself to this host using the new dsi funcs. This
>> patch does the same for the adv7533 i2c driver:
>>
>> http://www.spinics.net/lists/dri-devel/msg86840.html
>>
>>> hook up with a control endpoint. And then you'll need more quirks
>>> to describe what kind of DSI device this is.
>>
>> Could you explain what you meant by this? I.e. describing the kind
>> of DSI device?
>
> Describing the number of lanes, specifying the virtual channel, mode
> flags, etc. You could probably set the number of lanes and mode flags
> via the I2C driver, but especially the virtual channel cannot be set
> because it isn't known to the I2C DT branch of the device.

I agree with the VC part. It could be a DT entry within the i2c client 
node, but that does make it seem like a quirk. The 'reg' way under the
DSI host is definitely better to populate the virtual channel.

>
>> The dsi device created isn't really a dummy device as such. It's
>> dummy in the sense that there isn't a real dsi driver associated
>> with it. The dsi device is still used to attach to a mipi dsi host,
>> the way normal dsi devices do.
>
> I understand, but I don't see why it has to be instantiated by the I2C
> driver, that's what I find backwards. There is already a standard way
> for instantiating DSI devices, why not use it?

I assumed we could either represent the device using an i2c driver, or
dsi, but not both. Hence, I came up with this approach.

>
>>> On the other hand if you properly instantiate the DSI device you can
>>> easily write a driver for it, and the driver will set up the correct
>>> properties as implied by the compatible string. Once you have that you
>>> can easily hook it up to the I2C control interface in whatever way you
>>> like, be that an OF graph or just a simple unidirectional link by
>>> phandle.
>>>
>>
>> With the fused approach you suggested, we would have 2 drivers: one i2c
>> and the other dsi. The i2c client driver would be more or less minimal,
>> preparing an i2c_client device for the dsi driver to use. Is my
>> understanding correct?
>
> Correct. That's kind of similar to the way an HDMI encoder driver would
> use an I2C adapter to query EDID. The i2c_client device would be a means
> for the DSI driver to access the control interface.

Okay.

Although, I'm not sure about the HDMI encoder example. An HDMI
encoder would read off edid directly from the adapter(with an address
specified), it wouldn't need to create an i2c client device. Therefore,
an HDMI encoder wouldn't need to have a separate node for i2c in DT.

>
>> We can do without dummy dsi devices with this method. But, representing
>> a device with 2 DT nodes seems a bit off. We'd also need to compatible
>> strings for the same device, one for the i2c part, and the other for
>> the dsi part.
>
> I agree that this somewhat stretches the capabilities of device tree.
> Another alternative I guess would be to not have a compatible string for
> the I2C device at all (that's technically not valid, I guess) because we
> really don't need an I2C driver for the device. What we really need is a
> DSI driver with a means to talk over some I2C bus with some other part
> of its device.

I think what the driver should 'really' be is a bit subjective, and can
vary based on what the buses are used for in the device. For the Toshiba
chip that Jani mentioned, it tends more towards a DSI driver. Whereas,
for an ADV75xx chip, it's closer to an I2C driver since only I2C can be
used to configure the chip registers.

Although, I agree with the point you made about the DSI bus here:

"and the DSI interface may even be crippled, but the device is still 
addressable from the DSI host controller, if for nothing else than for 
routing the video stream."

The fact that the data on the DSI bus contains routing information (i.e, 
virtual channel number) always gives it some 'control' aspect.

>
>>  From an adv75xx driver perspective, it should also support the ADV7511
>> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
>> DSI DT node. It would be a bit inconsistent to have the bindings
>> require both DSI and I2C nodes for one chip, and only I2C node for the
>> other, with both chips being supported by the same driver.
>
> Why would that be inconsistent? That sounds like the most accurate
> representation of the hardware to me.

Inconsistent wasn't the right term. I should have used 'uncommon' :)
It's common for two chips of the same family to have a different set
optional properties in DT, but it's not common for two chips of the
same family to be represented by a different number of devices in
DT.

I don't have an issue with the fused approach you suggested, as long
as people are okay with the DT parts. Especially the part of needing 2
compatible strings in the DT.

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-08-21  6:09                 ` Archit Taneja
@ 2015-09-07 11:46                   ` Archit Taneja
  2015-09-08 10:27                     ` Andrzej Hajda
  0 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-09-07 11:46 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Lucas Stach, linux-arm-msm, linux-kernel, dri-devel, a.hajda,
	lars, Jani Nikula, devicetree

Thierry,

On 08/21/2015 11:39 AM, Archit Taneja wrote:
>
>
> On 08/20/2015 05:18 PM, Thierry Reding wrote:
>> On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
>>> Hi Thierry, Lucas,
>>>
>>>
>>> On 08/19/2015 08:32 PM, Thierry Reding wrote:
>>>> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>>>>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>>>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>>>>> Hi Thierry, Archit,
>>>>>>>
>>>>> [...]
>>>>>>>> Perhaps a better way would be to invert this relationship.
>>>>>>>> According to
>>>>>>>> your proposal we'd have to have DT like this:
>>>>>>>>
>>>>>>>>     i2c@... {
>>>>>>>>         ...
>>>>>>>>
>>>>>>>>         dsi-device@... {
>>>>>>>>             ...
>>>>>>>>             dsi-bus = <&dsi>;
>>>>>>>>             ...
>>>>>>>>         };
>>>>>>>>
>>>>>>>>         ...
>>>>>>>>     };
>>>>>>>>
>>>>>>>>     dsi@... {
>>>>>>>>         ...
>>>>>>>>     };
>>>>>>>>
>>>>>>>> Inversing the relationship would become something like this:
>>>>>>>>
>>>>>>>>     i2c@... {
>>>>>>>>         ...
>>>>>>>>     };
>>>>>>>>
>>>>>>>>     dsi@... {
>>>>>>>>         ...
>>>>>>>>
>>>>>>>>         peripheral@... {
>>>>>>>>             ...
>>>>>>>>             i2c-bus = <&i2c>;
>>>>>>>>             ...
>>>>>>>>         };
>>>>>>>>
>>>>>>>>         ...
>>>>>>>>     };
>>>>>>>>
>>>>>>>> Both of those aren't fundamentally different, and they both have
>>>>>>>> the
>>>>>>>> disavantage of lacking ways to transport configuration data that
>>>>>>>> the
>>>>>>>> other bus needs to instantiate the dummy device (such as the reg
>>>>>>>> property for example, denoting the I2C slave address or the DSI
>>>>>>>> VC).
>>>>>>>>
>>>>>>>> So how about we create two devices in the device tree and fuse
>>>>>>>> them at
>>>>>>>> the driver level:
>>>>>>>>
>>>>>>>>     i2c@... {
>>>>>>>>         ...
>>>>>>>>
>>>>>>>>         i2cdsi: dsi-device@... {
>>>>>>>>             ...
>>>>>>>>         };
>>>>>>>>
>>>>>>>>         ...
>>>>>>>>     };
>>>>>>>>
>>>>>>>>     dsi@... {
>>>>>>>>         ...
>>>>>>>>
>>>>>>>>         peripheral@... {
>>>>>>>>             ...
>>>>>>>>             control = <&i2cdsi>;
>>>>>>>>             ...
>>>>>>>>         };
>>>>>>>>
>>>>>>>>         ...
>>>>>>>>     };
>>>>>>>>
>>>>>>>> This way we'll get both an I2C device and a DSI device that we
>>>>>>>> can fully
>>>>>>>> describe using the standard device tree bindings. At driver time
>>>>>>>> we can
>>>>>>>> get the I2C device from the phandle in the control property of
>>>>>>>> the DSI
>>>>>>>> device and use it to execute I2C transactions.
>>>>>>>>
>>>>>>> I don't really like to see that you are inventing yet-another-way to
>>>>>>> handle devices connected to multiple buses.
>>>>>>>
>>>>>>> Devicetree is structured along the control buses, even if the
>>>>>>> devices
>>>>>>> are connected to multiple buses, in the DT they are always
>>>>>>> children of
>>>>>>> the bus that is used to control their registers from the CPUs
>>>>>>> perspective. So a DSI encoder that is controlled through i2c is
>>>>>>> clearly
>>>>>>> a child of the i2c master controller and only of that one.
>>>>>>
>>>>>> I think that's a flawed interpretation of what's going on here. The
>>>>>> device in fact has two interfaces: one is I2C, the other is DSI.
>>>>>> In my
>>>>>> opinion that's reason enough to represent it as two logical devices.
>>>>>>
>>>>> Does it really have 2 control interfaces that are used at the same
>>>>> time?
>>>>> Or is the DSI connection a passive data bus if the register control
>>>>> happens through i2c?
>>>>
>>>> The interfaces may not be used at the same time, and the DSI interface
>>>> may even be crippled, but the device is still addressable from the DSI
>>>> host controller, if for nothing else than for routing the video stream.
>>>>
>>>>>>> If you need to model connections between devices that are not
>>>>>>> reflected
>>>>>>> through the control bus hierarchy you should really consider
>>>>>>> using the
>>>>>>> standardized of-graph bindings.
>>>>>>> (Documentation/devicetree/bindings/graph.txt)
>>>>>>
>>>>>> The problem is that the original proposal would instantiate a dummy
>>>>>> device, so it wouldn't be represented in DT at all. So unless you
>>>>>> do add
>>>>>> two logical devices to DT (one for each bus interface), you don't
>>>>>> have
>>>>>> anything to glue together with an OF graph.
>>>>>>
>>>>> I see that the having dummy device is the least desirable solution.
>>>>> But
>>>>> if there is only one control bus to the device I think it should be
>>>>> one
>>>>> device sitting beneath the control bus.
>>>>>
>>>>> You can then use of-graph to model the data path between the DSI
>>>>> encoder
>>>>> and device.
>>>>
>>>> But you will be needing a device below the DSI host controller to
>>>> represent that endpoint of the connection. The DSI host controller
>>>> itself is in no way connected to the I2C adapter. You would have to
>>>> add some sort of quirk to the DSI controller binding to allow it to
>>>
>>> Thanks for the review.
>>>
>>> I implemented this to support ADV7533 DSI to HDMI encoder chip, which
>>> has a DSI video bus and an i2c control bus.
>>>
>>> There weren't any quirks as such in the device tree when I tried to
>>> implement this. The DT seems to manage fine without a node
>>> corresponding to a mipi_dsi_device:
>>>
>>> i2c_adap@.. {
>>>     adv7533@.. {
>>>
>>>         port {
>>>             adv_in: endpoint {
>>>                 remote-endpoint = <&dsi_out>;
>>>             };
>>>         };
>>>     };
>>> };
>>>
>>> dsi_host@.. {
>>>     ...
>>>     ...
>>>
>>>     port {
>>>         dsi_out: endpoint {
>>>             remote-endpoint = <&adv_in>;
>>>         }
>>>     };
>>> };
>>>
>>> It's the i2c driver's job to parse the graph and retrieve the
>>> phandle to the dsi host. Using this, it can proceed with
>>> registering itself to this host using the new dsi funcs. This
>>> patch does the same for the adv7533 i2c driver:
>>>
>>> http://www.spinics.net/lists/dri-devel/msg86840.html
>>>
>>>> hook up with a control endpoint. And then you'll need more quirks
>>>> to describe what kind of DSI device this is.
>>>
>>> Could you explain what you meant by this? I.e. describing the kind
>>> of DSI device?
>>
>> Describing the number of lanes, specifying the virtual channel, mode
>> flags, etc. You could probably set the number of lanes and mode flags
>> via the I2C driver, but especially the virtual channel cannot be set
>> because it isn't known to the I2C DT branch of the device.
>
> I agree with the VC part. It could be a DT entry within the i2c client
> node, but that does make it seem like a quirk. The 'reg' way under the
> DSI host is definitely better to populate the virtual channel.
>
>>
>>> The dsi device created isn't really a dummy device as such. It's
>>> dummy in the sense that there isn't a real dsi driver associated
>>> with it. The dsi device is still used to attach to a mipi dsi host,
>>> the way normal dsi devices do.
>>
>> I understand, but I don't see why it has to be instantiated by the I2C
>> driver, that's what I find backwards. There is already a standard way
>> for instantiating DSI devices, why not use it?
>
> I assumed we could either represent the device using an i2c driver, or
> dsi, but not both. Hence, I came up with this approach.
>
>>
>>>> On the other hand if you properly instantiate the DSI device you can
>>>> easily write a driver for it, and the driver will set up the correct
>>>> properties as implied by the compatible string. Once you have that you
>>>> can easily hook it up to the I2C control interface in whatever way you
>>>> like, be that an OF graph or just a simple unidirectional link by
>>>> phandle.
>>>>
>>>
>>> With the fused approach you suggested, we would have 2 drivers: one i2c
>>> and the other dsi. The i2c client driver would be more or less minimal,
>>> preparing an i2c_client device for the dsi driver to use. Is my
>>> understanding correct?
>>
>> Correct. That's kind of similar to the way an HDMI encoder driver would
>> use an I2C adapter to query EDID. The i2c_client device would be a means
>> for the DSI driver to access the control interface.
>
> Okay.
>
> Although, I'm not sure about the HDMI encoder example. An HDMI
> encoder would read off edid directly from the adapter(with an address
> specified), it wouldn't need to create an i2c client device. Therefore,
> an HDMI encoder wouldn't need to have a separate node for i2c in DT.
>
>>
>>> We can do without dummy dsi devices with this method. But, representing
>>> a device with 2 DT nodes seems a bit off. We'd also need to compatible
>>> strings for the same device, one for the i2c part, and the other for
>>> the dsi part.
>>
>> I agree that this somewhat stretches the capabilities of device tree.
>> Another alternative I guess would be to not have a compatible string for
>> the I2C device at all (that's technically not valid, I guess) because we
>> really don't need an I2C driver for the device. What we really need is a
>> DSI driver with a means to talk over some I2C bus with some other part
>> of its device.
>
> I think what the driver should 'really' be is a bit subjective, and can
> vary based on what the buses are used for in the device. For the Toshiba
> chip that Jani mentioned, it tends more towards a DSI driver. Whereas,
> for an ADV75xx chip, it's closer to an I2C driver since only I2C can be
> used to configure the chip registers.
>
> Although, I agree with the point you made about the DSI bus here:
>
> "and the DSI interface may even be crippled, but the device is still
> addressable from the DSI host controller, if for nothing else than for
> routing the video stream."
>
> The fact that the data on the DSI bus contains routing information (i.e,
> virtual channel number) always gives it some 'control' aspect.
>
>>
>>>  From an adv75xx driver perspective, it should also support the ADV7511
>>> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
>>> DSI DT node. It would be a bit inconsistent to have the bindings
>>> require both DSI and I2C nodes for one chip, and only I2C node for the
>>> other, with both chips being supported by the same driver.
>>
>> Why would that be inconsistent? That sounds like the most accurate
>> representation of the hardware to me.
>
> Inconsistent wasn't the right term. I should have used 'uncommon' :)
> It's common for two chips of the same family to have a different set
> optional properties in DT, but it's not common for two chips of the
> same family to be represented by a different number of devices in
> DT.
>
> I don't have an issue with the fused approach you suggested, as long
> as people are okay with the DT parts. Especially the part of needing 2
> compatible strings in the DT.

I implemented the ADV7533 driver with the approach you suggested above
(2 drivers for 2 different components of the chip). I posted it out
just a while back (with you in loop).

The DT node with this apporach would look like this:

https://github.com/boddob/linux/blob/c24cbf63a6998d00095c10122ce5e37b764c7dba/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi#L162

The main irritant with the '2 driver' approach is that we need to
share the per-device driver data with them. For ADV7533, I've made
the i2c driver allocate driver data (struct adv7511).

The dsi driver gets the driver data in the following way:

- The i2c driver sets the driver data as its client data using
   i2c_set_clientdata()
- Parse the i2c-control phandle to get the corresponding i2c client.
- Extract the adv7511 struct by getting i2c_get_clientdata()

This way of getting the same driver data is a bit strange, but it
works. For this, we do need to ensure that the dsi driver defers
as long as the i2c driver isn't probed.

I've now implemented both approaches for the driver. The first using
a dummy dsi device, and this one using 2 drivers (with both being
represented in DT). The advantage of the latter is that we don't need
to create any dummy device stuff, the disadvantage is that DT is a bit
uncommon.

Can we now come to a conclusion on what approach is better?

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-09-07 11:46                   ` Archit Taneja
@ 2015-09-08 10:27                     ` Andrzej Hajda
  2015-09-10  6:15                       ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Andrzej Hajda @ 2015-09-08 10:27 UTC (permalink / raw)
  To: Archit Taneja, Thierry Reding
  Cc: devicetree, linux-arm-msm, linux-kernel, dri-devel

On 09/07/2015 01:46 PM, Archit Taneja wrote:
> Thierry,
> 
> On 08/21/2015 11:39 AM, Archit Taneja wrote:
>>
>>
>> On 08/20/2015 05:18 PM, Thierry Reding wrote:
>>> On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
>>>> Hi Thierry, Lucas,
>>>>
>>>>
>>>> On 08/19/2015 08:32 PM, Thierry Reding wrote:
>>>>> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>>>>>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>>>>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>>>>>> Hi Thierry, Archit,
>>>>>>>>
>>>>>> [...]
>>>>>>>>> Perhaps a better way would be to invert this relationship.
>>>>>>>>> According to
>>>>>>>>> your proposal we'd have to have DT like this:
>>>>>>>>>
>>>>>>>>>     i2c@... {
>>>>>>>>>         ...
>>>>>>>>>
>>>>>>>>>         dsi-device@... {
>>>>>>>>>             ...
>>>>>>>>>             dsi-bus = <&dsi>;
>>>>>>>>>             ...
>>>>>>>>>         };
>>>>>>>>>
>>>>>>>>>         ...
>>>>>>>>>     };
>>>>>>>>>
>>>>>>>>>     dsi@... {
>>>>>>>>>         ...
>>>>>>>>>     };
>>>>>>>>>
>>>>>>>>> Inversing the relationship would become something like this:
>>>>>>>>>
>>>>>>>>>     i2c@... {
>>>>>>>>>         ...
>>>>>>>>>     };
>>>>>>>>>
>>>>>>>>>     dsi@... {
>>>>>>>>>         ...
>>>>>>>>>
>>>>>>>>>         peripheral@... {
>>>>>>>>>             ...
>>>>>>>>>             i2c-bus = <&i2c>;
>>>>>>>>>             ...
>>>>>>>>>         };
>>>>>>>>>
>>>>>>>>>         ...
>>>>>>>>>     };
>>>>>>>>>
>>>>>>>>> Both of those aren't fundamentally different, and they both have
>>>>>>>>> the
>>>>>>>>> disavantage of lacking ways to transport configuration data that
>>>>>>>>> the
>>>>>>>>> other bus needs to instantiate the dummy device (such as the reg
>>>>>>>>> property for example, denoting the I2C slave address or the DSI
>>>>>>>>> VC).
>>>>>>>>>
>>>>>>>>> So how about we create two devices in the device tree and fuse
>>>>>>>>> them at
>>>>>>>>> the driver level:
>>>>>>>>>
>>>>>>>>>     i2c@... {
>>>>>>>>>         ...
>>>>>>>>>
>>>>>>>>>         i2cdsi: dsi-device@... {
>>>>>>>>>             ...
>>>>>>>>>         };
>>>>>>>>>
>>>>>>>>>         ...
>>>>>>>>>     };
>>>>>>>>>
>>>>>>>>>     dsi@... {
>>>>>>>>>         ...
>>>>>>>>>
>>>>>>>>>         peripheral@... {
>>>>>>>>>             ...
>>>>>>>>>             control = <&i2cdsi>;
>>>>>>>>>             ...
>>>>>>>>>         };
>>>>>>>>>
>>>>>>>>>         ...
>>>>>>>>>     };
>>>>>>>>>
>>>>>>>>> This way we'll get both an I2C device and a DSI device that we
>>>>>>>>> can fully
>>>>>>>>> describe using the standard device tree bindings. At driver time
>>>>>>>>> we can
>>>>>>>>> get the I2C device from the phandle in the control property of
>>>>>>>>> the DSI
>>>>>>>>> device and use it to execute I2C transactions.
>>>>>>>>>
>>>>>>>> I don't really like to see that you are inventing yet-another-way to
>>>>>>>> handle devices connected to multiple buses.
>>>>>>>>
>>>>>>>> Devicetree is structured along the control buses, even if the
>>>>>>>> devices
>>>>>>>> are connected to multiple buses, in the DT they are always
>>>>>>>> children of
>>>>>>>> the bus that is used to control their registers from the CPUs
>>>>>>>> perspective. So a DSI encoder that is controlled through i2c is
>>>>>>>> clearly
>>>>>>>> a child of the i2c master controller and only of that one.
>>>>>>>
>>>>>>> I think that's a flawed interpretation of what's going on here. The
>>>>>>> device in fact has two interfaces: one is I2C, the other is DSI.
>>>>>>> In my
>>>>>>> opinion that's reason enough to represent it as two logical devices.
>>>>>>>
>>>>>> Does it really have 2 control interfaces that are used at the same
>>>>>> time?
>>>>>> Or is the DSI connection a passive data bus if the register control
>>>>>> happens through i2c?
>>>>>
>>>>> The interfaces may not be used at the same time, and the DSI interface
>>>>> may even be crippled, but the device is still addressable from the DSI
>>>>> host controller, if for nothing else than for routing the video stream.
>>>>>
>>>>>>>> If you need to model connections between devices that are not
>>>>>>>> reflected
>>>>>>>> through the control bus hierarchy you should really consider
>>>>>>>> using the
>>>>>>>> standardized of-graph bindings.
>>>>>>>> (Documentation/devicetree/bindings/graph.txt)
>>>>>>>
>>>>>>> The problem is that the original proposal would instantiate a dummy
>>>>>>> device, so it wouldn't be represented in DT at all. So unless you
>>>>>>> do add
>>>>>>> two logical devices to DT (one for each bus interface), you don't
>>>>>>> have
>>>>>>> anything to glue together with an OF graph.
>>>>>>>
>>>>>> I see that the having dummy device is the least desirable solution.
>>>>>> But
>>>>>> if there is only one control bus to the device I think it should be
>>>>>> one
>>>>>> device sitting beneath the control bus.
>>>>>>
>>>>>> You can then use of-graph to model the data path between the DSI
>>>>>> encoder
>>>>>> and device.
>>>>>
>>>>> But you will be needing a device below the DSI host controller to
>>>>> represent that endpoint of the connection. The DSI host controller
>>>>> itself is in no way connected to the I2C adapter. You would have to
>>>>> add some sort of quirk to the DSI controller binding to allow it to
>>>>
>>>> Thanks for the review.
>>>>
>>>> I implemented this to support ADV7533 DSI to HDMI encoder chip, which
>>>> has a DSI video bus and an i2c control bus.
>>>>
>>>> There weren't any quirks as such in the device tree when I tried to
>>>> implement this. The DT seems to manage fine without a node
>>>> corresponding to a mipi_dsi_device:
>>>>
>>>> i2c_adap@.. {
>>>>     adv7533@.. {
>>>>
>>>>         port {
>>>>             adv_in: endpoint {
>>>>                 remote-endpoint = <&dsi_out>;
>>>>             };
>>>>         };
>>>>     };
>>>> };
>>>>
>>>> dsi_host@.. {
>>>>     ...
>>>>     ...
>>>>
>>>>     port {
>>>>         dsi_out: endpoint {
>>>>             remote-endpoint = <&adv_in>;
>>>>         }
>>>>     };
>>>> };
>>>>
>>>> It's the i2c driver's job to parse the graph and retrieve the
>>>> phandle to the dsi host. Using this, it can proceed with
>>>> registering itself to this host using the new dsi funcs. This
>>>> patch does the same for the adv7533 i2c driver:
>>>>
>>>> http://www.spinics.net/lists/dri-devel/msg86840.html
>>>>
>>>>> hook up with a control endpoint. And then you'll need more quirks
>>>>> to describe what kind of DSI device this is.
>>>>
>>>> Could you explain what you meant by this? I.e. describing the kind
>>>> of DSI device?
>>>
>>> Describing the number of lanes, specifying the virtual channel, mode
>>> flags, etc. You could probably set the number of lanes and mode flags
>>> via the I2C driver, but especially the virtual channel cannot be set
>>> because it isn't known to the I2C DT branch of the device.
>>
>> I agree with the VC part. It could be a DT entry within the i2c client
>> node, but that does make it seem like a quirk. The 'reg' way under the
>> DSI host is definitely better to populate the virtual channel.
>>
>>>
>>>> The dsi device created isn't really a dummy device as such. It's
>>>> dummy in the sense that there isn't a real dsi driver associated
>>>> with it. The dsi device is still used to attach to a mipi dsi host,
>>>> the way normal dsi devices do.
>>>
>>> I understand, but I don't see why it has to be instantiated by the I2C
>>> driver, that's what I find backwards. There is already a standard way
>>> for instantiating DSI devices, why not use it?
>>
>> I assumed we could either represent the device using an i2c driver, or
>> dsi, but not both. Hence, I came up with this approach.
>>
>>>
>>>>> On the other hand if you properly instantiate the DSI device you can
>>>>> easily write a driver for it, and the driver will set up the correct
>>>>> properties as implied by the compatible string. Once you have that you
>>>>> can easily hook it up to the I2C control interface in whatever way you
>>>>> like, be that an OF graph or just a simple unidirectional link by
>>>>> phandle.
>>>>>
>>>>
>>>> With the fused approach you suggested, we would have 2 drivers: one i2c
>>>> and the other dsi. The i2c client driver would be more or less minimal,
>>>> preparing an i2c_client device for the dsi driver to use. Is my
>>>> understanding correct?
>>>
>>> Correct. That's kind of similar to the way an HDMI encoder driver would
>>> use an I2C adapter to query EDID. The i2c_client device would be a means
>>> for the DSI driver to access the control interface.
>>
>> Okay.
>>
>> Although, I'm not sure about the HDMI encoder example. An HDMI
>> encoder would read off edid directly from the adapter(with an address
>> specified), it wouldn't need to create an i2c client device. Therefore,
>> an HDMI encoder wouldn't need to have a separate node for i2c in DT.
>>
>>>
>>>> We can do without dummy dsi devices with this method. But, representing
>>>> a device with 2 DT nodes seems a bit off. We'd also need to compatible
>>>> strings for the same device, one for the i2c part, and the other for
>>>> the dsi part.
>>>
>>> I agree that this somewhat stretches the capabilities of device tree.
>>> Another alternative I guess would be to not have a compatible string for
>>> the I2C device at all (that's technically not valid, I guess) because we
>>> really don't need an I2C driver for the device. What we really need is a
>>> DSI driver with a means to talk over some I2C bus with some other part
>>> of its device.
>>
>> I think what the driver should 'really' be is a bit subjective, and can
>> vary based on what the buses are used for in the device. For the Toshiba
>> chip that Jani mentioned, it tends more towards a DSI driver. Whereas,
>> for an ADV75xx chip, it's closer to an I2C driver since only I2C can be
>> used to configure the chip registers.
>>
>> Although, I agree with the point you made about the DSI bus here:
>>
>> "and the DSI interface may even be crippled, but the device is still
>> addressable from the DSI host controller, if for nothing else than for
>> routing the video stream."
>>
>> The fact that the data on the DSI bus contains routing information (i.e,
>> virtual channel number) always gives it some 'control' aspect.
>>
>>>
>>>>  From an adv75xx driver perspective, it should also support the ADV7511
>>>> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
>>>> DSI DT node. It would be a bit inconsistent to have the bindings
>>>> require both DSI and I2C nodes for one chip, and only I2C node for the
>>>> other, with both chips being supported by the same driver.
>>>
>>> Why would that be inconsistent? That sounds like the most accurate
>>> representation of the hardware to me.
>>
>> Inconsistent wasn't the right term. I should have used 'uncommon' :)
>> It's common for two chips of the same family to have a different set
>> optional properties in DT, but it's not common for two chips of the
>> same family to be represented by a different number of devices in
>> DT.
>>
>> I don't have an issue with the fused approach you suggested, as long
>> as people are okay with the DT parts. Especially the part of needing 2
>> compatible strings in the DT.
> 
> I implemented the ADV7533 driver with the approach you suggested above
> (2 drivers for 2 different components of the chip). I posted it out
> just a while back (with you in loop).
> 
> The DT node with this apporach would look like this:
> 
> https://github.com/boddob/linux/blob/c24cbf63a6998d00095c10122ce5e37b764c7dba/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi#L162
> 
> The main irritant with the '2 driver' approach is that we need to
> share the per-device driver data with them. For ADV7533, I've made
> the i2c driver allocate driver data (struct adv7511).
> 
> The dsi driver gets the driver data in the following way:
> 
> - The i2c driver sets the driver data as its client data using
>    i2c_set_clientdata()
> - Parse the i2c-control phandle to get the corresponding i2c client.
> - Extract the adv7511 struct by getting i2c_get_clientdata()
> 
> This way of getting the same driver data is a bit strange, but it
> works. For this, we do need to ensure that the dsi driver defers
> as long as the i2c driver isn't probed.
> 
> I've now implemented both approaches for the driver. The first using
> a dummy dsi device, and this one using 2 drivers (with both being
> represented in DT). The advantage of the latter is that we don't need
> to create any dummy device stuff, the disadvantage is that DT is a bit
> uncommon.
> 
> Can we now come to a conclusion on what approach is better?

DSI by design is data bus which can be used additionally as a control bus, but
in this particular case it is purely data bus. So of-graph bindings seem to be
better choice. As already Lucas Stach said DT hierarchy should describe control
buses and of-graph bindings should describe data bus. Argument that hw has two
interfaces does not seem to be valid here - it has only one control interface.
The other one is only for data, representing every data interface using DT
hierarchy would lead to inflation of pseudo devices.

On the other side I do not see dummy device approach ideal solution, I guess
lightweight framework providing DSI hosts detached from Linux device model could
work better here.
The only problem here is that it should coexist somehow with dsi bus used to
control devices. Anyway implementing it shouldn't be hard, question is if it
would be eventually accepted :) I guess we can live for now with dummy devs.

Summarizing I would prefer version with dummy devices, as it seems more
compatible with DT design.

Regards
Andrzej


> 
> Thanks,
> Archit
> 


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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-09-08 10:27                     ` Andrzej Hajda
@ 2015-09-10  6:15                       ` Archit Taneja
  2015-09-10  7:32                         ` Thierry Reding
  0 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-09-10  6:15 UTC (permalink / raw)
  To: Andrzej Hajda, Thierry Reding
  Cc: devicetree, linux-arm-msm, linux-kernel, dri-devel



On 09/08/2015 03:57 PM, Andrzej Hajda wrote:
> On 09/07/2015 01:46 PM, Archit Taneja wrote:
>> Thierry,
>>
>> On 08/21/2015 11:39 AM, Archit Taneja wrote:
>>>
>>>
>>> On 08/20/2015 05:18 PM, Thierry Reding wrote:
>>>> On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
>>>>> Hi Thierry, Lucas,
>>>>>
>>>>>
>>>>> On 08/19/2015 08:32 PM, Thierry Reding wrote:
>>>>>> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>>>>>>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>>>>>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>>>>>>> Hi Thierry, Archit,
>>>>>>>>>
>>>>>>> [...]
>>>>>>>>>> Perhaps a better way would be to invert this relationship.
>>>>>>>>>> According to
>>>>>>>>>> your proposal we'd have to have DT like this:
>>>>>>>>>>
>>>>>>>>>>      i2c@... {
>>>>>>>>>>          ...
>>>>>>>>>>
>>>>>>>>>>          dsi-device@... {
>>>>>>>>>>              ...
>>>>>>>>>>              dsi-bus = <&dsi>;
>>>>>>>>>>              ...
>>>>>>>>>>          };
>>>>>>>>>>
>>>>>>>>>>          ...
>>>>>>>>>>      };
>>>>>>>>>>
>>>>>>>>>>      dsi@... {
>>>>>>>>>>          ...
>>>>>>>>>>      };
>>>>>>>>>>
>>>>>>>>>> Inversing the relationship would become something like this:
>>>>>>>>>>
>>>>>>>>>>      i2c@... {
>>>>>>>>>>          ...
>>>>>>>>>>      };
>>>>>>>>>>
>>>>>>>>>>      dsi@... {
>>>>>>>>>>          ...
>>>>>>>>>>
>>>>>>>>>>          peripheral@... {
>>>>>>>>>>              ...
>>>>>>>>>>              i2c-bus = <&i2c>;
>>>>>>>>>>              ...
>>>>>>>>>>          };
>>>>>>>>>>
>>>>>>>>>>          ...
>>>>>>>>>>      };
>>>>>>>>>>
>>>>>>>>>> Both of those aren't fundamentally different, and they both have
>>>>>>>>>> the
>>>>>>>>>> disavantage of lacking ways to transport configuration data that
>>>>>>>>>> the
>>>>>>>>>> other bus needs to instantiate the dummy device (such as the reg
>>>>>>>>>> property for example, denoting the I2C slave address or the DSI
>>>>>>>>>> VC).
>>>>>>>>>>
>>>>>>>>>> So how about we create two devices in the device tree and fuse
>>>>>>>>>> them at
>>>>>>>>>> the driver level:
>>>>>>>>>>
>>>>>>>>>>      i2c@... {
>>>>>>>>>>          ...
>>>>>>>>>>
>>>>>>>>>>          i2cdsi: dsi-device@... {
>>>>>>>>>>              ...
>>>>>>>>>>          };
>>>>>>>>>>
>>>>>>>>>>          ...
>>>>>>>>>>      };
>>>>>>>>>>
>>>>>>>>>>      dsi@... {
>>>>>>>>>>          ...
>>>>>>>>>>
>>>>>>>>>>          peripheral@... {
>>>>>>>>>>              ...
>>>>>>>>>>              control = <&i2cdsi>;
>>>>>>>>>>              ...
>>>>>>>>>>          };
>>>>>>>>>>
>>>>>>>>>>          ...
>>>>>>>>>>      };
>>>>>>>>>>
>>>>>>>>>> This way we'll get both an I2C device and a DSI device that we
>>>>>>>>>> can fully
>>>>>>>>>> describe using the standard device tree bindings. At driver time
>>>>>>>>>> we can
>>>>>>>>>> get the I2C device from the phandle in the control property of
>>>>>>>>>> the DSI
>>>>>>>>>> device and use it to execute I2C transactions.
>>>>>>>>>>
>>>>>>>>> I don't really like to see that you are inventing yet-another-way to
>>>>>>>>> handle devices connected to multiple buses.
>>>>>>>>>
>>>>>>>>> Devicetree is structured along the control buses, even if the
>>>>>>>>> devices
>>>>>>>>> are connected to multiple buses, in the DT they are always
>>>>>>>>> children of
>>>>>>>>> the bus that is used to control their registers from the CPUs
>>>>>>>>> perspective. So a DSI encoder that is controlled through i2c is
>>>>>>>>> clearly
>>>>>>>>> a child of the i2c master controller and only of that one.
>>>>>>>>
>>>>>>>> I think that's a flawed interpretation of what's going on here. The
>>>>>>>> device in fact has two interfaces: one is I2C, the other is DSI.
>>>>>>>> In my
>>>>>>>> opinion that's reason enough to represent it as two logical devices.
>>>>>>>>
>>>>>>> Does it really have 2 control interfaces that are used at the same
>>>>>>> time?
>>>>>>> Or is the DSI connection a passive data bus if the register control
>>>>>>> happens through i2c?
>>>>>>
>>>>>> The interfaces may not be used at the same time, and the DSI interface
>>>>>> may even be crippled, but the device is still addressable from the DSI
>>>>>> host controller, if for nothing else than for routing the video stream.
>>>>>>
>>>>>>>>> If you need to model connections between devices that are not
>>>>>>>>> reflected
>>>>>>>>> through the control bus hierarchy you should really consider
>>>>>>>>> using the
>>>>>>>>> standardized of-graph bindings.
>>>>>>>>> (Documentation/devicetree/bindings/graph.txt)
>>>>>>>>
>>>>>>>> The problem is that the original proposal would instantiate a dummy
>>>>>>>> device, so it wouldn't be represented in DT at all. So unless you
>>>>>>>> do add
>>>>>>>> two logical devices to DT (one for each bus interface), you don't
>>>>>>>> have
>>>>>>>> anything to glue together with an OF graph.
>>>>>>>>
>>>>>>> I see that the having dummy device is the least desirable solution.
>>>>>>> But
>>>>>>> if there is only one control bus to the device I think it should be
>>>>>>> one
>>>>>>> device sitting beneath the control bus.
>>>>>>>
>>>>>>> You can then use of-graph to model the data path between the DSI
>>>>>>> encoder
>>>>>>> and device.
>>>>>>
>>>>>> But you will be needing a device below the DSI host controller to
>>>>>> represent that endpoint of the connection. The DSI host controller
>>>>>> itself is in no way connected to the I2C adapter. You would have to
>>>>>> add some sort of quirk to the DSI controller binding to allow it to
>>>>>
>>>>> Thanks for the review.
>>>>>
>>>>> I implemented this to support ADV7533 DSI to HDMI encoder chip, which
>>>>> has a DSI video bus and an i2c control bus.
>>>>>
>>>>> There weren't any quirks as such in the device tree when I tried to
>>>>> implement this. The DT seems to manage fine without a node
>>>>> corresponding to a mipi_dsi_device:
>>>>>
>>>>> i2c_adap@.. {
>>>>>      adv7533@.. {
>>>>>
>>>>>          port {
>>>>>              adv_in: endpoint {
>>>>>                  remote-endpoint = <&dsi_out>;
>>>>>              };
>>>>>          };
>>>>>      };
>>>>> };
>>>>>
>>>>> dsi_host@.. {
>>>>>      ...
>>>>>      ...
>>>>>
>>>>>      port {
>>>>>          dsi_out: endpoint {
>>>>>              remote-endpoint = <&adv_in>;
>>>>>          }
>>>>>      };
>>>>> };
>>>>>
>>>>> It's the i2c driver's job to parse the graph and retrieve the
>>>>> phandle to the dsi host. Using this, it can proceed with
>>>>> registering itself to this host using the new dsi funcs. This
>>>>> patch does the same for the adv7533 i2c driver:
>>>>>
>>>>> http://www.spinics.net/lists/dri-devel/msg86840.html
>>>>>
>>>>>> hook up with a control endpoint. And then you'll need more quirks
>>>>>> to describe what kind of DSI device this is.
>>>>>
>>>>> Could you explain what you meant by this? I.e. describing the kind
>>>>> of DSI device?
>>>>
>>>> Describing the number of lanes, specifying the virtual channel, mode
>>>> flags, etc. You could probably set the number of lanes and mode flags
>>>> via the I2C driver, but especially the virtual channel cannot be set
>>>> because it isn't known to the I2C DT branch of the device.
>>>
>>> I agree with the VC part. It could be a DT entry within the i2c client
>>> node, but that does make it seem like a quirk. The 'reg' way under the
>>> DSI host is definitely better to populate the virtual channel.
>>>
>>>>
>>>>> The dsi device created isn't really a dummy device as such. It's
>>>>> dummy in the sense that there isn't a real dsi driver associated
>>>>> with it. The dsi device is still used to attach to a mipi dsi host,
>>>>> the way normal dsi devices do.
>>>>
>>>> I understand, but I don't see why it has to be instantiated by the I2C
>>>> driver, that's what I find backwards. There is already a standard way
>>>> for instantiating DSI devices, why not use it?
>>>
>>> I assumed we could either represent the device using an i2c driver, or
>>> dsi, but not both. Hence, I came up with this approach.
>>>
>>>>
>>>>>> On the other hand if you properly instantiate the DSI device you can
>>>>>> easily write a driver for it, and the driver will set up the correct
>>>>>> properties as implied by the compatible string. Once you have that you
>>>>>> can easily hook it up to the I2C control interface in whatever way you
>>>>>> like, be that an OF graph or just a simple unidirectional link by
>>>>>> phandle.
>>>>>>
>>>>>
>>>>> With the fused approach you suggested, we would have 2 drivers: one i2c
>>>>> and the other dsi. The i2c client driver would be more or less minimal,
>>>>> preparing an i2c_client device for the dsi driver to use. Is my
>>>>> understanding correct?
>>>>
>>>> Correct. That's kind of similar to the way an HDMI encoder driver would
>>>> use an I2C adapter to query EDID. The i2c_client device would be a means
>>>> for the DSI driver to access the control interface.
>>>
>>> Okay.
>>>
>>> Although, I'm not sure about the HDMI encoder example. An HDMI
>>> encoder would read off edid directly from the adapter(with an address
>>> specified), it wouldn't need to create an i2c client device. Therefore,
>>> an HDMI encoder wouldn't need to have a separate node for i2c in DT.
>>>
>>>>
>>>>> We can do without dummy dsi devices with this method. But, representing
>>>>> a device with 2 DT nodes seems a bit off. We'd also need to compatible
>>>>> strings for the same device, one for the i2c part, and the other for
>>>>> the dsi part.
>>>>
>>>> I agree that this somewhat stretches the capabilities of device tree.
>>>> Another alternative I guess would be to not have a compatible string for
>>>> the I2C device at all (that's technically not valid, I guess) because we
>>>> really don't need an I2C driver for the device. What we really need is a
>>>> DSI driver with a means to talk over some I2C bus with some other part
>>>> of its device.
>>>
>>> I think what the driver should 'really' be is a bit subjective, and can
>>> vary based on what the buses are used for in the device. For the Toshiba
>>> chip that Jani mentioned, it tends more towards a DSI driver. Whereas,
>>> for an ADV75xx chip, it's closer to an I2C driver since only I2C can be
>>> used to configure the chip registers.
>>>
>>> Although, I agree with the point you made about the DSI bus here:
>>>
>>> "and the DSI interface may even be crippled, but the device is still
>>> addressable from the DSI host controller, if for nothing else than for
>>> routing the video stream."
>>>
>>> The fact that the data on the DSI bus contains routing information (i.e,
>>> virtual channel number) always gives it some 'control' aspect.
>>>
>>>>
>>>>>   From an adv75xx driver perspective, it should also support the ADV7511
>>>>> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
>>>>> DSI DT node. It would be a bit inconsistent to have the bindings
>>>>> require both DSI and I2C nodes for one chip, and only I2C node for the
>>>>> other, with both chips being supported by the same driver.
>>>>
>>>> Why would that be inconsistent? That sounds like the most accurate
>>>> representation of the hardware to me.
>>>
>>> Inconsistent wasn't the right term. I should have used 'uncommon' :)
>>> It's common for two chips of the same family to have a different set
>>> optional properties in DT, but it's not common for two chips of the
>>> same family to be represented by a different number of devices in
>>> DT.
>>>
>>> I don't have an issue with the fused approach you suggested, as long
>>> as people are okay with the DT parts. Especially the part of needing 2
>>> compatible strings in the DT.
>>
>> I implemented the ADV7533 driver with the approach you suggested above
>> (2 drivers for 2 different components of the chip). I posted it out
>> just a while back (with you in loop).
>>
>> The DT node with this apporach would look like this:
>>
>> https://github.com/boddob/linux/blob/c24cbf63a6998d00095c10122ce5e37b764c7dba/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi#L162
>>
>> The main irritant with the '2 driver' approach is that we need to
>> share the per-device driver data with them. For ADV7533, I've made
>> the i2c driver allocate driver data (struct adv7511).
>>
>> The dsi driver gets the driver data in the following way:
>>
>> - The i2c driver sets the driver data as its client data using
>>     i2c_set_clientdata()
>> - Parse the i2c-control phandle to get the corresponding i2c client.
>> - Extract the adv7511 struct by getting i2c_get_clientdata()
>>
>> This way of getting the same driver data is a bit strange, but it
>> works. For this, we do need to ensure that the dsi driver defers
>> as long as the i2c driver isn't probed.
>>
>> I've now implemented both approaches for the driver. The first using
>> a dummy dsi device, and this one using 2 drivers (with both being
>> represented in DT). The advantage of the latter is that we don't need
>> to create any dummy device stuff, the disadvantage is that DT is a bit
>> uncommon.
>>
>> Can we now come to a conclusion on what approach is better?
>
> DSI by design is data bus which can be used additionally as a control bus, but
> in this particular case it is purely data bus. So of-graph bindings seem to be
> better choice. As already Lucas Stach said DT hierarchy should describe control
> buses and of-graph bindings should describe data bus. Argument that hw has two
> interfaces does not seem to be valid here - it has only one control interface.
> The other one is only for data, representing every data interface using DT
> hierarchy would lead to inflation of pseudo devices.
>
> On the other side I do not see dummy device approach ideal solution, I guess
> lightweight framework providing DSI hosts detached from Linux device model could
> work better here.
> The only problem here is that it should coexist somehow with dsi bus used to
> control devices. Anyway implementing it shouldn't be hard, question is if it
> would be eventually accepted :) I guess we can live for now with dummy devs.
>
> Summarizing I would prefer version with dummy devices, as it seems more
> compatible with DT design.

Thanks for the feedback. I'll spin a newer version of the dummy dsi dev 
patches after waiting for some more comments.

Archit

> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-09-10  6:15                       ` Archit Taneja
@ 2015-09-10  7:32                         ` Thierry Reding
  2015-09-15 10:32                           ` Archit Taneja
  2015-09-15 10:41                           ` Archit Taneja
  0 siblings, 2 replies; 84+ messages in thread
From: Thierry Reding @ 2015-09-10  7:32 UTC (permalink / raw)
  To: Archit Taneja
  Cc: Andrzej Hajda, devicetree, linux-arm-msm, linux-kernel, dri-devel

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

On Thu, Sep 10, 2015 at 11:45:35AM +0530, Archit Taneja wrote:
> 
> 
> On 09/08/2015 03:57 PM, Andrzej Hajda wrote:
> >On 09/07/2015 01:46 PM, Archit Taneja wrote:
> >>Thierry,
> >>
> >>On 08/21/2015 11:39 AM, Archit Taneja wrote:
> >>>
> >>>
> >>>On 08/20/2015 05:18 PM, Thierry Reding wrote:
> >>>>On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
> >>>>>Hi Thierry, Lucas,
> >>>>>
> >>>>>
> >>>>>On 08/19/2015 08:32 PM, Thierry Reding wrote:
> >>>>>>On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
> >>>>>>>Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
> >>>>>>>>On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
> >>>>>>>>>Hi Thierry, Archit,
> >>>>>>>>>
> >>>>>>>[...]
> >>>>>>>>>>Perhaps a better way would be to invert this relationship.
> >>>>>>>>>>According to
> >>>>>>>>>>your proposal we'd have to have DT like this:
> >>>>>>>>>>
> >>>>>>>>>>     i2c@... {
> >>>>>>>>>>         ...
> >>>>>>>>>>
> >>>>>>>>>>         dsi-device@... {
> >>>>>>>>>>             ...
> >>>>>>>>>>             dsi-bus = <&dsi>;
> >>>>>>>>>>             ...
> >>>>>>>>>>         };
> >>>>>>>>>>
> >>>>>>>>>>         ...
> >>>>>>>>>>     };
> >>>>>>>>>>
> >>>>>>>>>>     dsi@... {
> >>>>>>>>>>         ...
> >>>>>>>>>>     };
> >>>>>>>>>>
> >>>>>>>>>>Inversing the relationship would become something like this:
> >>>>>>>>>>
> >>>>>>>>>>     i2c@... {
> >>>>>>>>>>         ...
> >>>>>>>>>>     };
> >>>>>>>>>>
> >>>>>>>>>>     dsi@... {
> >>>>>>>>>>         ...
> >>>>>>>>>>
> >>>>>>>>>>         peripheral@... {
> >>>>>>>>>>             ...
> >>>>>>>>>>             i2c-bus = <&i2c>;
> >>>>>>>>>>             ...
> >>>>>>>>>>         };
> >>>>>>>>>>
> >>>>>>>>>>         ...
> >>>>>>>>>>     };
> >>>>>>>>>>
> >>>>>>>>>>Both of those aren't fundamentally different, and they both have
> >>>>>>>>>>the
> >>>>>>>>>>disavantage of lacking ways to transport configuration data that
> >>>>>>>>>>the
> >>>>>>>>>>other bus needs to instantiate the dummy device (such as the reg
> >>>>>>>>>>property for example, denoting the I2C slave address or the DSI
> >>>>>>>>>>VC).
> >>>>>>>>>>
> >>>>>>>>>>So how about we create two devices in the device tree and fuse
> >>>>>>>>>>them at
> >>>>>>>>>>the driver level:
> >>>>>>>>>>
> >>>>>>>>>>     i2c@... {
> >>>>>>>>>>         ...
> >>>>>>>>>>
> >>>>>>>>>>         i2cdsi: dsi-device@... {
> >>>>>>>>>>             ...
> >>>>>>>>>>         };
> >>>>>>>>>>
> >>>>>>>>>>         ...
> >>>>>>>>>>     };
> >>>>>>>>>>
> >>>>>>>>>>     dsi@... {
> >>>>>>>>>>         ...
> >>>>>>>>>>
> >>>>>>>>>>         peripheral@... {
> >>>>>>>>>>             ...
> >>>>>>>>>>             control = <&i2cdsi>;
> >>>>>>>>>>             ...
> >>>>>>>>>>         };
> >>>>>>>>>>
> >>>>>>>>>>         ...
> >>>>>>>>>>     };
> >>>>>>>>>>
> >>>>>>>>>>This way we'll get both an I2C device and a DSI device that we
> >>>>>>>>>>can fully
> >>>>>>>>>>describe using the standard device tree bindings. At driver time
> >>>>>>>>>>we can
> >>>>>>>>>>get the I2C device from the phandle in the control property of
> >>>>>>>>>>the DSI
> >>>>>>>>>>device and use it to execute I2C transactions.
> >>>>>>>>>>
> >>>>>>>>>I don't really like to see that you are inventing yet-another-way to
> >>>>>>>>>handle devices connected to multiple buses.
> >>>>>>>>>
> >>>>>>>>>Devicetree is structured along the control buses, even if the
> >>>>>>>>>devices
> >>>>>>>>>are connected to multiple buses, in the DT they are always
> >>>>>>>>>children of
> >>>>>>>>>the bus that is used to control their registers from the CPUs
> >>>>>>>>>perspective. So a DSI encoder that is controlled through i2c is
> >>>>>>>>>clearly
> >>>>>>>>>a child of the i2c master controller and only of that one.
> >>>>>>>>
> >>>>>>>>I think that's a flawed interpretation of what's going on here. The
> >>>>>>>>device in fact has two interfaces: one is I2C, the other is DSI.
> >>>>>>>>In my
> >>>>>>>>opinion that's reason enough to represent it as two logical devices.
> >>>>>>>>
> >>>>>>>Does it really have 2 control interfaces that are used at the same
> >>>>>>>time?
> >>>>>>>Or is the DSI connection a passive data bus if the register control
> >>>>>>>happens through i2c?
> >>>>>>
> >>>>>>The interfaces may not be used at the same time, and the DSI interface
> >>>>>>may even be crippled, but the device is still addressable from the DSI
> >>>>>>host controller, if for nothing else than for routing the video stream.
> >>>>>>
> >>>>>>>>>If you need to model connections between devices that are not
> >>>>>>>>>reflected
> >>>>>>>>>through the control bus hierarchy you should really consider
> >>>>>>>>>using the
> >>>>>>>>>standardized of-graph bindings.
> >>>>>>>>>(Documentation/devicetree/bindings/graph.txt)
> >>>>>>>>
> >>>>>>>>The problem is that the original proposal would instantiate a dummy
> >>>>>>>>device, so it wouldn't be represented in DT at all. So unless you
> >>>>>>>>do add
> >>>>>>>>two logical devices to DT (one for each bus interface), you don't
> >>>>>>>>have
> >>>>>>>>anything to glue together with an OF graph.
> >>>>>>>>
> >>>>>>>I see that the having dummy device is the least desirable solution.
> >>>>>>>But
> >>>>>>>if there is only one control bus to the device I think it should be
> >>>>>>>one
> >>>>>>>device sitting beneath the control bus.
> >>>>>>>
> >>>>>>>You can then use of-graph to model the data path between the DSI
> >>>>>>>encoder
> >>>>>>>and device.
> >>>>>>
> >>>>>>But you will be needing a device below the DSI host controller to
> >>>>>>represent that endpoint of the connection. The DSI host controller
> >>>>>>itself is in no way connected to the I2C adapter. You would have to
> >>>>>>add some sort of quirk to the DSI controller binding to allow it to
> >>>>>
> >>>>>Thanks for the review.
> >>>>>
> >>>>>I implemented this to support ADV7533 DSI to HDMI encoder chip, which
> >>>>>has a DSI video bus and an i2c control bus.
> >>>>>
> >>>>>There weren't any quirks as such in the device tree when I tried to
> >>>>>implement this. The DT seems to manage fine without a node
> >>>>>corresponding to a mipi_dsi_device:
> >>>>>
> >>>>>i2c_adap@.. {
> >>>>>     adv7533@.. {
> >>>>>
> >>>>>         port {
> >>>>>             adv_in: endpoint {
> >>>>>                 remote-endpoint = <&dsi_out>;
> >>>>>             };
> >>>>>         };
> >>>>>     };
> >>>>>};
> >>>>>
> >>>>>dsi_host@.. {
> >>>>>     ...
> >>>>>     ...
> >>>>>
> >>>>>     port {
> >>>>>         dsi_out: endpoint {
> >>>>>             remote-endpoint = <&adv_in>;
> >>>>>         }
> >>>>>     };
> >>>>>};
> >>>>>
> >>>>>It's the i2c driver's job to parse the graph and retrieve the
> >>>>>phandle to the dsi host. Using this, it can proceed with
> >>>>>registering itself to this host using the new dsi funcs. This
> >>>>>patch does the same for the adv7533 i2c driver:
> >>>>>
> >>>>>http://www.spinics.net/lists/dri-devel/msg86840.html
> >>>>>
> >>>>>>hook up with a control endpoint. And then you'll need more quirks
> >>>>>>to describe what kind of DSI device this is.
> >>>>>
> >>>>>Could you explain what you meant by this? I.e. describing the kind
> >>>>>of DSI device?
> >>>>
> >>>>Describing the number of lanes, specifying the virtual channel, mode
> >>>>flags, etc. You could probably set the number of lanes and mode flags
> >>>>via the I2C driver, but especially the virtual channel cannot be set
> >>>>because it isn't known to the I2C DT branch of the device.
> >>>
> >>>I agree with the VC part. It could be a DT entry within the i2c client
> >>>node, but that does make it seem like a quirk. The 'reg' way under the
> >>>DSI host is definitely better to populate the virtual channel.
> >>>
> >>>>
> >>>>>The dsi device created isn't really a dummy device as such. It's
> >>>>>dummy in the sense that there isn't a real dsi driver associated
> >>>>>with it. The dsi device is still used to attach to a mipi dsi host,
> >>>>>the way normal dsi devices do.
> >>>>
> >>>>I understand, but I don't see why it has to be instantiated by the I2C
> >>>>driver, that's what I find backwards. There is already a standard way
> >>>>for instantiating DSI devices, why not use it?
> >>>
> >>>I assumed we could either represent the device using an i2c driver, or
> >>>dsi, but not both. Hence, I came up with this approach.
> >>>
> >>>>
> >>>>>>On the other hand if you properly instantiate the DSI device you can
> >>>>>>easily write a driver for it, and the driver will set up the correct
> >>>>>>properties as implied by the compatible string. Once you have that you
> >>>>>>can easily hook it up to the I2C control interface in whatever way you
> >>>>>>like, be that an OF graph or just a simple unidirectional link by
> >>>>>>phandle.
> >>>>>>
> >>>>>
> >>>>>With the fused approach you suggested, we would have 2 drivers: one i2c
> >>>>>and the other dsi. The i2c client driver would be more or less minimal,
> >>>>>preparing an i2c_client device for the dsi driver to use. Is my
> >>>>>understanding correct?
> >>>>
> >>>>Correct. That's kind of similar to the way an HDMI encoder driver would
> >>>>use an I2C adapter to query EDID. The i2c_client device would be a means
> >>>>for the DSI driver to access the control interface.
> >>>
> >>>Okay.
> >>>
> >>>Although, I'm not sure about the HDMI encoder example. An HDMI
> >>>encoder would read off edid directly from the adapter(with an address
> >>>specified), it wouldn't need to create an i2c client device. Therefore,
> >>>an HDMI encoder wouldn't need to have a separate node for i2c in DT.
> >>>
> >>>>
> >>>>>We can do without dummy dsi devices with this method. But, representing
> >>>>>a device with 2 DT nodes seems a bit off. We'd also need to compatible
> >>>>>strings for the same device, one for the i2c part, and the other for
> >>>>>the dsi part.
> >>>>
> >>>>I agree that this somewhat stretches the capabilities of device tree.
> >>>>Another alternative I guess would be to not have a compatible string for
> >>>>the I2C device at all (that's technically not valid, I guess) because we
> >>>>really don't need an I2C driver for the device. What we really need is a
> >>>>DSI driver with a means to talk over some I2C bus with some other part
> >>>>of its device.
> >>>
> >>>I think what the driver should 'really' be is a bit subjective, and can
> >>>vary based on what the buses are used for in the device. For the Toshiba
> >>>chip that Jani mentioned, it tends more towards a DSI driver. Whereas,
> >>>for an ADV75xx chip, it's closer to an I2C driver since only I2C can be
> >>>used to configure the chip registers.
> >>>
> >>>Although, I agree with the point you made about the DSI bus here:
> >>>
> >>>"and the DSI interface may even be crippled, but the device is still
> >>>addressable from the DSI host controller, if for nothing else than for
> >>>routing the video stream."
> >>>
> >>>The fact that the data on the DSI bus contains routing information (i.e,
> >>>virtual channel number) always gives it some 'control' aspect.
> >>>
> >>>>
> >>>>>  From an adv75xx driver perspective, it should also support the ADV7511
> >>>>>chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
> >>>>>DSI DT node. It would be a bit inconsistent to have the bindings
> >>>>>require both DSI and I2C nodes for one chip, and only I2C node for the
> >>>>>other, with both chips being supported by the same driver.
> >>>>
> >>>>Why would that be inconsistent? That sounds like the most accurate
> >>>>representation of the hardware to me.
> >>>
> >>>Inconsistent wasn't the right term. I should have used 'uncommon' :)
> >>>It's common for two chips of the same family to have a different set
> >>>optional properties in DT, but it's not common for two chips of the
> >>>same family to be represented by a different number of devices in
> >>>DT.
> >>>
> >>>I don't have an issue with the fused approach you suggested, as long
> >>>as people are okay with the DT parts. Especially the part of needing 2
> >>>compatible strings in the DT.
> >>
> >>I implemented the ADV7533 driver with the approach you suggested above
> >>(2 drivers for 2 different components of the chip). I posted it out
> >>just a while back (with you in loop).
> >>
> >>The DT node with this apporach would look like this:
> >>
> >>https://github.com/boddob/linux/blob/c24cbf63a6998d00095c10122ce5e37b764c7dba/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi#L162
> >>
> >>The main irritant with the '2 driver' approach is that we need to
> >>share the per-device driver data with them. For ADV7533, I've made
> >>the i2c driver allocate driver data (struct adv7511).
> >>
> >>The dsi driver gets the driver data in the following way:
> >>
> >>- The i2c driver sets the driver data as its client data using
> >>    i2c_set_clientdata()
> >>- Parse the i2c-control phandle to get the corresponding i2c client.
> >>- Extract the adv7511 struct by getting i2c_get_clientdata()
> >>
> >>This way of getting the same driver data is a bit strange, but it
> >>works. For this, we do need to ensure that the dsi driver defers
> >>as long as the i2c driver isn't probed.
> >>
> >>I've now implemented both approaches for the driver. The first using
> >>a dummy dsi device, and this one using 2 drivers (with both being
> >>represented in DT). The advantage of the latter is that we don't need
> >>to create any dummy device stuff, the disadvantage is that DT is a bit
> >>uncommon.
> >>
> >>Can we now come to a conclusion on what approach is better?
> >
> >DSI by design is data bus which can be used additionally as a control bus, but
> >in this particular case it is purely data bus. So of-graph bindings seem to be
> >better choice. As already Lucas Stach said DT hierarchy should describe control
> >buses and of-graph bindings should describe data bus. Argument that hw has two
> >interfaces does not seem to be valid here - it has only one control interface.
> >The other one is only for data, representing every data interface using DT
> >hierarchy would lead to inflation of pseudo devices.
> >
> >On the other side I do not see dummy device approach ideal solution, I guess
> >lightweight framework providing DSI hosts detached from Linux device model could
> >work better here.
> >The only problem here is that it should coexist somehow with dsi bus used to
> >control devices. Anyway implementing it shouldn't be hard, question is if it
> >would be eventually accepted :) I guess we can live for now with dummy devs.
> >
> >Summarizing I would prefer version with dummy devices, as it seems more
> >compatible with DT design.
> 
> Thanks for the feedback. I'll spin a newer version of the dummy dsi dev
> patches after waiting for some more comments.

Let's wait for someone from the device tree maintainers to comment
instead of going around in circles.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-09-10  7:32                         ` Thierry Reding
@ 2015-09-15 10:32                           ` Archit Taneja
  2015-09-15 15:43                             ` Rob Herring
  2015-09-15 10:41                           ` Archit Taneja
  1 sibling, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-09-15 10:32 UTC (permalink / raw)
  To: Thierry Reding, Mark Rutland, Rob Herring
  Cc: Andrzej Hajda, devicetree, linux-arm-msm, linux-kernel,
	dri-devel, Lucas Stach

Hi Rob, Mark,

We've been trying to figure out the right way to represent a class
of display encoder devices in DT.

These devices have registers that are generally configured via i2c. Once 
the device is configured, it takes in video data from the mipi
dsi bus.

Until now, all the devices we've supported devices that can be are
configured by the dsi bus itself, and hence, we've been able to
represent them in DT as children under the dsi host.

For the above class of devices (using both i2c and dsi), we aren't
able to conclude upon what's the better approach among the two:

1. Represent the device via 2 different nodes in DT. One would be
a child under an i2c adapter, the other a child of a dsi host. We
would have two device drivers, one i2c client, and the other a
mipi dsi device.

2. Represent the device as an i2c client in DT. Provide an api
to create "dummy" dsi devices. The i2c client driver would use
this api to register a dsi device, and link itself with the dsi
host.

What do you think would be the way to go here? I guess you
might have faced something similar in other subsystems.

I've given a relatively brief description of the problem. There
were some more nitty gritties discussed in this thread before.

Thierry, Andrzej, Lucas,

Please feel free to add your comments if I have missed out on
something.

Thanks,
Archit

On 09/10/2015 01:02 PM, Thierry Reding wrote:
> On Thu, Sep 10, 2015 at 11:45:35AM +0530, Archit Taneja wrote:
>>
>>
>> On 09/08/2015 03:57 PM, Andrzej Hajda wrote:
>>> On 09/07/2015 01:46 PM, Archit Taneja wrote:
>>>> Thierry,
>>>>
>>>> On 08/21/2015 11:39 AM, Archit Taneja wrote:
>>>>>
>>>>>
>>>>> On 08/20/2015 05:18 PM, Thierry Reding wrote:
>>>>>> On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
>>>>>>> Hi Thierry, Lucas,
>>>>>>>
>>>>>>>
>>>>>>> On 08/19/2015 08:32 PM, Thierry Reding wrote:
>>>>>>>> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>>>>>>>>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>>>>>>>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>>>>>>>>> Hi Thierry, Archit,
>>>>>>>>>>>
>>>>>>>>> [...]
>>>>>>>>>>>> Perhaps a better way would be to invert this relationship.
>>>>>>>>>>>> According to
>>>>>>>>>>>> your proposal we'd have to have DT like this:
>>>>>>>>>>>>
>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          dsi-device@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>              dsi-bus = <&dsi>;
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>> Inversing the relationship would become something like this:
>>>>>>>>>>>>
>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          peripheral@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>              i2c-bus = <&i2c>;
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>> Both of those aren't fundamentally different, and they both have
>>>>>>>>>>>> the
>>>>>>>>>>>> disavantage of lacking ways to transport configuration data that
>>>>>>>>>>>> the
>>>>>>>>>>>> other bus needs to instantiate the dummy device (such as the reg
>>>>>>>>>>>> property for example, denoting the I2C slave address or the DSI
>>>>>>>>>>>> VC).
>>>>>>>>>>>>
>>>>>>>>>>>> So how about we create two devices in the device tree and fuse
>>>>>>>>>>>> them at
>>>>>>>>>>>> the driver level:
>>>>>>>>>>>>
>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          i2cdsi: dsi-device@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          peripheral@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>              control = <&i2cdsi>;
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>> This way we'll get both an I2C device and a DSI device that we
>>>>>>>>>>>> can fully
>>>>>>>>>>>> describe using the standard device tree bindings. At driver time
>>>>>>>>>>>> we can
>>>>>>>>>>>> get the I2C device from the phandle in the control property of
>>>>>>>>>>>> the DSI
>>>>>>>>>>>> device and use it to execute I2C transactions.
>>>>>>>>>>>>
>>>>>>>>>>> I don't really like to see that you are inventing yet-another-way to
>>>>>>>>>>> handle devices connected to multiple buses.
>>>>>>>>>>>
>>>>>>>>>>> Devicetree is structured along the control buses, even if the
>>>>>>>>>>> devices
>>>>>>>>>>> are connected to multiple buses, in the DT they are always
>>>>>>>>>>> children of
>>>>>>>>>>> the bus that is used to control their registers from the CPUs
>>>>>>>>>>> perspective. So a DSI encoder that is controlled through i2c is
>>>>>>>>>>> clearly
>>>>>>>>>>> a child of the i2c master controller and only of that one.
>>>>>>>>>>
>>>>>>>>>> I think that's a flawed interpretation of what's going on here. The
>>>>>>>>>> device in fact has two interfaces: one is I2C, the other is DSI.
>>>>>>>>>> In my
>>>>>>>>>> opinion that's reason enough to represent it as two logical devices.
>>>>>>>>>>
>>>>>>>>> Does it really have 2 control interfaces that are used at the same
>>>>>>>>> time?
>>>>>>>>> Or is the DSI connection a passive data bus if the register control
>>>>>>>>> happens through i2c?
>>>>>>>>
>>>>>>>> The interfaces may not be used at the same time, and the DSI interface
>>>>>>>> may even be crippled, but the device is still addressable from the DSI
>>>>>>>> host controller, if for nothing else than for routing the video stream.
>>>>>>>>
>>>>>>>>>>> If you need to model connections between devices that are not
>>>>>>>>>>> reflected
>>>>>>>>>>> through the control bus hierarchy you should really consider
>>>>>>>>>>> using the
>>>>>>>>>>> standardized of-graph bindings.
>>>>>>>>>>> (Documentation/devicetree/bindings/graph.txt)
>>>>>>>>>>
>>>>>>>>>> The problem is that the original proposal would instantiate a dummy
>>>>>>>>>> device, so it wouldn't be represented in DT at all. So unless you
>>>>>>>>>> do add
>>>>>>>>>> two logical devices to DT (one for each bus interface), you don't
>>>>>>>>>> have
>>>>>>>>>> anything to glue together with an OF graph.
>>>>>>>>>>
>>>>>>>>> I see that the having dummy device is the least desirable solution.
>>>>>>>>> But
>>>>>>>>> if there is only one control bus to the device I think it should be
>>>>>>>>> one
>>>>>>>>> device sitting beneath the control bus.
>>>>>>>>>
>>>>>>>>> You can then use of-graph to model the data path between the DSI
>>>>>>>>> encoder
>>>>>>>>> and device.
>>>>>>>>
>>>>>>>> But you will be needing a device below the DSI host controller to
>>>>>>>> represent that endpoint of the connection. The DSI host controller
>>>>>>>> itself is in no way connected to the I2C adapter. You would have to
>>>>>>>> add some sort of quirk to the DSI controller binding to allow it to
>>>>>>>
>>>>>>> Thanks for the review.
>>>>>>>
>>>>>>> I implemented this to support ADV7533 DSI to HDMI encoder chip, which
>>>>>>> has a DSI video bus and an i2c control bus.
>>>>>>>
>>>>>>> There weren't any quirks as such in the device tree when I tried to
>>>>>>> implement this. The DT seems to manage fine without a node
>>>>>>> corresponding to a mipi_dsi_device:
>>>>>>>
>>>>>>> i2c_adap@.. {
>>>>>>>      adv7533@.. {
>>>>>>>
>>>>>>>          port {
>>>>>>>              adv_in: endpoint {
>>>>>>>                  remote-endpoint = <&dsi_out>;
>>>>>>>              };
>>>>>>>          };
>>>>>>>      };
>>>>>>> };
>>>>>>>
>>>>>>> dsi_host@.. {
>>>>>>>      ...
>>>>>>>      ...
>>>>>>>
>>>>>>>      port {
>>>>>>>          dsi_out: endpoint {
>>>>>>>              remote-endpoint = <&adv_in>;
>>>>>>>          }
>>>>>>>      };
>>>>>>> };
>>>>>>>
>>>>>>> It's the i2c driver's job to parse the graph and retrieve the
>>>>>>> phandle to the dsi host. Using this, it can proceed with
>>>>>>> registering itself to this host using the new dsi funcs. This
>>>>>>> patch does the same for the adv7533 i2c driver:
>>>>>>>
>>>>>>> http://www.spinics.net/lists/dri-devel/msg86840.html
>>>>>>>
>>>>>>>> hook up with a control endpoint. And then you'll need more quirks
>>>>>>>> to describe what kind of DSI device this is.
>>>>>>>
>>>>>>> Could you explain what you meant by this? I.e. describing the kind
>>>>>>> of DSI device?
>>>>>>
>>>>>> Describing the number of lanes, specifying the virtual channel, mode
>>>>>> flags, etc. You could probably set the number of lanes and mode flags
>>>>>> via the I2C driver, but especially the virtual channel cannot be set
>>>>>> because it isn't known to the I2C DT branch of the device.
>>>>>
>>>>> I agree with the VC part. It could be a DT entry within the i2c client
>>>>> node, but that does make it seem like a quirk. The 'reg' way under the
>>>>> DSI host is definitely better to populate the virtual channel.
>>>>>
>>>>>>
>>>>>>> The dsi device created isn't really a dummy device as such. It's
>>>>>>> dummy in the sense that there isn't a real dsi driver associated
>>>>>>> with it. The dsi device is still used to attach to a mipi dsi host,
>>>>>>> the way normal dsi devices do.
>>>>>>
>>>>>> I understand, but I don't see why it has to be instantiated by the I2C
>>>>>> driver, that's what I find backwards. There is already a standard way
>>>>>> for instantiating DSI devices, why not use it?
>>>>>
>>>>> I assumed we could either represent the device using an i2c driver, or
>>>>> dsi, but not both. Hence, I came up with this approach.
>>>>>
>>>>>>
>>>>>>>> On the other hand if you properly instantiate the DSI device you can
>>>>>>>> easily write a driver for it, and the driver will set up the correct
>>>>>>>> properties as implied by the compatible string. Once you have that you
>>>>>>>> can easily hook it up to the I2C control interface in whatever way you
>>>>>>>> like, be that an OF graph or just a simple unidirectional link by
>>>>>>>> phandle.
>>>>>>>>
>>>>>>>
>>>>>>> With the fused approach you suggested, we would have 2 drivers: one i2c
>>>>>>> and the other dsi. The i2c client driver would be more or less minimal,
>>>>>>> preparing an i2c_client device for the dsi driver to use. Is my
>>>>>>> understanding correct?
>>>>>>
>>>>>> Correct. That's kind of similar to the way an HDMI encoder driver would
>>>>>> use an I2C adapter to query EDID. The i2c_client device would be a means
>>>>>> for the DSI driver to access the control interface.
>>>>>
>>>>> Okay.
>>>>>
>>>>> Although, I'm not sure about the HDMI encoder example. An HDMI
>>>>> encoder would read off edid directly from the adapter(with an address
>>>>> specified), it wouldn't need to create an i2c client device. Therefore,
>>>>> an HDMI encoder wouldn't need to have a separate node for i2c in DT.
>>>>>
>>>>>>
>>>>>>> We can do without dummy dsi devices with this method. But, representing
>>>>>>> a device with 2 DT nodes seems a bit off. We'd also need to compatible
>>>>>>> strings for the same device, one for the i2c part, and the other for
>>>>>>> the dsi part.
>>>>>>
>>>>>> I agree that this somewhat stretches the capabilities of device tree.
>>>>>> Another alternative I guess would be to not have a compatible string for
>>>>>> the I2C device at all (that's technically not valid, I guess) because we
>>>>>> really don't need an I2C driver for the device. What we really need is a
>>>>>> DSI driver with a means to talk over some I2C bus with some other part
>>>>>> of its device.
>>>>>
>>>>> I think what the driver should 'really' be is a bit subjective, and can
>>>>> vary based on what the buses are used for in the device. For the Toshiba
>>>>> chip that Jani mentioned, it tends more towards a DSI driver. Whereas,
>>>>> for an ADV75xx chip, it's closer to an I2C driver since only I2C can be
>>>>> used to configure the chip registers.
>>>>>
>>>>> Although, I agree with the point you made about the DSI bus here:
>>>>>
>>>>> "and the DSI interface may even be crippled, but the device is still
>>>>> addressable from the DSI host controller, if for nothing else than for
>>>>> routing the video stream."
>>>>>
>>>>> The fact that the data on the DSI bus contains routing information (i.e,
>>>>> virtual channel number) always gives it some 'control' aspect.
>>>>>
>>>>>>
>>>>>>>   From an adv75xx driver perspective, it should also support the ADV7511
>>>>>>> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
>>>>>>> DSI DT node. It would be a bit inconsistent to have the bindings
>>>>>>> require both DSI and I2C nodes for one chip, and only I2C node for the
>>>>>>> other, with both chips being supported by the same driver.
>>>>>>
>>>>>> Why would that be inconsistent? That sounds like the most accurate
>>>>>> representation of the hardware to me.
>>>>>
>>>>> Inconsistent wasn't the right term. I should have used 'uncommon' :)
>>>>> It's common for two chips of the same family to have a different set
>>>>> optional properties in DT, but it's not common for two chips of the
>>>>> same family to be represented by a different number of devices in
>>>>> DT.
>>>>>
>>>>> I don't have an issue with the fused approach you suggested, as long
>>>>> as people are okay with the DT parts. Especially the part of needing 2
>>>>> compatible strings in the DT.
>>>>
>>>> I implemented the ADV7533 driver with the approach you suggested above
>>>> (2 drivers for 2 different components of the chip). I posted it out
>>>> just a while back (with you in loop).
>>>>
>>>> The DT node with this apporach would look like this:
>>>>
>>>> https://github.com/boddob/linux/blob/c24cbf63a6998d00095c10122ce5e37b764c7dba/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi#L162
>>>>
>>>> The main irritant with the '2 driver' approach is that we need to
>>>> share the per-device driver data with them. For ADV7533, I've made
>>>> the i2c driver allocate driver data (struct adv7511).
>>>>
>>>> The dsi driver gets the driver data in the following way:
>>>>
>>>> - The i2c driver sets the driver data as its client data using
>>>>     i2c_set_clientdata()
>>>> - Parse the i2c-control phandle to get the corresponding i2c client.
>>>> - Extract the adv7511 struct by getting i2c_get_clientdata()
>>>>
>>>> This way of getting the same driver data is a bit strange, but it
>>>> works. For this, we do need to ensure that the dsi driver defers
>>>> as long as the i2c driver isn't probed.
>>>>
>>>> I've now implemented both approaches for the driver. The first using
>>>> a dummy dsi device, and this one using 2 drivers (with both being
>>>> represented in DT). The advantage of the latter is that we don't need
>>>> to create any dummy device stuff, the disadvantage is that DT is a bit
>>>> uncommon.
>>>>
>>>> Can we now come to a conclusion on what approach is better?
>>>
>>> DSI by design is data bus which can be used additionally as a control bus, but
>>> in this particular case it is purely data bus. So of-graph bindings seem to be
>>> better choice. As already Lucas Stach said DT hierarchy should describe control
>>> buses and of-graph bindings should describe data bus. Argument that hw has two
>>> interfaces does not seem to be valid here - it has only one control interface.
>>> The other one is only for data, representing every data interface using DT
>>> hierarchy would lead to inflation of pseudo devices.
>>>
>>> On the other side I do not see dummy device approach ideal solution, I guess
>>> lightweight framework providing DSI hosts detached from Linux device model could
>>> work better here.
>>> The only problem here is that it should coexist somehow with dsi bus used to
>>> control devices. Anyway implementing it shouldn't be hard, question is if it
>>> would be eventually accepted :) I guess we can live for now with dummy devs.
>>>
>>> Summarizing I would prefer version with dummy devices, as it seems more
>>> compatible with DT design.
>>
>> Thanks for the feedback. I'll spin a newer version of the dummy dsi dev
>> patches after waiting for some more comments.
>
> Let's wait for someone from the device tree maintainers to comment
> instead of going around in circles.
>
> Thierry
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-09-10  7:32                         ` Thierry Reding
  2015-09-15 10:32                           ` Archit Taneja
@ 2015-09-15 10:41                           ` Archit Taneja
  1 sibling, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-09-15 10:41 UTC (permalink / raw)
  To: Thierry Reding, Mark Rutland, Rob Herring
  Cc: Andrzej Hajda, devicetree, linux-arm-msm, linux-kernel, dri-devel

Hi Rob, Mark,

We've been trying to figure out the right way to represent a class
of display encoder devices in DT.

These devices have registers that are generally configured via i2c. Once 
the device is configured, it takes in video data from the mipi
dsi bus.

Until now, all the devices we've supported devices that can be are
configured by the dsi bus itself, and hence, we've been able to
represent them in DT as children under the dsi host.

For the above class of devices (using both i2c and dsi), we aren't
able to conclude upon what's the better approach among the two:

1. Represent the device via 2 different nodes in DT. One would be
a child under an i2c adapter, the other a child of a dsi host. We
would have two device drivers, one i2c client, and the other a
mipi dsi device.

2. Represent the device as an i2c client in DT. Provide an api
to create "dummy" dsi devices. The i2c client driver would use
this api to register a dsi device, and link itself with the dsi
host.

What do you think would be the way to go here? I guess you
might have faced something similar in other subsystems.

I've given a relatively brief description of the problem. There
were some more nitty gritties discussed in this thread before.

Thierry, Andrzej, Lucas,

Please feel free to add your comments if I have missed out on
something.

Thanks,
Archit

On 09/10/2015 01:02 PM, Thierry Reding wrote:
> On Thu, Sep 10, 2015 at 11:45:35AM +0530, Archit Taneja wrote:
>>
>>
>> On 09/08/2015 03:57 PM, Andrzej Hajda wrote:
>>> On 09/07/2015 01:46 PM, Archit Taneja wrote:
>>>> Thierry,
>>>>
>>>> On 08/21/2015 11:39 AM, Archit Taneja wrote:
>>>>>
>>>>>
>>>>> On 08/20/2015 05:18 PM, Thierry Reding wrote:
>>>>>> On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
>>>>>>> Hi Thierry, Lucas,
>>>>>>>
>>>>>>>
>>>>>>> On 08/19/2015 08:32 PM, Thierry Reding wrote:
>>>>>>>> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>>>>>>>>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>>>>>>>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>>>>>>>>> Hi Thierry, Archit,
>>>>>>>>>>>
>>>>>>>>> [...]
>>>>>>>>>>>> Perhaps a better way would be to invert this relationship.
>>>>>>>>>>>> According to
>>>>>>>>>>>> your proposal we'd have to have DT like this:
>>>>>>>>>>>>
>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          dsi-device@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>              dsi-bus = <&dsi>;
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>> Inversing the relationship would become something like this:
>>>>>>>>>>>>
>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          peripheral@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>              i2c-bus = <&i2c>;
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>> Both of those aren't fundamentally different, and they both have
>>>>>>>>>>>> the
>>>>>>>>>>>> disavantage of lacking ways to transport configuration data that
>>>>>>>>>>>> the
>>>>>>>>>>>> other bus needs to instantiate the dummy device (such as the reg
>>>>>>>>>>>> property for example, denoting the I2C slave address or the DSI
>>>>>>>>>>>> VC).
>>>>>>>>>>>>
>>>>>>>>>>>> So how about we create two devices in the device tree and fuse
>>>>>>>>>>>> them at
>>>>>>>>>>>> the driver level:
>>>>>>>>>>>>
>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          i2cdsi: dsi-device@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>          ...
>>>>>>>>>>>>
>>>>>>>>>>>>          peripheral@... {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>              control = <&i2cdsi>;
>>>>>>>>>>>>              ...
>>>>>>>>>>>>          };
>>>>>>>>>>>>
>>>>>>>>>>>>          ...
>>>>>>>>>>>>      };
>>>>>>>>>>>>
>>>>>>>>>>>> This way we'll get both an I2C device and a DSI device that we
>>>>>>>>>>>> can fully
>>>>>>>>>>>> describe using the standard device tree bindings. At driver time
>>>>>>>>>>>> we can
>>>>>>>>>>>> get the I2C device from the phandle in the control property of
>>>>>>>>>>>> the DSI
>>>>>>>>>>>> device and use it to execute I2C transactions.
>>>>>>>>>>>>
>>>>>>>>>>> I don't really like to see that you are inventing yet-another-way to
>>>>>>>>>>> handle devices connected to multiple buses.
>>>>>>>>>>>
>>>>>>>>>>> Devicetree is structured along the control buses, even if the
>>>>>>>>>>> devices
>>>>>>>>>>> are connected to multiple buses, in the DT they are always
>>>>>>>>>>> children of
>>>>>>>>>>> the bus that is used to control their registers from the CPUs
>>>>>>>>>>> perspective. So a DSI encoder that is controlled through i2c is
>>>>>>>>>>> clearly
>>>>>>>>>>> a child of the i2c master controller and only of that one.
>>>>>>>>>>
>>>>>>>>>> I think that's a flawed interpretation of what's going on here. The
>>>>>>>>>> device in fact has two interfaces: one is I2C, the other is DSI.
>>>>>>>>>> In my
>>>>>>>>>> opinion that's reason enough to represent it as two logical devices.
>>>>>>>>>>
>>>>>>>>> Does it really have 2 control interfaces that are used at the same
>>>>>>>>> time?
>>>>>>>>> Or is the DSI connection a passive data bus if the register control
>>>>>>>>> happens through i2c?
>>>>>>>>
>>>>>>>> The interfaces may not be used at the same time, and the DSI interface
>>>>>>>> may even be crippled, but the device is still addressable from the DSI
>>>>>>>> host controller, if for nothing else than for routing the video stream.
>>>>>>>>
>>>>>>>>>>> If you need to model connections between devices that are not
>>>>>>>>>>> reflected
>>>>>>>>>>> through the control bus hierarchy you should really consider
>>>>>>>>>>> using the
>>>>>>>>>>> standardized of-graph bindings.
>>>>>>>>>>> (Documentation/devicetree/bindings/graph.txt)
>>>>>>>>>>
>>>>>>>>>> The problem is that the original proposal would instantiate a dummy
>>>>>>>>>> device, so it wouldn't be represented in DT at all. So unless you
>>>>>>>>>> do add
>>>>>>>>>> two logical devices to DT (one for each bus interface), you don't
>>>>>>>>>> have
>>>>>>>>>> anything to glue together with an OF graph.
>>>>>>>>>>
>>>>>>>>> I see that the having dummy device is the least desirable solution.
>>>>>>>>> But
>>>>>>>>> if there is only one control bus to the device I think it should be
>>>>>>>>> one
>>>>>>>>> device sitting beneath the control bus.
>>>>>>>>>
>>>>>>>>> You can then use of-graph to model the data path between the DSI
>>>>>>>>> encoder
>>>>>>>>> and device.
>>>>>>>>
>>>>>>>> But you will be needing a device below the DSI host controller to
>>>>>>>> represent that endpoint of the connection. The DSI host controller
>>>>>>>> itself is in no way connected to the I2C adapter. You would have to
>>>>>>>> add some sort of quirk to the DSI controller binding to allow it to
>>>>>>>
>>>>>>> Thanks for the review.
>>>>>>>
>>>>>>> I implemented this to support ADV7533 DSI to HDMI encoder chip, which
>>>>>>> has a DSI video bus and an i2c control bus.
>>>>>>>
>>>>>>> There weren't any quirks as such in the device tree when I tried to
>>>>>>> implement this. The DT seems to manage fine without a node
>>>>>>> corresponding to a mipi_dsi_device:
>>>>>>>
>>>>>>> i2c_adap@.. {
>>>>>>>      adv7533@.. {
>>>>>>>
>>>>>>>          port {
>>>>>>>              adv_in: endpoint {
>>>>>>>                  remote-endpoint = <&dsi_out>;
>>>>>>>              };
>>>>>>>          };
>>>>>>>      };
>>>>>>> };
>>>>>>>
>>>>>>> dsi_host@.. {
>>>>>>>      ...
>>>>>>>      ...
>>>>>>>
>>>>>>>      port {
>>>>>>>          dsi_out: endpoint {
>>>>>>>              remote-endpoint = <&adv_in>;
>>>>>>>          }
>>>>>>>      };
>>>>>>> };
>>>>>>>
>>>>>>> It's the i2c driver's job to parse the graph and retrieve the
>>>>>>> phandle to the dsi host. Using this, it can proceed with
>>>>>>> registering itself to this host using the new dsi funcs. This
>>>>>>> patch does the same for the adv7533 i2c driver:
>>>>>>>
>>>>>>> http://www.spinics.net/lists/dri-devel/msg86840.html
>>>>>>>
>>>>>>>> hook up with a control endpoint. And then you'll need more quirks
>>>>>>>> to describe what kind of DSI device this is.
>>>>>>>
>>>>>>> Could you explain what you meant by this? I.e. describing the kind
>>>>>>> of DSI device?
>>>>>>
>>>>>> Describing the number of lanes, specifying the virtual channel, mode
>>>>>> flags, etc. You could probably set the number of lanes and mode flags
>>>>>> via the I2C driver, but especially the virtual channel cannot be set
>>>>>> because it isn't known to the I2C DT branch of the device.
>>>>>
>>>>> I agree with the VC part. It could be a DT entry within the i2c client
>>>>> node, but that does make it seem like a quirk. The 'reg' way under the
>>>>> DSI host is definitely better to populate the virtual channel.
>>>>>
>>>>>>
>>>>>>> The dsi device created isn't really a dummy device as such. It's
>>>>>>> dummy in the sense that there isn't a real dsi driver associated
>>>>>>> with it. The dsi device is still used to attach to a mipi dsi host,
>>>>>>> the way normal dsi devices do.
>>>>>>
>>>>>> I understand, but I don't see why it has to be instantiated by the I2C
>>>>>> driver, that's what I find backwards. There is already a standard way
>>>>>> for instantiating DSI devices, why not use it?
>>>>>
>>>>> I assumed we could either represent the device using an i2c driver, or
>>>>> dsi, but not both. Hence, I came up with this approach.
>>>>>
>>>>>>
>>>>>>>> On the other hand if you properly instantiate the DSI device you can
>>>>>>>> easily write a driver for it, and the driver will set up the correct
>>>>>>>> properties as implied by the compatible string. Once you have that you
>>>>>>>> can easily hook it up to the I2C control interface in whatever way you
>>>>>>>> like, be that an OF graph or just a simple unidirectional link by
>>>>>>>> phandle.
>>>>>>>>
>>>>>>>
>>>>>>> With the fused approach you suggested, we would have 2 drivers: one i2c
>>>>>>> and the other dsi. The i2c client driver would be more or less minimal,
>>>>>>> preparing an i2c_client device for the dsi driver to use. Is my
>>>>>>> understanding correct?
>>>>>>
>>>>>> Correct. That's kind of similar to the way an HDMI encoder driver would
>>>>>> use an I2C adapter to query EDID. The i2c_client device would be a means
>>>>>> for the DSI driver to access the control interface.
>>>>>
>>>>> Okay.
>>>>>
>>>>> Although, I'm not sure about the HDMI encoder example. An HDMI
>>>>> encoder would read off edid directly from the adapter(with an address
>>>>> specified), it wouldn't need to create an i2c client device. Therefore,
>>>>> an HDMI encoder wouldn't need to have a separate node for i2c in DT.
>>>>>
>>>>>>
>>>>>>> We can do without dummy dsi devices with this method. But, representing
>>>>>>> a device with 2 DT nodes seems a bit off. We'd also need to compatible
>>>>>>> strings for the same device, one for the i2c part, and the other for
>>>>>>> the dsi part.
>>>>>>
>>>>>> I agree that this somewhat stretches the capabilities of device tree.
>>>>>> Another alternative I guess would be to not have a compatible string for
>>>>>> the I2C device at all (that's technically not valid, I guess) because we
>>>>>> really don't need an I2C driver for the device. What we really need is a
>>>>>> DSI driver with a means to talk over some I2C bus with some other part
>>>>>> of its device.
>>>>>
>>>>> I think what the driver should 'really' be is a bit subjective, and can
>>>>> vary based on what the buses are used for in the device. For the Toshiba
>>>>> chip that Jani mentioned, it tends more towards a DSI driver. Whereas,
>>>>> for an ADV75xx chip, it's closer to an I2C driver since only I2C can be
>>>>> used to configure the chip registers.
>>>>>
>>>>> Although, I agree with the point you made about the DSI bus here:
>>>>>
>>>>> "and the DSI interface may even be crippled, but the device is still
>>>>> addressable from the DSI host controller, if for nothing else than for
>>>>> routing the video stream."
>>>>>
>>>>> The fact that the data on the DSI bus contains routing information (i.e,
>>>>> virtual channel number) always gives it some 'control' aspect.
>>>>>
>>>>>>
>>>>>>>   From an adv75xx driver perspective, it should also support the ADV7511
>>>>>>> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't need a
>>>>>>> DSI DT node. It would be a bit inconsistent to have the bindings
>>>>>>> require both DSI and I2C nodes for one chip, and only I2C node for the
>>>>>>> other, with both chips being supported by the same driver.
>>>>>>
>>>>>> Why would that be inconsistent? That sounds like the most accurate
>>>>>> representation of the hardware to me.
>>>>>
>>>>> Inconsistent wasn't the right term. I should have used 'uncommon' :)
>>>>> It's common for two chips of the same family to have a different set
>>>>> optional properties in DT, but it's not common for two chips of the
>>>>> same family to be represented by a different number of devices in
>>>>> DT.
>>>>>
>>>>> I don't have an issue with the fused approach you suggested, as long
>>>>> as people are okay with the DT parts. Especially the part of needing 2
>>>>> compatible strings in the DT.
>>>>
>>>> I implemented the ADV7533 driver with the approach you suggested above
>>>> (2 drivers for 2 different components of the chip). I posted it out
>>>> just a while back (with you in loop).
>>>>
>>>> The DT node with this apporach would look like this:
>>>>
>>>> https://github.com/boddob/linux/blob/c24cbf63a6998d00095c10122ce5e37b764c7dba/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi#L162
>>>>
>>>> The main irritant with the '2 driver' approach is that we need to
>>>> share the per-device driver data with them. For ADV7533, I've made
>>>> the i2c driver allocate driver data (struct adv7511).
>>>>
>>>> The dsi driver gets the driver data in the following way:
>>>>
>>>> - The i2c driver sets the driver data as its client data using
>>>>     i2c_set_clientdata()
>>>> - Parse the i2c-control phandle to get the corresponding i2c client.
>>>> - Extract the adv7511 struct by getting i2c_get_clientdata()
>>>>
>>>> This way of getting the same driver data is a bit strange, but it
>>>> works. For this, we do need to ensure that the dsi driver defers
>>>> as long as the i2c driver isn't probed.
>>>>
>>>> I've now implemented both approaches for the driver. The first using
>>>> a dummy dsi device, and this one using 2 drivers (with both being
>>>> represented in DT). The advantage of the latter is that we don't need
>>>> to create any dummy device stuff, the disadvantage is that DT is a bit
>>>> uncommon.
>>>>
>>>> Can we now come to a conclusion on what approach is better?
>>>
>>> DSI by design is data bus which can be used additionally as a control bus, but
>>> in this particular case it is purely data bus. So of-graph bindings seem to be
>>> better choice. As already Lucas Stach said DT hierarchy should describe control
>>> buses and of-graph bindings should describe data bus. Argument that hw has two
>>> interfaces does not seem to be valid here - it has only one control interface.
>>> The other one is only for data, representing every data interface using DT
>>> hierarchy would lead to inflation of pseudo devices.
>>>
>>> On the other side I do not see dummy device approach ideal solution, I guess
>>> lightweight framework providing DSI hosts detached from Linux device model could
>>> work better here.
>>> The only problem here is that it should coexist somehow with dsi bus used to
>>> control devices. Anyway implementing it shouldn't be hard, question is if it
>>> would be eventually accepted :) I guess we can live for now with dummy devs.
>>>
>>> Summarizing I would prefer version with dummy devices, as it seems more
>>> compatible with DT design.
>>
>> Thanks for the feedback. I'll spin a newer version of the dummy dsi dev
>> patches after waiting for some more comments.
>
> Let's wait for someone from the device tree maintainers to comment
> instead of going around in circles.
>
> Thierry
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-09-15 10:32                           ` Archit Taneja
@ 2015-09-15 15:43                             ` Rob Herring
  2015-09-17  8:56                               ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Rob Herring @ 2015-09-15 15:43 UTC (permalink / raw)
  To: Archit Taneja, Thierry Reding, Mark Rutland, Rob Herring
  Cc: Andrzej Hajda, devicetree, linux-arm-msm, linux-kernel,
	dri-devel, Lucas Stach

On 09/15/2015 05:32 AM, Archit Taneja wrote:
> Hi Rob, Mark,
> 
> We've been trying to figure out the right way to represent a class
> of display encoder devices in DT.

I've been meaning to reply on this.

> These devices have registers that are generally configured via i2c. Once
> the device is configured, it takes in video data from the mipi
> dsi bus.
> 
> Until now, all the devices we've supported devices that can be are
> configured by the dsi bus itself, and hence, we've been able to
> represent them in DT as children under the dsi host.
> 
> For the above class of devices (using both i2c and dsi), we aren't
> able to conclude upon what's the better approach among the two:
> 
> 1. Represent the device via 2 different nodes in DT. One would be
> a child under an i2c adapter, the other a child of a dsi host. We
> would have two device drivers, one i2c client, and the other a
> mipi dsi device.
> 
> 2. Represent the device as an i2c client in DT. Provide an api
> to create "dummy" dsi devices. The i2c client driver would use
> this api to register a dsi device, and link itself with the dsi
> host.
> 
> What do you think would be the way to go here? I guess you
> might have faced something similar in other subsystems.

The closest thing I can think of are WiFi/BT combo chips that use
SDIO+UART. In that case, 2 nodes makes sense as these chips are
essentially 2 independent functions in a single chip and both interfaces
are control interfaces (as well as data). This case is a bit different
with both interfaces being tied to the same function.

So in this case, I think option 2 is the right way for the reasons
already outlined in this thread. I think there needs to be more
consistency in how the of-graph connections are defined with the core
doing more of the graph traversing. So having an i2c device plus
of-graph seems more consistent with other non-DSI cases.

The main open issue seemed to be setting the VC. At least for the
ADV7533, it can be whatever you want it to be. The host and device just
need to agree. I see no need for that to be in DT at least in this case.
But then I'm not sure what are typical constraints for VC assignment.
I'd guess that constraints are on the device side and hosts can support
whatever the device wants. If so, then it can purely be up to the driver
to set.

Implementation-wise, I don't think that I'd call this a dummy device.
There are multiple ways for devices to get created in the driver model.
DT is just one way. You are just creating the device in a different way
outside of DT which is fine.

Rob

> I've given a relatively brief description of the problem. There
> were some more nitty gritties discussed in this thread before.
> 
> Thierry, Andrzej, Lucas,
> 
> Please feel free to add your comments if I have missed out on
> something.
> 
> Thanks,
> Archit
> 
> On 09/10/2015 01:02 PM, Thierry Reding wrote:
>> On Thu, Sep 10, 2015 at 11:45:35AM +0530, Archit Taneja wrote:
>>>
>>>
>>> On 09/08/2015 03:57 PM, Andrzej Hajda wrote:
>>>> On 09/07/2015 01:46 PM, Archit Taneja wrote:
>>>>> Thierry,
>>>>>
>>>>> On 08/21/2015 11:39 AM, Archit Taneja wrote:
>>>>>>
>>>>>>
>>>>>> On 08/20/2015 05:18 PM, Thierry Reding wrote:
>>>>>>> On Thu, Aug 20, 2015 at 09:46:14AM +0530, Archit Taneja wrote:
>>>>>>>> Hi Thierry, Lucas,
>>>>>>>>
>>>>>>>>
>>>>>>>> On 08/19/2015 08:32 PM, Thierry Reding wrote:
>>>>>>>>> On Wed, Aug 19, 2015 at 04:52:24PM +0200, Lucas Stach wrote:
>>>>>>>>>> Am Mittwoch, den 19.08.2015, 16:34 +0200 schrieb Thierry Reding:
>>>>>>>>>>> On Wed, Aug 19, 2015 at 04:17:08PM +0200, Lucas Stach wrote:
>>>>>>>>>>>> Hi Thierry, Archit,
>>>>>>>>>>>>
>>>>>>>>>> [...]
>>>>>>>>>>>>> Perhaps a better way would be to invert this relationship.
>>>>>>>>>>>>> According to
>>>>>>>>>>>>> your proposal we'd have to have DT like this:
>>>>>>>>>>>>>
>>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>
>>>>>>>>>>>>>          dsi-device@... {
>>>>>>>>>>>>>              ...
>>>>>>>>>>>>>              dsi-bus = <&dsi>;
>>>>>>>>>>>>>              ...
>>>>>>>>>>>>>          };
>>>>>>>>>>>>>
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>      };
>>>>>>>>>>>>>
>>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>      };
>>>>>>>>>>>>>
>>>>>>>>>>>>> Inversing the relationship would become something like this:
>>>>>>>>>>>>>
>>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>      };
>>>>>>>>>>>>>
>>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>
>>>>>>>>>>>>>          peripheral@... {
>>>>>>>>>>>>>              ...
>>>>>>>>>>>>>              i2c-bus = <&i2c>;
>>>>>>>>>>>>>              ...
>>>>>>>>>>>>>          };
>>>>>>>>>>>>>
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>      };
>>>>>>>>>>>>>
>>>>>>>>>>>>> Both of those aren't fundamentally different, and they both
>>>>>>>>>>>>> have
>>>>>>>>>>>>> the
>>>>>>>>>>>>> disavantage of lacking ways to transport configuration data
>>>>>>>>>>>>> that
>>>>>>>>>>>>> the
>>>>>>>>>>>>> other bus needs to instantiate the dummy device (such as
>>>>>>>>>>>>> the reg
>>>>>>>>>>>>> property for example, denoting the I2C slave address or the
>>>>>>>>>>>>> DSI
>>>>>>>>>>>>> VC).
>>>>>>>>>>>>>
>>>>>>>>>>>>> So how about we create two devices in the device tree and fuse
>>>>>>>>>>>>> them at
>>>>>>>>>>>>> the driver level:
>>>>>>>>>>>>>
>>>>>>>>>>>>>      i2c@... {
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>
>>>>>>>>>>>>>          i2cdsi: dsi-device@... {
>>>>>>>>>>>>>              ...
>>>>>>>>>>>>>          };
>>>>>>>>>>>>>
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>      };
>>>>>>>>>>>>>
>>>>>>>>>>>>>      dsi@... {
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>
>>>>>>>>>>>>>          peripheral@... {
>>>>>>>>>>>>>              ...
>>>>>>>>>>>>>              control = <&i2cdsi>;
>>>>>>>>>>>>>              ...
>>>>>>>>>>>>>          };
>>>>>>>>>>>>>
>>>>>>>>>>>>>          ...
>>>>>>>>>>>>>      };
>>>>>>>>>>>>>
>>>>>>>>>>>>> This way we'll get both an I2C device and a DSI device that we
>>>>>>>>>>>>> can fully
>>>>>>>>>>>>> describe using the standard device tree bindings. At driver
>>>>>>>>>>>>> time
>>>>>>>>>>>>> we can
>>>>>>>>>>>>> get the I2C device from the phandle in the control property of
>>>>>>>>>>>>> the DSI
>>>>>>>>>>>>> device and use it to execute I2C transactions.
>>>>>>>>>>>>>
>>>>>>>>>>>> I don't really like to see that you are inventing
>>>>>>>>>>>> yet-another-way to
>>>>>>>>>>>> handle devices connected to multiple buses.
>>>>>>>>>>>>
>>>>>>>>>>>> Devicetree is structured along the control buses, even if the
>>>>>>>>>>>> devices
>>>>>>>>>>>> are connected to multiple buses, in the DT they are always
>>>>>>>>>>>> children of
>>>>>>>>>>>> the bus that is used to control their registers from the CPUs
>>>>>>>>>>>> perspective. So a DSI encoder that is controlled through i2c is
>>>>>>>>>>>> clearly
>>>>>>>>>>>> a child of the i2c master controller and only of that one.
>>>>>>>>>>>
>>>>>>>>>>> I think that's a flawed interpretation of what's going on
>>>>>>>>>>> here. The
>>>>>>>>>>> device in fact has two interfaces: one is I2C, the other is DSI.
>>>>>>>>>>> In my
>>>>>>>>>>> opinion that's reason enough to represent it as two logical
>>>>>>>>>>> devices.
>>>>>>>>>>>
>>>>>>>>>> Does it really have 2 control interfaces that are used at the
>>>>>>>>>> same
>>>>>>>>>> time?
>>>>>>>>>> Or is the DSI connection a passive data bus if the register
>>>>>>>>>> control
>>>>>>>>>> happens through i2c?
>>>>>>>>>
>>>>>>>>> The interfaces may not be used at the same time, and the DSI
>>>>>>>>> interface
>>>>>>>>> may even be crippled, but the device is still addressable from
>>>>>>>>> the DSI
>>>>>>>>> host controller, if for nothing else than for routing the video
>>>>>>>>> stream.
>>>>>>>>>
>>>>>>>>>>>> If you need to model connections between devices that are not
>>>>>>>>>>>> reflected
>>>>>>>>>>>> through the control bus hierarchy you should really consider
>>>>>>>>>>>> using the
>>>>>>>>>>>> standardized of-graph bindings.
>>>>>>>>>>>> (Documentation/devicetree/bindings/graph.txt)
>>>>>>>>>>>
>>>>>>>>>>> The problem is that the original proposal would instantiate a
>>>>>>>>>>> dummy
>>>>>>>>>>> device, so it wouldn't be represented in DT at all. So unless
>>>>>>>>>>> you
>>>>>>>>>>> do add
>>>>>>>>>>> two logical devices to DT (one for each bus interface), you
>>>>>>>>>>> don't
>>>>>>>>>>> have
>>>>>>>>>>> anything to glue together with an OF graph.
>>>>>>>>>>>
>>>>>>>>>> I see that the having dummy device is the least desirable
>>>>>>>>>> solution.
>>>>>>>>>> But
>>>>>>>>>> if there is only one control bus to the device I think it
>>>>>>>>>> should be
>>>>>>>>>> one
>>>>>>>>>> device sitting beneath the control bus.
>>>>>>>>>>
>>>>>>>>>> You can then use of-graph to model the data path between the DSI
>>>>>>>>>> encoder
>>>>>>>>>> and device.
>>>>>>>>>
>>>>>>>>> But you will be needing a device below the DSI host controller to
>>>>>>>>> represent that endpoint of the connection. The DSI host controller
>>>>>>>>> itself is in no way connected to the I2C adapter. You would
>>>>>>>>> have to
>>>>>>>>> add some sort of quirk to the DSI controller binding to allow
>>>>>>>>> it to
>>>>>>>>
>>>>>>>> Thanks for the review.
>>>>>>>>
>>>>>>>> I implemented this to support ADV7533 DSI to HDMI encoder chip,
>>>>>>>> which
>>>>>>>> has a DSI video bus and an i2c control bus.
>>>>>>>>
>>>>>>>> There weren't any quirks as such in the device tree when I tried to
>>>>>>>> implement this. The DT seems to manage fine without a node
>>>>>>>> corresponding to a mipi_dsi_device:
>>>>>>>>
>>>>>>>> i2c_adap@.. {
>>>>>>>>      adv7533@.. {
>>>>>>>>
>>>>>>>>          port {
>>>>>>>>              adv_in: endpoint {
>>>>>>>>                  remote-endpoint = <&dsi_out>;
>>>>>>>>              };
>>>>>>>>          };
>>>>>>>>      };
>>>>>>>> };
>>>>>>>>
>>>>>>>> dsi_host@.. {
>>>>>>>>      ...
>>>>>>>>      ...
>>>>>>>>
>>>>>>>>      port {
>>>>>>>>          dsi_out: endpoint {
>>>>>>>>              remote-endpoint = <&adv_in>;
>>>>>>>>          }
>>>>>>>>      };
>>>>>>>> };
>>>>>>>>
>>>>>>>> It's the i2c driver's job to parse the graph and retrieve the
>>>>>>>> phandle to the dsi host. Using this, it can proceed with
>>>>>>>> registering itself to this host using the new dsi funcs. This
>>>>>>>> patch does the same for the adv7533 i2c driver:
>>>>>>>>
>>>>>>>> http://www.spinics.net/lists/dri-devel/msg86840.html
>>>>>>>>
>>>>>>>>> hook up with a control endpoint. And then you'll need more quirks
>>>>>>>>> to describe what kind of DSI device this is.
>>>>>>>>
>>>>>>>> Could you explain what you meant by this? I.e. describing the kind
>>>>>>>> of DSI device?
>>>>>>>
>>>>>>> Describing the number of lanes, specifying the virtual channel, mode
>>>>>>> flags, etc. You could probably set the number of lanes and mode
>>>>>>> flags
>>>>>>> via the I2C driver, but especially the virtual channel cannot be set
>>>>>>> because it isn't known to the I2C DT branch of the device.
>>>>>>
>>>>>> I agree with the VC part. It could be a DT entry within the i2c
>>>>>> client
>>>>>> node, but that does make it seem like a quirk. The 'reg' way under
>>>>>> the
>>>>>> DSI host is definitely better to populate the virtual channel.
>>>>>>
>>>>>>>
>>>>>>>> The dsi device created isn't really a dummy device as such. It's
>>>>>>>> dummy in the sense that there isn't a real dsi driver associated
>>>>>>>> with it. The dsi device is still used to attach to a mipi dsi host,
>>>>>>>> the way normal dsi devices do.
>>>>>>>
>>>>>>> I understand, but I don't see why it has to be instantiated by
>>>>>>> the I2C
>>>>>>> driver, that's what I find backwards. There is already a standard
>>>>>>> way
>>>>>>> for instantiating DSI devices, why not use it?
>>>>>>
>>>>>> I assumed we could either represent the device using an i2c
>>>>>> driver, or
>>>>>> dsi, but not both. Hence, I came up with this approach.
>>>>>>
>>>>>>>
>>>>>>>>> On the other hand if you properly instantiate the DSI device
>>>>>>>>> you can
>>>>>>>>> easily write a driver for it, and the driver will set up the
>>>>>>>>> correct
>>>>>>>>> properties as implied by the compatible string. Once you have
>>>>>>>>> that you
>>>>>>>>> can easily hook it up to the I2C control interface in whatever
>>>>>>>>> way you
>>>>>>>>> like, be that an OF graph or just a simple unidirectional link by
>>>>>>>>> phandle.
>>>>>>>>>
>>>>>>>>
>>>>>>>> With the fused approach you suggested, we would have 2 drivers:
>>>>>>>> one i2c
>>>>>>>> and the other dsi. The i2c client driver would be more or less
>>>>>>>> minimal,
>>>>>>>> preparing an i2c_client device for the dsi driver to use. Is my
>>>>>>>> understanding correct?
>>>>>>>
>>>>>>> Correct. That's kind of similar to the way an HDMI encoder driver
>>>>>>> would
>>>>>>> use an I2C adapter to query EDID. The i2c_client device would be
>>>>>>> a means
>>>>>>> for the DSI driver to access the control interface.
>>>>>>
>>>>>> Okay.
>>>>>>
>>>>>> Although, I'm not sure about the HDMI encoder example. An HDMI
>>>>>> encoder would read off edid directly from the adapter(with an address
>>>>>> specified), it wouldn't need to create an i2c client device.
>>>>>> Therefore,
>>>>>> an HDMI encoder wouldn't need to have a separate node for i2c in DT.
>>>>>>
>>>>>>>
>>>>>>>> We can do without dummy dsi devices with this method. But,
>>>>>>>> representing
>>>>>>>> a device with 2 DT nodes seems a bit off. We'd also need to
>>>>>>>> compatible
>>>>>>>> strings for the same device, one for the i2c part, and the other
>>>>>>>> for
>>>>>>>> the dsi part.
>>>>>>>
>>>>>>> I agree that this somewhat stretches the capabilities of device
>>>>>>> tree.
>>>>>>> Another alternative I guess would be to not have a compatible
>>>>>>> string for
>>>>>>> the I2C device at all (that's technically not valid, I guess)
>>>>>>> because we
>>>>>>> really don't need an I2C driver for the device. What we really
>>>>>>> need is a
>>>>>>> DSI driver with a means to talk over some I2C bus with some other
>>>>>>> part
>>>>>>> of its device.
>>>>>>
>>>>>> I think what the driver should 'really' be is a bit subjective,
>>>>>> and can
>>>>>> vary based on what the buses are used for in the device. For the
>>>>>> Toshiba
>>>>>> chip that Jani mentioned, it tends more towards a DSI driver.
>>>>>> Whereas,
>>>>>> for an ADV75xx chip, it's closer to an I2C driver since only I2C
>>>>>> can be
>>>>>> used to configure the chip registers.
>>>>>>
>>>>>> Although, I agree with the point you made about the DSI bus here:
>>>>>>
>>>>>> "and the DSI interface may even be crippled, but the device is still
>>>>>> addressable from the DSI host controller, if for nothing else than
>>>>>> for
>>>>>> routing the video stream."
>>>>>>
>>>>>> The fact that the data on the DSI bus contains routing information
>>>>>> (i.e,
>>>>>> virtual channel number) always gives it some 'control' aspect.
>>>>>>
>>>>>>>
>>>>>>>>   From an adv75xx driver perspective, it should also support the
>>>>>>>> ADV7511
>>>>>>>> chip, which is a RGB/DPI to HDMI encoder. For adv7511, we don't
>>>>>>>> need a
>>>>>>>> DSI DT node. It would be a bit inconsistent to have the bindings
>>>>>>>> require both DSI and I2C nodes for one chip, and only I2C node
>>>>>>>> for the
>>>>>>>> other, with both chips being supported by the same driver.
>>>>>>>
>>>>>>> Why would that be inconsistent? That sounds like the most accurate
>>>>>>> representation of the hardware to me.
>>>>>>
>>>>>> Inconsistent wasn't the right term. I should have used 'uncommon' :)
>>>>>> It's common for two chips of the same family to have a different set
>>>>>> optional properties in DT, but it's not common for two chips of the
>>>>>> same family to be represented by a different number of devices in
>>>>>> DT.
>>>>>>
>>>>>> I don't have an issue with the fused approach you suggested, as long
>>>>>> as people are okay with the DT parts. Especially the part of
>>>>>> needing 2
>>>>>> compatible strings in the DT.
>>>>>
>>>>> I implemented the ADV7533 driver with the approach you suggested above
>>>>> (2 drivers for 2 different components of the chip). I posted it out
>>>>> just a while back (with you in loop).
>>>>>
>>>>> The DT node with this apporach would look like this:
>>>>>
>>>>> https://github.com/boddob/linux/blob/c24cbf63a6998d00095c10122ce5e37b764c7dba/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi#L162
>>>>>
>>>>>
>>>>> The main irritant with the '2 driver' approach is that we need to
>>>>> share the per-device driver data with them. For ADV7533, I've made
>>>>> the i2c driver allocate driver data (struct adv7511).
>>>>>
>>>>> The dsi driver gets the driver data in the following way:
>>>>>
>>>>> - The i2c driver sets the driver data as its client data using
>>>>>     i2c_set_clientdata()
>>>>> - Parse the i2c-control phandle to get the corresponding i2c client.
>>>>> - Extract the adv7511 struct by getting i2c_get_clientdata()
>>>>>
>>>>> This way of getting the same driver data is a bit strange, but it
>>>>> works. For this, we do need to ensure that the dsi driver defers
>>>>> as long as the i2c driver isn't probed.
>>>>>
>>>>> I've now implemented both approaches for the driver. The first using
>>>>> a dummy dsi device, and this one using 2 drivers (with both being
>>>>> represented in DT). The advantage of the latter is that we don't need
>>>>> to create any dummy device stuff, the disadvantage is that DT is a bit
>>>>> uncommon.
>>>>>
>>>>> Can we now come to a conclusion on what approach is better?
>>>>
>>>> DSI by design is data bus which can be used additionally as a
>>>> control bus, but
>>>> in this particular case it is purely data bus. So of-graph bindings
>>>> seem to be
>>>> better choice. As already Lucas Stach said DT hierarchy should
>>>> describe control
>>>> buses and of-graph bindings should describe data bus. Argument that
>>>> hw has two
>>>> interfaces does not seem to be valid here - it has only one control
>>>> interface.
>>>> The other one is only for data, representing every data interface
>>>> using DT
>>>> hierarchy would lead to inflation of pseudo devices.
>>>>
>>>> On the other side I do not see dummy device approach ideal solution,
>>>> I guess
>>>> lightweight framework providing DSI hosts detached from Linux device
>>>> model could
>>>> work better here.
>>>> The only problem here is that it should coexist somehow with dsi bus
>>>> used to
>>>> control devices. Anyway implementing it shouldn't be hard, question
>>>> is if it
>>>> would be eventually accepted :) I guess we can live for now with
>>>> dummy devs.
>>>>
>>>> Summarizing I would prefer version with dummy devices, as it seems more
>>>> compatible with DT design.
>>>
>>> Thanks for the feedback. I'll spin a newer version of the dummy dsi dev
>>> patches after waiting for some more comments.
>>
>> Let's wait for someone from the device tree maintainers to comment
>> instead of going around in circles.
>>
>> Thierry
>>
> 


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

* Re: [RFC 0/2] drm/dsi: DSI for devices with different control bus
  2015-09-15 15:43                             ` Rob Herring
@ 2015-09-17  8:56                               ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-09-17  8:56 UTC (permalink / raw)
  To: Rob Herring, Thierry Reding, Mark Rutland, Rob Herring
  Cc: Andrzej Hajda, devicetree, linux-arm-msm, linux-kernel,
	dri-devel, Lucas Stach



On 9/15/2015 9:13 PM, Rob Herring wrote:
> On 09/15/2015 05:32 AM, Archit Taneja wrote:
>> Hi Rob, Mark,
>>
>> We've been trying to figure out the right way to represent a class
>> of display encoder devices in DT.
>
> I've been meaning to reply on this.
>
>> These devices have registers that are generally configured via i2c. Once
>> the device is configured, it takes in video data from the mipi
>> dsi bus.
>>
>> Until now, all the devices we've supported devices that can be are
>> configured by the dsi bus itself, and hence, we've been able to
>> represent them in DT as children under the dsi host.
>>
>> For the above class of devices (using both i2c and dsi), we aren't
>> able to conclude upon what's the better approach among the two:
>>
>> 1. Represent the device via 2 different nodes in DT. One would be
>> a child under an i2c adapter, the other a child of a dsi host. We
>> would have two device drivers, one i2c client, and the other a
>> mipi dsi device.
>>
>> 2. Represent the device as an i2c client in DT. Provide an api
>> to create "dummy" dsi devices. The i2c client driver would use
>> this api to register a dsi device, and link itself with the dsi
>> host.
>>
>> What do you think would be the way to go here? I guess you
>> might have faced something similar in other subsystems.
>
> The closest thing I can think of are WiFi/BT combo chips that use
> SDIO+UART. In that case, 2 nodes makes sense as these chips are
> essentially 2 independent functions in a single chip and both interfaces
> are control interfaces (as well as data). This case is a bit different
> with both interfaces being tied to the same function.
>
> So in this case, I think option 2 is the right way for the reasons
> already outlined in this thread. I think there needs to be more
> consistency in how the of-graph connections are defined with the core
> doing more of the graph traversing. So having an i2c device plus
> of-graph seems more consistent with other non-DSI cases.
>
> The main open issue seemed to be setting the VC. At least for the
> ADV7533, it can be whatever you want it to be. The host and device just
> need to agree. I see no need for that to be in DT at least in this case.
> But then I'm not sure what are typical constraints for VC assignment.
> I'd guess that constraints are on the device side and hosts can support
> whatever the device wants. If so, then it can purely be up to the driver
> to set.

2 DSI devices connected to the same host shouldn't have the same VC.
When representing the DSI nodes via DT, we use the 'reg' property to
assign the VC.

Although, in practice, we don't generally have multiple devices
on the same bus. The trend is to have multiple DSI hosts on the
platform to support more devices.

If we have checks that ensures the DT way and the new manual way
of creation of DSI devices doesn't result in having conflicting VCs
for devices, we should be okay.

>
> Implementation-wise, I don't think that I'd call this a dummy device.
> There are multiple ways for devices to get created in the driver model.
> DT is just one way. You are just creating the device in a different way
> outside of DT which is fine.
>

Thanks for the feedback.

Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* [RFC v2 0/5] drm/dsi: DSI for devices with different control bus
  2015-06-30  5:24 [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
                   ` (2 preceding siblings ...)
  2015-08-19  5:07 ` [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
@ 2015-10-06  9:24 ` Archit Taneja
  2015-10-06  9:24   ` [RFC v2 1/5] drm/dsi: Refactor device creation Archit Taneja
                     ` (5 more replies)
  3 siblings, 6 replies; 84+ messages in thread
From: Archit Taneja @ 2015-10-06  9:24 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

We are currently restricted when it comes to supporting DSI on devices
that have a non-DSI control bus. For example, DSI encoder chips are
available in the market that are configured via i2c. Configuring their
registers via DSI bus is either optional or not available at all.

These devices still need to pass DSI parameters (data lanes, mode flags
etc) to the DSI host they are connected to. We don't have a way to do
that at the moment.

After some discussions on the previous RFC[1], we decided to support this
by providing additional API in drm_mipi_dsi which lets us create new DSI
devices without the need of them to have a DT node.

There are a couple of concerns I have about this patchset which I
couldn't figure out a solution to (they are addressed in the individual
patches too):

- Matching of non-DT devices: buses like i2c/spi populate id_table in
  their drivers to perform a match for the non-DT case. Is this something
  that we should do too?

- Race between host_unregister and device_unregister: The new API provides
  peripheral drivers to unregister the DSI devices they created by using
  mipi_dsi_device_unregister. If the dsi host unregisters first, the
  peripheral driver might have an unregistered device pointer without
  being aware of it.

Some comments on these would help.

[1]: https://lkml.org/lkml/2015/6/30/42

Archit Taneja (5):
  drm/dsi: Refactor device creation
  drm/dsi: Try to match non-DT dsi devices
  drm/dsi: Check for used channels
  drm/dsi: Add routine to unregister dsi device
  drm/dsi: Get DSI host by DT device node

 drivers/gpu/drm/drm_mipi_dsi.c | 135 ++++++++++++++++++++++++++++++++---------
 include/drm/drm_mipi_dsi.h     |  27 +++++++++
 2 files changed, 132 insertions(+), 30 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [RFC v2 1/5] drm/dsi: Refactor device creation
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
@ 2015-10-06  9:24   ` Archit Taneja
  2015-10-30 11:28     ` Andrzej Hajda
  2015-10-06  9:24   ` [RFC v2 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-10-06  9:24 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

Simplify the mipi dsi device creation process. device_initialize and
device_add don't need to be called separately when creating
mipi_dsi_device's. Use device_register instead to simplify things.

Create a helper function mipi_dsi_device_new which takes in struct
mipi_dsi_device_info and mipi_dsi_host. It clubs the functions
mipi_dsi_device_alloc and mipi_dsi_device_add into one.

mipi_dsi_device_info acts as a template to populate the dsi device
information. This is populated by of_mipi_dsi_device_add and passed to
mipi_dsi_device_new.

Later on, we'll provide mipi_dsi_device_new as a standalone way to create
a dsi device not available via DT.

The new device creation process tries to closely follow what's been done
in i2c_new_device in i2c-core.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 61 +++++++++++++++++-------------------------
 include/drm/drm_mipi_dsi.h     | 15 +++++++++++
 2 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 2d5ca8ee..245ecfe 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -102,9 +102,18 @@ static const struct device_type mipi_dsi_device_type = {
 	.release = mipi_dsi_dev_release,
 };
 
-static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
+struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
+					    struct mipi_dsi_device_info *info)
 {
 	struct mipi_dsi_device *dsi;
+	struct device *dev = host->dev;
+	int r;
+
+	if (info->reg > 3) {
+		dev_err(dev, "device node has invalid reg property: %u\n",
+			info->reg);
+		return ERR_PTR(-EINVAL);
+	}
 
 	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
 	if (!dsi)
@@ -114,26 +123,27 @@ static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
 	dsi->dev.bus = &mipi_dsi_bus_type;
 	dsi->dev.parent = host->dev;
 	dsi->dev.type = &mipi_dsi_device_type;
+	dsi->dev.of_node = info->node;
+	dsi->channel = info->reg;
 
-	device_initialize(&dsi->dev);
-
-	return dsi;
-}
-
-static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
-{
-	struct mipi_dsi_host *host = dsi->host;
+	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
-	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev),  dsi->channel);
+	r = device_register(&dsi->dev);
+	if (r) {
+		dev_err(dev, "failed to register device: %d\n", r);
+		kfree(dsi);
+		return ERR_PTR(r);
+	}
 
-	return device_add(&dsi->dev);
+	return dsi;
 }
+EXPORT_SYMBOL(mipi_dsi_device_new);
 
 static struct mipi_dsi_device *
 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 {
-	struct mipi_dsi_device *dsi;
 	struct device *dev = host->dev;
+	struct mipi_dsi_device_info info = { };
 	int ret;
 	u32 reg;
 
@@ -144,31 +154,10 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (reg > 3) {
-		dev_err(dev, "device node %s has invalid reg property: %u\n",
-			node->full_name, reg);
-		return ERR_PTR(-EINVAL);
-	}
-
-	dsi = mipi_dsi_device_alloc(host);
-	if (IS_ERR(dsi)) {
-		dev_err(dev, "failed to allocate DSI device %s: %ld\n",
-			node->full_name, PTR_ERR(dsi));
-		return dsi;
-	}
-
-	dsi->dev.of_node = of_node_get(node);
-	dsi->channel = reg;
+	info.reg = reg;
+	info.node = of_node_get(node);
 
-	ret = mipi_dsi_device_add(dsi);
-	if (ret) {
-		dev_err(dev, "failed to add DSI device %s: %d\n",
-			node->full_name, ret);
-		kfree(dsi);
-		return ERR_PTR(ret);
-	}
-
-	return dsi;
+	return mipi_dsi_device_new(host, &info);
 }
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index f1d8d0d..90f4f3c 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -140,6 +140,19 @@ enum mipi_dsi_pixel_format {
 };
 
 /**
+ * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @reg: DSI virtual channel assigned to peripheral
+ * @node: pointer to OF device node
+ *
+ * This is populated and passed to mipi_dsi_device_new to create a new
+ * DSI device
+ */
+struct mipi_dsi_device_info {
+	u32 reg;
+	struct device_node *node;
+};
+
+/**
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
@@ -174,6 +187,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
+struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
+					    struct mipi_dsi_device_info *info);
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [RFC v2 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
  2015-10-06  9:24   ` [RFC v2 1/5] drm/dsi: Refactor device creation Archit Taneja
@ 2015-10-06  9:24   ` Archit Taneja
  2015-10-30 12:42     ` Andrzej Hajda
  2015-10-06  9:24   ` [RFC v2 3/5] drm/dsi: Check for used channels Archit Taneja
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-10-06  9:24 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

Add a device name field in mipi_dsi_device. This name is different from
the actual dev name (which is of the format "hostname.reg"). When the
device is created via DT, this name is set to the modalias string.
In the non-DT case, the driver creating the DSI device provides the
name by populating a filed in mipi_dsi_device_info.

Matching for DT case would be as it was before. For the non-DT case,
we compare the device and driver names. Matching by comparing driver and
device names isn't the best thing to do. I'd appreciate some suggestions
here.

Other buses (like i2c/spi) perform a non-DT match by comparing the
device name and entries in the driver's id_table. The id_table structs
for different buses are defined in "include/linux/mod_devicetable.h", I
didn't want to touch that for now.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 29 ++++++++++++++++++++++++++++-
 include/drm/drm_mipi_dsi.h     |  8 ++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 245ecfe..46ee515 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -45,9 +45,30 @@
  * subset of the MIPI DCS command set.
  */
 
+static const struct device_type mipi_dsi_device_type;
+
 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
 {
-	return of_driver_match_device(dev, drv);
+	struct mipi_dsi_device *dsi;
+
+	if (dev->type == &mipi_dsi_device_type)
+		dsi = to_mipi_dsi_device(dev);
+	else
+		return 0;
+
+	/* Attempt OF style match */
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
+	/*
+	 * Try to compare dsi device and driver names. If this matching approach
+	 * isn't strong, we'd probably want the dsi drivers to populate the
+	 * id_table field and use that instead
+	 */
+	if (!strcmp(dsi->name, drv->name))
+		return 1;
+
+	return 0;
 }
 
 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
@@ -125,6 +146,7 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 	dsi->dev.type = &mipi_dsi_device_type;
 	dsi->dev.of_node = info->node;
 	dsi->channel = info->reg;
+	strlcpy(dsi->name, info->name, sizeof(dsi->name));
 
 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
@@ -147,6 +169,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 	int ret;
 	u32 reg;
 
+	if (of_modalias_node(node, info.name, sizeof(info.name)) < 0) {
+		dev_err(dev, "modalias failure on %s\n", node->full_name);
+		return ERR_PTR(-EINVAL);
+	}
+
 	ret = of_property_read_u32(node, "reg", &reg);
 	if (ret) {
 		dev_err(dev, "device node %s has no valid reg property: %d\n",
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 90f4f3c..93dec7b 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -139,8 +139,11 @@ enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB565,
 };
 
+#define DSI_DEV_NAME_SIZE		20
+
 /**
  * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @name: name of the dsi peripheral
  * @reg: DSI virtual channel assigned to peripheral
  * @node: pointer to OF device node
  *
@@ -148,14 +151,17 @@ enum mipi_dsi_pixel_format {
  * DSI device
  */
 struct mipi_dsi_device_info {
+	char name[DSI_DEV_NAME_SIZE];
 	u32 reg;
 	struct device_node *node;
 };
 
+
 /**
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
+ * @name: name of the dsi peripheral
  * @channel: virtual channel assigned to the peripheral
  * @format: pixel format for video mode
  * @lanes: number of active data lanes
@@ -165,6 +171,8 @@ struct mipi_dsi_device {
 	struct mipi_dsi_host *host;
 	struct device dev;
 
+	char name[DSI_DEV_NAME_SIZE];
+
 	unsigned int channel;
 	unsigned int lanes;
 	enum mipi_dsi_pixel_format format;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [RFC v2 3/5] drm/dsi: Check for used channels
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
  2015-10-06  9:24   ` [RFC v2 1/5] drm/dsi: Refactor device creation Archit Taneja
  2015-10-06  9:24   ` [RFC v2 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
@ 2015-10-06  9:24   ` Archit Taneja
  2015-10-30 12:52     ` Andrzej Hajda
  2015-10-06  9:24   ` [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-10-06  9:24 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

We don't check whether a previously registered mipi_dsi_device under the
same host shares the same virtual channel.

Before registering, check if any of the registered devices doesn't
already have the same virtual channel.

This wasn't crucial when all the devices under a host were populated via
DT. Now that we also support creating devices manually, we could end up
in a situation where a driver tries to create a device with a virtual
channel already taken by a device populated in DT.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 46ee515..db6130a 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -123,6 +123,22 @@ static const struct device_type mipi_dsi_device_type = {
 	.release = mipi_dsi_dev_release,
 };
 
+static int __dsi_check_chan_busy(struct device *dev, void *data)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+	u32 reg = *(u32 *) data;
+
+	if (dsi && dsi->channel == reg)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int mipi_dsi_check_chan_busy(struct mipi_dsi_host *host, u32 reg)
+{
+	return device_for_each_child(host->dev, &reg, __dsi_check_chan_busy);
+}
+
 struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 					    struct mipi_dsi_device_info *info)
 {
@@ -150,14 +166,20 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 
 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
+	r = mipi_dsi_check_chan_busy(host, info->reg);
+	if (r)
+		goto err;
+
 	r = device_register(&dsi->dev);
 	if (r) {
 		dev_err(dev, "failed to register device: %d\n", r);
-		kfree(dsi);
-		return ERR_PTR(r);
+		goto err;
 	}
 
 	return dsi;
+err:
+	kfree(dsi);
+	return ERR_PTR(r);
 }
 EXPORT_SYMBOL(mipi_dsi_device_new);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
                     ` (2 preceding siblings ...)
  2015-10-06  9:24   ` [RFC v2 3/5] drm/dsi: Check for used channels Archit Taneja
@ 2015-10-06  9:24   ` Archit Taneja
  2015-10-30 14:21     ` Andrzej Hajda
  2015-10-06  9:24   ` [RFC v2 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
  5 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-10-06  9:24 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

A driver calling mipi_dsi_device_new might want to unregister the device
once it's done. It might also require it in an error handling path in
case something didn't go right.

When the dsi host driver calls mipi_dsi_host_unregister, the devices
created by both DT and and without DT will be removed. This does leave
the possibility of the host removing the dsi device without the
peripheral driver being aware of it. I don't know a good way to solve
this. Some suggestions here would be of help too.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 7 +++++++
 include/drm/drm_mipi_dsi.h     | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index db6130a..cbb7373 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -183,6 +183,13 @@ err:
 }
 EXPORT_SYMBOL(mipi_dsi_device_new);
 
+void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
+{
+	if (dsi)
+		device_unregister(&dsi->dev);
+}
+EXPORT_SYMBOL(mipi_dsi_device_unregister);
+
 static struct mipi_dsi_device *
 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 {
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 93dec7b..68f49f4 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -197,6 +197,8 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 
 struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 					    struct mipi_dsi_device_info *info);
+void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
+
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [RFC v2 5/5] drm/dsi: Get DSI host by DT device node
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
                     ` (3 preceding siblings ...)
  2015-10-06  9:24   ` [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
@ 2015-10-06  9:24   ` Archit Taneja
  2015-10-06 10:00     ` kbuild test robot
  2015-11-02 10:50     ` Andrzej Hajda
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
  5 siblings, 2 replies; 84+ messages in thread
From: Archit Taneja @ 2015-10-06  9:24 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

mipi_dsi_devices are inherently aware of their host because they
share a parent-child hierarchy in the device tree.

Non-dsi drivers that create a dummy dsi device don't have this data.
In order to get this information, they require to a phandle to the dsi
host in the device tree.

Maintain a list of all the hosts DSI that are currently registered.

This list will be used to find the mipi_dsi_host corresponding to the
device_node passed in of_find_mipi_dsi_host_by_node.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 30 ++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index cbb7373..c51d73e 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -216,6 +216,28 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 	return mipi_dsi_device_new(host, &info);
 }
 
+static DEFINE_MUTEX(host_lock);
+static LIST_HEAD(host_list);
+
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
+{
+	struct mipi_dsi_host *host;
+
+	mutex_lock(&host_lock);
+
+	list_for_each_entry(host, &host_list, list) {
+		if (host->dev->of_node == node) {
+			mutex_unlock(&host_lock);
+			return host;
+		}
+	}
+
+	mutex_unlock(&host_lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
 	struct device_node *node;
@@ -227,6 +249,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
 		of_mipi_dsi_device_add(host, node);
 	}
 
+	mutex_lock(&host_lock);
+	list_add_tail(&host->list, &host_list);
+	mutex_unlock(&host_lock);
+
 	return 0;
 }
 EXPORT_SYMBOL(mipi_dsi_host_register);
@@ -243,6 +269,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
 {
 	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
+
+	mutex_lock(&host_lock);
+	list_del_init(&host->list);
+	mutex_unlock(&host_lock);
 }
 EXPORT_SYMBOL(mipi_dsi_host_unregister);
 
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 68f49f4..15d3068 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -100,10 +100,12 @@ struct mipi_dsi_host_ops {
 struct mipi_dsi_host {
 	struct device *dev;
 	const struct mipi_dsi_host_ops *ops;
+	struct list_head list;
 };
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host);
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 
 /* DSI mode flags */
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* Re: [RFC v2 5/5] drm/dsi: Get DSI host by DT device node
  2015-10-06  9:24   ` [RFC v2 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2015-10-06 10:00     ` kbuild test robot
  2015-11-02 10:50     ` Andrzej Hajda
  1 sibling, 0 replies; 84+ messages in thread
From: kbuild test robot @ 2015-10-06 10:00 UTC (permalink / raw)
  To: Archit Taneja
  Cc: kbuild-all, dri-devel, a.hajda, linux-kernel, airlied, daniel,
	treding, l.stach, robh, linux-arm-msm, jani.nikula,
	Archit Taneja

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

Hi Archit,

[auto build test WARNING on v4.3-rc4 -- if it's inappropriate base, please ignore]

reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/i915/i915_irq.c:491: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2217: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'wedged'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'fmt'
   include/drm/drm_crtc.h:310: warning: No description found for parameter 'mode_blob'
   include/drm/drm_crtc.h:748: warning: No description found for parameter 'tile_blob_ptr'
   include/drm/drm_crtc.h:787: warning: No description found for parameter 'rotation'
   include/drm/drm_crtc.h:883: warning: No description found for parameter 'mutex'
   include/drm/drm_crtc.h:883: warning: No description found for parameter 'helper_private'
   include/drm/drm_crtc.h:931: warning: Excess struct/union/enum/typedef member 'base' description in 'drm_bridge'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tile_idr'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'delayed_event'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'edid_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'dpms_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'path_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tile_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'plane_type_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'rotation_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_src_x'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_src_y'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_src_w'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_src_h'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_crtc_x'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_crtc_y'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_crtc_w'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_crtc_h'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_fb_id'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_crtc_id'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_active'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'prop_mode_id'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'dvi_i_subconnector_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'dvi_i_select_subconnector_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_subconnector_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_select_subconnector_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_mode_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_left_margin_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_right_margin_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_top_margin_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_bottom_margin_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_brightness_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_contrast_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_flicker_reduction_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_overscan_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_saturation_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'tv_hue_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'scaling_mode_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'aspect_ratio_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'dirty_info_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'suggested_x_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'suggested_y_property'
   include/drm/drm_crtc.h:1169: warning: No description found for parameter 'allow_fb_modifiers'
   Warning(include/drm/drm_modeset_lock.h:47): Incorrect use of kernel-doc format: 	 * Contended lock: if a lock is contended you should only call
   Warning(include/drm/drm_modeset_lock.h:54): Incorrect use of kernel-doc format: 	 * list of held locks (drm_modeset_lock)
   Warning(include/drm/drm_modeset_lock.h:59): Incorrect use of kernel-doc format: 	 * Trylock mode, use only for panic handlers!
   Warning(include/drm/drm_modeset_lock.h:74): Incorrect use of kernel-doc format: 	 * modeset lock
   Warning(include/drm/drm_modeset_lock.h:79): Incorrect use of kernel-doc format: 	 * Resources that are locked as part of an atomic update are added
   include/drm/drm_dp_helper.h:706: warning: No description found for parameter 'i2c_nack_count'
   include/drm/drm_dp_helper.h:706: warning: No description found for parameter 'i2c_defer_count'
   drivers/gpu/drm/drm_dp_mst_topology.c:2226: warning: No description found for parameter 'connector'
   include/drm/drm_dp_mst_helper.h:97: warning: No description found for parameter 'cached_edid'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'max_dpcd_transaction_bytes'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'sink_count'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'total_slots'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'avail_slots'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'total_pbn'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'qlock'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'tx_msg_downq'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'tx_msg_upq'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'tx_down_in_progress'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'tx_up_in_progress'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'payload_lock'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'proposed_vcpis'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'payloads'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'payload_mask'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'vcpi_mask'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'tx_waitq'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'work'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'tx_work'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'destroy_connector_list'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'destroy_connector_lock'
   include/drm/drm_dp_mst_helper.h:471: warning: No description found for parameter 'destroy_connector_work'
   drivers/gpu/drm/drm_dp_mst_topology.c:2226: warning: No description found for parameter 'connector'
>> include/drm/drm_mipi_dsi.h:104: warning: No description found for parameter 'list'
   include/drm/drmP.h:164: warning: No description found for parameter 'fmt'
   include/drm/drmP.h:180: warning: No description found for parameter 'fmt'
   include/drm/drmP.h:198: warning: No description found for parameter 'fmt'
   include/drm/drmP.h:238: warning: No description found for parameter 'dev'
   include/drm/drmP.h:238: warning: No description found for parameter 'data'
   include/drm/drmP.h:238: warning: No description found for parameter 'file_priv'
   include/drm/drmP.h:271: warning: No description found for parameter 'ioctl'
   include/drm/drmP.h:271: warning: No description found for parameter '_func'
   include/drm/drmP.h:271: warning: No description found for parameter '_flags'
   include/drm/drmP.h:344: warning: cannot understand function prototype: 'struct drm_lock_data '
   include/drm/drmP.h:397: warning: cannot understand function prototype: 'struct drm_driver '
   include/drm/drmP.h:646: warning: cannot understand function prototype: 'struct drm_info_list '
   include/drm/drmP.h:656: warning: cannot understand function prototype: 'struct drm_info_node '
   include/drm/drmP.h:666: warning: cannot understand function prototype: 'struct drm_minor '
   include/drm/drmP.h:712: warning: cannot understand function prototype: 'struct drm_device '
   drivers/gpu/drm/i915/i915_irq.c:491: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2217: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'wedged'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'fmt'
   drivers/gpu/drm/i915/i915_irq.c:491: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2217: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'wedged'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'fmt'
   drivers/gpu/drm/i915/i915_irq.c:491: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2217: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'wedged'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'fmt'
   drivers/gpu/drm/i915/i915_irq.c:491: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2217: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'wedged'
   drivers/gpu/drm/i915/i915_irq.c:2397: warning: No description found for parameter 'fmt'
   drivers/gpu/drm/i915/i915_gem.c:421: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:421: warning: No description found for parameter 'data'
   drivers/gpu/drm/i915/i915_gem.c:421: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:686: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:686: warning: No description found for parameter 'data'
   drivers/gpu/drm/i915/i915_gem.c:686: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'obj'
   drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'args'
   drivers/gpu/drm/i915/i915_gem.c:767: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:1027: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:1027: warning: No description found for parameter 'data'
   drivers/gpu/drm/i915/i915_gem.c:1027: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:1192: warning: No description found for parameter 'rps'
   drivers/gpu/drm/i915/i915_gem.c:1398: warning: No description found for parameter 'req'
   drivers/gpu/drm/i915/i915_gem.c:1433: warning: No description found for parameter 'obj'
   drivers/gpu/drm/i915/i915_gem.c:1433: warning: No description found for parameter 'readonly'
   drivers/gpu/drm/i915/i915_gem.c:1556: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:1556: warning: No description found for parameter 'data'
   drivers/gpu/drm/i915/i915_gem.c:1556: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:1619: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:1619: warning: No description found for parameter 'data'
   drivers/gpu/drm/i915/i915_gem.c:1619: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:1664: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:1664: warning: No description found for parameter 'data'
   drivers/gpu/drm/i915/i915_gem.c:1664: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:1729: warning: No description found for parameter 'vma'
   drivers/gpu/drm/i915/i915_gem.c:1729: warning: No description found for parameter 'vmf'
   drivers/gpu/drm/i915/i915_gem.c:1952: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:1952: warning: No description found for parameter 'size'
   drivers/gpu/drm/i915/i915_gem.c:1952: warning: No description found for parameter 'tiling_mode'
   drivers/gpu/drm/i915/i915_gem.c:1952: warning: No description found for parameter 'fenced'
   drivers/gpu/drm/i915/i915_gem.c:1952: warning: Excess function parameter 'obj' description in 'i915_gem_get_gtt_alignment'
   drivers/gpu/drm/i915/i915_gem.c:2815: warning: No description found for parameter 'ring'
   drivers/gpu/drm/i915/i915_gem.c:2944: warning: No description found for parameter 'obj'
   drivers/gpu/drm/i915/i915_gem.c:2994: warning: No description found for parameter 'dev'
   drivers/gpu/drm/i915/i915_gem.c:2994: warning: No description found for parameter 'data'
   drivers/gpu/drm/i915/i915_gem.c:2994: warning: No description found for parameter 'file'
   drivers/gpu/drm/i915/i915_gem.c:2994: warning: Excess function parameter 'DRM_IOCTL_ARGS' description in 'i915_gem_wait_ioctl'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for parameter 'obj'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for parameter 'vm'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for parameter 'ggtt_view'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for parameter 'alignment'
   drivers/gpu/drm/i915/i915_gem.c:3355: warning: No description found for parameter 'flags'
   drivers/gpu/drm/i915/i915_gem.c:3576: warning: No description found for parameter 'obj'
   drivers/gpu/drm/i915/i915_gem.c:3576: warning: No description found for parameter 'write'
   drivers/gpu/drm/i915/i915_gem.c:3858: warning: No description found for parameter 'obj'
   drivers/gpu/drm/i915/i915_gem.c:3858: warning: No description found for parameter 'write'
   drivers/gpu/drm/i915/i915_gem.c:4962: warning: No description found for parameter 'old'
   drivers/gpu/drm/i915/i915_gem.c:4962: warning: No description found for parameter 'new'
   drivers/gpu/drm/i915/i915_gem.c:4962: warning: No description found for parameter 'frontbuffer_bits'
   drivers/gpu/drm/i915/intel_lrc.c:782: warning: No description found for parameter 'req'
   drivers/gpu/drm/i915/intel_lrc.c:782: warning: Excess function parameter 'request' description in 'intel_logical_ring_begin'
   drivers/gpu/drm/i915/intel_lrc.c:782: warning: Excess function parameter 'ctx' description in 'intel_logical_ring_begin'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: No description found for parameter 'params'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'dev' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'file' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'ring' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'ctx' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'batch_obj' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'exec_start' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'dispatch_flags' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:782: warning: No description found for parameter 'req'
   drivers/gpu/drm/i915/intel_lrc.c:782: warning: Excess function parameter 'request' description in 'intel_logical_ring_begin'
   drivers/gpu/drm/i915/intel_lrc.c:782: warning: Excess function parameter 'ctx' description in 'intel_logical_ring_begin'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: No description found for parameter 'params'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'dev' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'file' description in 'intel_execlists_submission'
   drivers/gpu/drm/i915/intel_lrc.c:837: warning: Excess function parameter 'ring' description in 'intel_execlists_submission'

vim +/list +104 include/drm/drm_mipi_dsi.h

068a0023 Andrzej Hajda  2013-12-04   88  		      struct mipi_dsi_device *dsi);
068a0023 Andrzej Hajda  2013-12-04   89  	int (*detach)(struct mipi_dsi_host *host,
068a0023 Andrzej Hajda  2013-12-04   90  		      struct mipi_dsi_device *dsi);
068a0023 Andrzej Hajda  2013-12-04   91  	ssize_t (*transfer)(struct mipi_dsi_host *host,
ed6ff40e Thierry Reding 2014-08-05   92  			    const struct mipi_dsi_msg *msg);
068a0023 Andrzej Hajda  2013-12-04   93  };
068a0023 Andrzej Hajda  2013-12-04   94  
068a0023 Andrzej Hajda  2013-12-04   95  /**
068a0023 Andrzej Hajda  2013-12-04   96   * struct mipi_dsi_host - DSI host device
068a0023 Andrzej Hajda  2013-12-04   97   * @dev: driver model device node for this DSI host
068a0023 Andrzej Hajda  2013-12-04   98   * @ops: DSI host operations
068a0023 Andrzej Hajda  2013-12-04   99   */
068a0023 Andrzej Hajda  2013-12-04  100  struct mipi_dsi_host {
068a0023 Andrzej Hajda  2013-12-04  101  	struct device *dev;
068a0023 Andrzej Hajda  2013-12-04  102  	const struct mipi_dsi_host_ops *ops;
b3e0f8f8 Archit Taneja  2015-10-06  103  	struct list_head list;
068a0023 Andrzej Hajda  2013-12-04 @104  };
068a0023 Andrzej Hajda  2013-12-04  105  
068a0023 Andrzej Hajda  2013-12-04  106  int mipi_dsi_host_register(struct mipi_dsi_host *host);
068a0023 Andrzej Hajda  2013-12-04  107  void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
b3e0f8f8 Archit Taneja  2015-10-06  108  struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
068a0023 Andrzej Hajda  2013-12-04  109  
068a0023 Andrzej Hajda  2013-12-04  110  /* DSI mode flags */
068a0023 Andrzej Hajda  2013-12-04  111  
068a0023 Andrzej Hajda  2013-12-04  112  /* video mode */

:::::: The code at line 104 was first introduced by commit
:::::: 068a00233969833f1ba925e7627797489efd6041 drm: Add MIPI DSI bus support

:::::: TO: Andrzej Hajda <a.hajda@samsung.com>
:::::: CC: Thierry Reding <treding@nvidia.com>

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

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 6062 bytes --]

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

* Re: [RFC v2 1/5] drm/dsi: Refactor device creation
  2015-10-06  9:24   ` [RFC v2 1/5] drm/dsi: Refactor device creation Archit Taneja
@ 2015-10-30 11:28     ` Andrzej Hajda
  0 siblings, 0 replies; 84+ messages in thread
From: Andrzej Hajda @ 2015-10-30 11:28 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

On 10/06/2015 11:24 AM, Archit Taneja wrote:
> Simplify the mipi dsi device creation process. device_initialize and
> device_add don't need to be called separately when creating
> mipi_dsi_device's. Use device_register instead to simplify things.
>
> Create a helper function mipi_dsi_device_new which takes in struct
> mipi_dsi_device_info and mipi_dsi_host. It clubs the functions
> mipi_dsi_device_alloc and mipi_dsi_device_add into one.
>
> mipi_dsi_device_info acts as a template to populate the dsi device
> information. This is populated by of_mipi_dsi_device_add and passed to
> mipi_dsi_device_new.
>
> Later on, we'll provide mipi_dsi_device_new as a standalone way to create
> a dsi device not available via DT.
>
> The new device creation process tries to closely follow what's been done
> in i2c_new_device in i2c-core.
>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>

Regards
Andrzej

> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 61 +++++++++++++++++-------------------------
>  include/drm/drm_mipi_dsi.h     | 15 +++++++++++
>  2 files changed, 40 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 2d5ca8ee..245ecfe 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -102,9 +102,18 @@ static const struct device_type mipi_dsi_device_type = {
>  	.release = mipi_dsi_dev_release,
>  };
>  
> -static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
> +struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
> +					    struct mipi_dsi_device_info *info)
>  {
>  	struct mipi_dsi_device *dsi;
> +	struct device *dev = host->dev;
> +	int r;

> +
> +	if (info->reg > 3) {
> +		dev_err(dev, "device node has invalid reg property: %u\n",
> +			info->reg);
> +		return ERR_PTR(-EINVAL);
> +	}
>  
>  	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
>  	if (!dsi)
> @@ -114,26 +123,27 @@ static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
>  	dsi->dev.bus = &mipi_dsi_bus_type;
>  	dsi->dev.parent = host->dev;
>  	dsi->dev.type = &mipi_dsi_device_type;
> +	dsi->dev.of_node = info->node;
> +	dsi->channel = info->reg;
>  
> -	device_initialize(&dsi->dev);
> -
> -	return dsi;
> -}
> -
> -static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
> -{
> -	struct mipi_dsi_host *host = dsi->host;
> +	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
>  
> -	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev),  dsi->channel);
> +	r = device_register(&dsi->dev);
> +	if (r) {
> +		dev_err(dev, "failed to register device: %d\n", r);
> +		kfree(dsi);
> +		return ERR_PTR(r);
> +	}
>  
> -	return device_add(&dsi->dev);
> +	return dsi;
>  }
> +EXPORT_SYMBOL(mipi_dsi_device_new);
>  
>  static struct mipi_dsi_device *
>  of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  {
> -	struct mipi_dsi_device *dsi;
>  	struct device *dev = host->dev;
> +	struct mipi_dsi_device_info info = { };
>  	int ret;
>  	u32 reg;
>  
> @@ -144,31 +154,10 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  		return ERR_PTR(-EINVAL);
>  	}
>  
> -	if (reg > 3) {
> -		dev_err(dev, "device node %s has invalid reg property: %u\n",
> -			node->full_name, reg);
> -		return ERR_PTR(-EINVAL);
> -	}
> -
> -	dsi = mipi_dsi_device_alloc(host);
> -	if (IS_ERR(dsi)) {
> -		dev_err(dev, "failed to allocate DSI device %s: %ld\n",
> -			node->full_name, PTR_ERR(dsi));
> -		return dsi;
> -	}
> -
> -	dsi->dev.of_node = of_node_get(node);
> -	dsi->channel = reg;
> +	info.reg = reg;
> +	info.node = of_node_get(node);
>  
> -	ret = mipi_dsi_device_add(dsi);
> -	if (ret) {
> -		dev_err(dev, "failed to add DSI device %s: %d\n",
> -			node->full_name, ret);
> -		kfree(dsi);
> -		return ERR_PTR(ret);
> -	}
> -
> -	return dsi;
> +	return mipi_dsi_device_new(host, &info);
>  }
>  
>  int mipi_dsi_host_register(struct mipi_dsi_host *host)
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index f1d8d0d..90f4f3c 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -140,6 +140,19 @@ enum mipi_dsi_pixel_format {
>  };
>  
>  /**
> + * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
> + * @reg: DSI virtual channel assigned to peripheral
> + * @node: pointer to OF device node
> + *
> + * This is populated and passed to mipi_dsi_device_new to create a new
> + * DSI device
> + */
> +struct mipi_dsi_device_info {
> +	u32 reg;
> +	struct device_node *node;
> +};
> +
> +/**
>   * struct mipi_dsi_device - DSI peripheral device
>   * @host: DSI host for this peripheral
>   * @dev: driver model device node for this peripheral
> @@ -174,6 +187,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
>  ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>  			      size_t num_params, void *data, size_t size);
>  
> +struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
> +					    struct mipi_dsi_device_info *info);
>  /**
>   * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
>   * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking


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

* Re: [RFC v2 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-10-06  9:24   ` [RFC v2 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
@ 2015-10-30 12:42     ` Andrzej Hajda
  2015-11-02  5:26       ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Andrzej Hajda @ 2015-10-30 12:42 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

On 10/06/2015 11:24 AM, Archit Taneja wrote:
> Add a device name field in mipi_dsi_device. This name is different from
> the actual dev name (which is of the format "hostname.reg"). When the
> device is created via DT, this name is set to the modalias string.
> In the non-DT case, the driver creating the DSI device provides the
> name by populating a filed in mipi_dsi_device_info.
>
> Matching for DT case would be as it was before. For the non-DT case,
> we compare the device and driver names. Matching by comparing driver and
> device names isn't the best thing to do. I'd appreciate some suggestions
> here.
>
> Other buses (like i2c/spi) perform a non-DT match by comparing the
> device name and entries in the driver's id_table. The id_table structs
> for different buses are defined in "include/linux/mod_devicetable.h", I
> didn't want to touch that for now.
>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
Beside small comments below.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>

> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 29 ++++++++++++++++++++++++++++-
>  include/drm/drm_mipi_dsi.h     |  8 ++++++++
>  2 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 245ecfe..46ee515 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -45,9 +45,30 @@
>   * subset of the MIPI DCS command set.
>   */
>  
> +static const struct device_type mipi_dsi_device_type;
> +
>  static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
>  {
> -	return of_driver_match_device(dev, drv);
> +	struct mipi_dsi_device *dsi;
> +
> +	if (dev->type == &mipi_dsi_device_type)
> +		dsi = to_mipi_dsi_device(dev);
> +	else
> +		return 0;
> +
> +	/* Attempt OF style match */
> +	if (of_driver_match_device(dev, drv))
> +		return 1;
> +
> +	/*
> +	 * Try to compare dsi device and driver names. If this matching approach
> +	 * isn't strong, we'd probably want the dsi drivers to populate the
> +	 * id_table field and use that instead
> +	 */
> +	if (!strcmp(dsi->name, drv->name))
> +		return 1;
> +
> +	return 0;
>  }
>  
>  static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
> @@ -125,6 +146,7 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>  	dsi->dev.type = &mipi_dsi_device_type;
>  	dsi->dev.of_node = info->node;
>  	dsi->channel = info->reg;
> +	strlcpy(dsi->name, info->name, sizeof(dsi->name));
>  
>  	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
>  
> @@ -147,6 +169,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  	int ret;
>  	u32 reg;
>  
> +	if (of_modalias_node(node, info.name, sizeof(info.name)) < 0) {
> +		dev_err(dev, "modalias failure on %s\n", node->full_name);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
>  	ret = of_property_read_u32(node, "reg", &reg);
>  	if (ret) {
>  		dev_err(dev, "device node %s has no valid reg property: %d\n",
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 90f4f3c..93dec7b 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -139,8 +139,11 @@ enum mipi_dsi_pixel_format {
>  	MIPI_DSI_FMT_RGB565,
>  };
>  
> +#define DSI_DEV_NAME_SIZE		20
> +
>  /**
>   * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
> + * @name: name of the dsi peripheral
>   * @reg: DSI virtual channel assigned to peripheral
>   * @node: pointer to OF device node
>   *
> @@ -148,14 +151,17 @@ enum mipi_dsi_pixel_format {
>   * DSI device
>   */
>  struct mipi_dsi_device_info {
> +	char name[DSI_DEV_NAME_SIZE];
I wonder if it shouldn't be called type as in case of i2c,
but no strong feelings.
>  	u32 reg;
>  	struct device_node *node;
>  };
>  
> +
Empty line.

>  /**
>   * struct mipi_dsi_device - DSI peripheral device
>   * @host: DSI host for this peripheral
>   * @dev: driver model device node for this peripheral
> + * @name: name of the dsi peripheral
>   * @channel: virtual channel assigned to the peripheral
>   * @format: pixel format for video mode
>   * @lanes: number of active data lanes
> @@ -165,6 +171,8 @@ struct mipi_dsi_device {
>  	struct mipi_dsi_host *host;
>  	struct device dev;
>  
> +	char name[DSI_DEV_NAME_SIZE];
> +
This empty line can be also removed.

Regards
Andrzej

>  	unsigned int channel;
>  	unsigned int lanes;
>  	enum mipi_dsi_pixel_format format;


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

* Re: [RFC v2 3/5] drm/dsi: Check for used channels
  2015-10-06  9:24   ` [RFC v2 3/5] drm/dsi: Check for used channels Archit Taneja
@ 2015-10-30 12:52     ` Andrzej Hajda
  2015-11-02  5:28       ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Andrzej Hajda @ 2015-10-30 12:52 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

On 10/06/2015 11:24 AM, Archit Taneja wrote:
> We don't check whether a previously registered mipi_dsi_device under the
> same host shares the same virtual channel.
>
> Before registering, check if any of the registered devices doesn't
> already have the same virtual channel.
>
> This wasn't crucial when all the devices under a host were populated via
> DT. Now that we also support creating devices manually, we could end up
> in a situation where a driver tries to create a device with a virtual
> channel already taken by a device populated in DT.
>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
Beside few non-blcking nitpicks.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>

> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 46ee515..db6130a 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -123,6 +123,22 @@ static const struct device_type mipi_dsi_device_type = {
>  	.release = mipi_dsi_dev_release,
>  };
>  
> +static int __dsi_check_chan_busy(struct device *dev, void *data)
> +{
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
> +	u32 reg = *(u32 *) data;
> +
> +	if (dsi && dsi->channel == reg)
Maybe simpler would be:

    u32 *reg = data;
 
    if (dsi && dsi->channel == *reg)



> +		return -EBUSY;
> +
> +	return 0;
> +}
> +
> +static int mipi_dsi_check_chan_busy(struct mipi_dsi_host *host, u32 reg)
> +{
> +	return device_for_each_child(host->dev, &reg, __dsi_check_chan_busy);
> +}
> +
>  struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>  					    struct mipi_dsi_device_info *info)
>  {
> @@ -150,14 +166,20 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>  
>  	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
>  
> +	r = mipi_dsi_check_chan_busy(host, info->reg);

I know this r variable was introduced in the 1st patch, but if you will send
next iteration
consider replacing it with ret, looks more readable and follows file convention :)

Regards
Andrzej

> +	if (r)
> +		goto err;
> +
>  	r = device_register(&dsi->dev);
>  	if (r) {
>  		dev_err(dev, "failed to register device: %d\n", r);
> -		kfree(dsi);
> -		return ERR_PTR(r);
> +		goto err;
>  	}
>  
>  	return dsi;
> +err:
> +	kfree(dsi);
> +	return ERR_PTR(r);
>  }
>  EXPORT_SYMBOL(mipi_dsi_device_new);
>  


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

* Re: [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device
  2015-10-06  9:24   ` [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
@ 2015-10-30 14:21     ` Andrzej Hajda
  2015-11-02  6:28       ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Andrzej Hajda @ 2015-10-30 14:21 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

On 10/06/2015 11:24 AM, Archit Taneja wrote:
> A driver calling mipi_dsi_device_new might want to unregister the device
> once it's done. It might also require it in an error handling path in
> case something didn't go right.
>
> When the dsi host driver calls mipi_dsi_host_unregister, the devices
> created by both DT and and without DT will be removed. This does leave
> the possibility of the host removing the dsi device without the
> peripheral driver being aware of it. I don't know a good way to solve
> this. Some suggestions here would be of help too.
The 2nd paragraph is not relevant here. It is another issue. Some comments
about it:
I am not sure, but I guess device should not be removed if it is refcounted
properly, it will be just detached from the driver, bus and system (whatever it
means:) ).
It does not mean it will be usable and probably some races can occur anyway.
I guess i2c and other buses have the same problem, am I right?

>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 7 +++++++
>  include/drm/drm_mipi_dsi.h     | 2 ++
>  2 files changed, 9 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index db6130a..cbb7373 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -183,6 +183,13 @@ err:
>  }
>  EXPORT_SYMBOL(mipi_dsi_device_new);
>  
> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
> +{
> +	if (dsi)
> +		device_unregister(&dsi->dev);
> +}
> +EXPORT_SYMBOL(mipi_dsi_device_unregister);
> +
I guess NULL check can be removed and the whole function can be inlined.

Regards
Andrzej
>  static struct mipi_dsi_device *
>  of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  {
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 93dec7b..68f49f4 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -197,6 +197,8 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>  
>  struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>  					    struct mipi_dsi_device_info *info);
> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
> +
>  /**
>   * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
>   * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking


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

* Re: [RFC v2 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-10-30 12:42     ` Andrzej Hajda
@ 2015-11-02  5:26       ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-02  5:26 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula



On 10/30/2015 06:12 PM, Andrzej Hajda wrote:
> On 10/06/2015 11:24 AM, Archit Taneja wrote:
>> Add a device name field in mipi_dsi_device. This name is different from
>> the actual dev name (which is of the format "hostname.reg"). When the
>> device is created via DT, this name is set to the modalias string.
>> In the non-DT case, the driver creating the DSI device provides the
>> name by populating a filed in mipi_dsi_device_info.
>>
>> Matching for DT case would be as it was before. For the non-DT case,
>> we compare the device and driver names. Matching by comparing driver and
>> device names isn't the best thing to do. I'd appreciate some suggestions
>> here.
>>
>> Other buses (like i2c/spi) perform a non-DT match by comparing the
>> device name and entries in the driver's id_table. The id_table structs
>> for different buses are defined in "include/linux/mod_devicetable.h", I
>> didn't want to touch that for now.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> Beside small comments below.
>
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 29 ++++++++++++++++++++++++++++-
>>   include/drm/drm_mipi_dsi.h     |  8 ++++++++
>>   2 files changed, 36 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index 245ecfe..46ee515 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -45,9 +45,30 @@
>>    * subset of the MIPI DCS command set.
>>    */
>>
>> +static const struct device_type mipi_dsi_device_type;
>> +
>>   static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
>>   {
>> -	return of_driver_match_device(dev, drv);
>> +	struct mipi_dsi_device *dsi;
>> +
>> +	if (dev->type == &mipi_dsi_device_type)
>> +		dsi = to_mipi_dsi_device(dev);
>> +	else
>> +		return 0;
>> +
>> +	/* Attempt OF style match */
>> +	if (of_driver_match_device(dev, drv))
>> +		return 1;
>> +
>> +	/*
>> +	 * Try to compare dsi device and driver names. If this matching approach
>> +	 * isn't strong, we'd probably want the dsi drivers to populate the
>> +	 * id_table field and use that instead
>> +	 */
>> +	if (!strcmp(dsi->name, drv->name))
>> +		return 1;
>> +
>> +	return 0;
>>   }
>>
>>   static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
>> @@ -125,6 +146,7 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>   	dsi->dev.type = &mipi_dsi_device_type;
>>   	dsi->dev.of_node = info->node;
>>   	dsi->channel = info->reg;
>> +	strlcpy(dsi->name, info->name, sizeof(dsi->name));
>>
>>   	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
>>
>> @@ -147,6 +169,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>   	int ret;
>>   	u32 reg;
>>
>> +	if (of_modalias_node(node, info.name, sizeof(info.name)) < 0) {
>> +		dev_err(dev, "modalias failure on %s\n", node->full_name);
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>>   	ret = of_property_read_u32(node, "reg", &reg);
>>   	if (ret) {
>>   		dev_err(dev, "device node %s has no valid reg property: %d\n",
>> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
>> index 90f4f3c..93dec7b 100644
>> --- a/include/drm/drm_mipi_dsi.h
>> +++ b/include/drm/drm_mipi_dsi.h
>> @@ -139,8 +139,11 @@ enum mipi_dsi_pixel_format {
>>   	MIPI_DSI_FMT_RGB565,
>>   };
>>
>> +#define DSI_DEV_NAME_SIZE		20
>> +
>>   /**
>>    * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
>> + * @name: name of the dsi peripheral
>>    * @reg: DSI virtual channel assigned to peripheral
>>    * @node: pointer to OF device node
>>    *
>> @@ -148,14 +151,17 @@ enum mipi_dsi_pixel_format {
>>    * DSI device
>>    */
>>   struct mipi_dsi_device_info {
>> +	char name[DSI_DEV_NAME_SIZE];
> I wonder if it shouldn't be called type as in case of i2c,
> but no strong feelings.

We could change it to 'type'. It'll be easier for someone to understand
what the dsi core is doing by keeping the same nomenclature as in
i2c-core.

>>   	u32 reg;
>>   	struct device_node *node;
>>   };
>>
>> +
> Empty line.
>
>>   /**
>>    * struct mipi_dsi_device - DSI peripheral device
>>    * @host: DSI host for this peripheral
>>    * @dev: driver model device node for this peripheral
>> + * @name: name of the dsi peripheral
>>    * @channel: virtual channel assigned to the peripheral
>>    * @format: pixel format for video mode
>>    * @lanes: number of active data lanes
>> @@ -165,6 +171,8 @@ struct mipi_dsi_device {
>>   	struct mipi_dsi_host *host;
>>   	struct device dev;
>>
>> +	char name[DSI_DEV_NAME_SIZE];
>> +
> This empty line can be also removed.
>

Will remove these.

Thanks,
Archit

> Regards
> Andrzej
>
>>   	unsigned int channel;
>>   	unsigned int lanes;
>>   	enum mipi_dsi_pixel_format format;
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [RFC v2 3/5] drm/dsi: Check for used channels
  2015-10-30 12:52     ` Andrzej Hajda
@ 2015-11-02  5:28       ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-02  5:28 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula



On 10/30/2015 06:22 PM, Andrzej Hajda wrote:
> On 10/06/2015 11:24 AM, Archit Taneja wrote:
>> We don't check whether a previously registered mipi_dsi_device under the
>> same host shares the same virtual channel.
>>
>> Before registering, check if any of the registered devices doesn't
>> already have the same virtual channel.
>>
>> This wasn't crucial when all the devices under a host were populated via
>> DT. Now that we also support creating devices manually, we could end up
>> in a situation where a driver tries to create a device with a virtual
>> channel already taken by a device populated in DT.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> Beside few non-blcking nitpicks.
>
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 26 ++++++++++++++++++++++++--
>>   1 file changed, 24 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index 46ee515..db6130a 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -123,6 +123,22 @@ static const struct device_type mipi_dsi_device_type = {
>>   	.release = mipi_dsi_dev_release,
>>   };
>>
>> +static int __dsi_check_chan_busy(struct device *dev, void *data)
>> +{
>> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
>> +	u32 reg = *(u32 *) data;
>> +
>> +	if (dsi && dsi->channel == reg)
> Maybe simpler would be:
>
>      u32 *reg = data;
>
>      if (dsi && dsi->channel == *reg)
>

This is better. I'll change it to this.

>
>
>> +		return -EBUSY;
>> +
>> +	return 0;
>> +}
>> +
>> +static int mipi_dsi_check_chan_busy(struct mipi_dsi_host *host, u32 reg)
>> +{
>> +	return device_for_each_child(host->dev, &reg, __dsi_check_chan_busy);
>> +}
>> +
>>   struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>   					    struct mipi_dsi_device_info *info)
>>   {
>> @@ -150,14 +166,20 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>
>>   	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
>>
>> +	r = mipi_dsi_check_chan_busy(host, info->reg);
>
> I know this r variable was introduced in the 1st patch, but if you will send
> next iteration
> consider replacing it with ret, looks more readable and follows file convention :)

I'll probably end up sending another iteration (or more). I'll change
the name.

Thanks,
Archit

>
> Regards
> Andrzej
>
>> +	if (r)
>> +		goto err;
>> +
>>   	r = device_register(&dsi->dev);
>>   	if (r) {
>>   		dev_err(dev, "failed to register device: %d\n", r);
>> -		kfree(dsi);
>> -		return ERR_PTR(r);
>> +		goto err;
>>   	}
>>
>>   	return dsi;
>> +err:
>> +	kfree(dsi);
>> +	return ERR_PTR(r);
>>   }
>>   EXPORT_SYMBOL(mipi_dsi_device_new);
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device
  2015-10-30 14:21     ` Andrzej Hajda
@ 2015-11-02  6:28       ` Archit Taneja
  2015-11-02 10:42         ` Andrzej Hajda
  0 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-11-02  6:28 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula



On 10/30/2015 07:51 PM, Andrzej Hajda wrote:
> On 10/06/2015 11:24 AM, Archit Taneja wrote:
>> A driver calling mipi_dsi_device_new might want to unregister the device
>> once it's done. It might also require it in an error handling path in
>> case something didn't go right.
>>
>> When the dsi host driver calls mipi_dsi_host_unregister, the devices
>> created by both DT and and without DT will be removed. This does leave
>> the possibility of the host removing the dsi device without the
>> peripheral driver being aware of it. I don't know a good way to solve
>> this. Some suggestions here would be of help too.
> The 2nd paragraph is not relevant here. It is another issue. Some comments
> about it:

Yes, it's probably not the best to put it in the commit message of this
patch.

> I am not sure, but I guess device should not be removed if it is refcounted
> properly, it will be just detached from the driver, bus and system (whatever it
> means:) ).
> It does not mean it will be usable and probably some races can occur anyway.
> I guess i2c and other buses have the same problem, am I right?

I was concerned about one particular sequence:

1) DSI host driver calls mipi_dsi_host_unregister: All dsi devices would 
be unregistered.

2) dsi device driver calls mipi_dsi_device_unregister: This will try to
unregister our dsi device

The problem here is that the device will cease to exist after step (1)
itself, because the refcount of our device will never be 2.

mipi_dsi_host_register() will only register devices represented in DT,
not the one the drivers register manually.

In other words, the dsi pointer in our driver will point to nothing 
valid after mipi_dsi_host_unregister is called.

As you said, I guess this exists in other buses too, and it's the
drivers job to not use them.

>
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 7 +++++++
>>   include/drm/drm_mipi_dsi.h     | 2 ++
>>   2 files changed, 9 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index db6130a..cbb7373 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -183,6 +183,13 @@ err:
>>   }
>>   EXPORT_SYMBOL(mipi_dsi_device_new);
>>
>> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
>> +{
>> +	if (dsi)
>> +		device_unregister(&dsi->dev);
>> +}
>> +EXPORT_SYMBOL(mipi_dsi_device_unregister);
>> +
> I guess NULL check can be removed and the whole function can be inlined.

Yeah, this check won't help anyway.

I think I'll mention that drivers should use this only in error
handling paths, and not in the driver's remove() op.

I'll also change this to inlined.

Archit

>
> Regards
> Andrzej
>>   static struct mipi_dsi_device *
>>   of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>   {
>> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
>> index 93dec7b..68f49f4 100644
>> --- a/include/drm/drm_mipi_dsi.h
>> +++ b/include/drm/drm_mipi_dsi.h
>> @@ -197,6 +197,8 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>>
>>   struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>   					    struct mipi_dsi_device_info *info);
>> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
>> +
>>   /**
>>    * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
>>    * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device
  2015-11-02  6:28       ` Archit Taneja
@ 2015-11-02 10:42         ` Andrzej Hajda
  2015-11-03  7:18           ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Andrzej Hajda @ 2015-11-02 10:42 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

On 11/02/2015 07:28 AM, Archit Taneja wrote:
>
> On 10/30/2015 07:51 PM, Andrzej Hajda wrote:
>> On 10/06/2015 11:24 AM, Archit Taneja wrote:
>>> A driver calling mipi_dsi_device_new might want to unregister the device
>>> once it's done. It might also require it in an error handling path in
>>> case something didn't go right.
>>>
>>> When the dsi host driver calls mipi_dsi_host_unregister, the devices
>>> created by both DT and and without DT will be removed. This does leave
>>> the possibility of the host removing the dsi device without the
>>> peripheral driver being aware of it. I don't know a good way to solve
>>> this. Some suggestions here would be of help too.
>> The 2nd paragraph is not relevant here. It is another issue. Some comments
>> about it:
> Yes, it's probably not the best to put it in the commit message of this
> patch.
>
>> I am not sure, but I guess device should not be removed if it is refcounted
>> properly, it will be just detached from the driver, bus and system (whatever it
>> means:) ).
>> It does not mean it will be usable and probably some races can occur anyway.
>> I guess i2c and other buses have the same problem, am I right?
> I was concerned about one particular sequence:
>
> 1) DSI host driver calls mipi_dsi_host_unregister: All dsi devices would 
> be unregistered.
>
> 2) dsi device driver calls mipi_dsi_device_unregister: This will try to
> unregister our dsi device
>
> The problem here is that the device will cease to exist after step (1)
> itself, because the refcount of our device will never be 2.
>
> mipi_dsi_host_register() will only register devices represented in DT,
> not the one the drivers register manually.
>
> In other words, the dsi pointer in our driver will point to nothing 
> valid after mipi_dsi_host_unregister is called.
>
> As you said, I guess this exists in other buses too, and it's the
> drivers job to not use them.

I think the whole problem is due to fact we try to use devices
as interfaces to some bus hosts (DSI in our case), these devices
are owned by bus host and we cannot control their lifetime from other code.
The best solution IMO would be to create separate lightweight framework
as I suggested in previous discussion[1]. It should be cleaner solution
without any 'dummy' proxy devices.
But even in this case we would need some callbacks to notify that the provider
is about to be removed.

2nd 'solution' is to leave it as is and pretend everything is OK,
as in case of other frameworks :)

Maybe it would be possible 3rd solution - we could use probe and remove callbacks
from dsi driver to notify clients about adding/removal of dsi device to/from bus.
So during dummy dsi dev creation we would provide some callbacks which would be
called
by dummy dsi driver probe/remove to notifiy client it can start/stop using dsi
device.
This crazy construction probably can work but looks insane :)

[1]: http://www.spinics.net/lists/linux-arm-msm/msg16945.html

Regards
Andrzej

>
>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>>> ---
>>>   drivers/gpu/drm/drm_mipi_dsi.c | 7 +++++++
>>>   include/drm/drm_mipi_dsi.h     | 2 ++
>>>   2 files changed, 9 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>>> index db6130a..cbb7373 100644
>>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>>> @@ -183,6 +183,13 @@ err:
>>>   }
>>>   EXPORT_SYMBOL(mipi_dsi_device_new);
>>>
>>> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
>>> +{
>>> +	if (dsi)
>>> +		device_unregister(&dsi->dev);
>>> +}
>>> +EXPORT_SYMBOL(mipi_dsi_device_unregister);
>>> +
>> I guess NULL check can be removed and the whole function can be inlined.
> Yeah, this check won't help anyway.
>
> I think I'll mention that drivers should use this only in error
> handling paths, and not in the driver's remove() op.
>
> I'll also change this to inlined.
>
> Archit
>
>> Regards
>> Andrzej
>>>   static struct mipi_dsi_device *
>>>   of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>>   {
>>> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
>>> index 93dec7b..68f49f4 100644
>>> --- a/include/drm/drm_mipi_dsi.h
>>> +++ b/include/drm/drm_mipi_dsi.h
>>> @@ -197,6 +197,8 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>>>
>>>   struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>>   					    struct mipi_dsi_device_info *info);
>>> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
>>> +
>>>   /**
>>>    * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
>>>    * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>


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

* Re: [RFC v2 5/5] drm/dsi: Get DSI host by DT device node
  2015-10-06  9:24   ` [RFC v2 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
  2015-10-06 10:00     ` kbuild test robot
@ 2015-11-02 10:50     ` Andrzej Hajda
  2015-11-03  7:20       ` Archit Taneja
  1 sibling, 1 reply; 84+ messages in thread
From: Andrzej Hajda @ 2015-11-02 10:50 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

On 10/06/2015 11:24 AM, Archit Taneja wrote:
> mipi_dsi_devices are inherently aware of their host because they
> share a parent-child hierarchy in the device tree.
>
> Non-dsi drivers that create a dummy dsi device don't have this data.
> In order to get this information, they require to a phandle to the dsi
> host in the device tree.
>
> Maintain a list of all the hosts DSI that are currently registered.
>
> This list will be used to find the mipi_dsi_host corresponding to the
> device_node passed in of_find_mipi_dsi_host_by_node.
>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>

Looks OK, beside lack of documentation, after fixing it you can add
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>

Regards
Andrzej

> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 30 ++++++++++++++++++++++++++++++
>  include/drm/drm_mipi_dsi.h     |  2 ++
>  2 files changed, 32 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index cbb7373..c51d73e 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -216,6 +216,28 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  	return mipi_dsi_device_new(host, &info);
>  }
>  
> +static DEFINE_MUTEX(host_lock);
> +static LIST_HEAD(host_list);
> +
> +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
> +{
> +	struct mipi_dsi_host *host;
> +
> +	mutex_lock(&host_lock);
> +
> +	list_for_each_entry(host, &host_list, list) {
> +		if (host->dev->of_node == node) {
> +			mutex_unlock(&host_lock);
> +			return host;
> +		}
> +	}
> +
> +	mutex_unlock(&host_lock);
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
> +
>  int mipi_dsi_host_register(struct mipi_dsi_host *host)
>  {
>  	struct device_node *node;
> @@ -227,6 +249,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
>  		of_mipi_dsi_device_add(host, node);
>  	}
>  
> +	mutex_lock(&host_lock);
> +	list_add_tail(&host->list, &host_list);
> +	mutex_unlock(&host_lock);
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(mipi_dsi_host_register);
> @@ -243,6 +269,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
>  void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
>  {
>  	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
> +
> +	mutex_lock(&host_lock);
> +	list_del_init(&host->list);
> +	mutex_unlock(&host_lock);
>  }
>  EXPORT_SYMBOL(mipi_dsi_host_unregister);
>  
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 68f49f4..15d3068 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -100,10 +100,12 @@ struct mipi_dsi_host_ops {
>  struct mipi_dsi_host {
>  	struct device *dev;
>  	const struct mipi_dsi_host_ops *ops;
> +	struct list_head list;
>  };
>  
>  int mipi_dsi_host_register(struct mipi_dsi_host *host);
>  void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
> +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
>  
>  /* DSI mode flags */
>  


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

* Re: [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device
  2015-11-02 10:42         ` Andrzej Hajda
@ 2015-11-03  7:18           ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-03  7:18 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula



On 11/02/2015 04:12 PM, Andrzej Hajda wrote:
> On 11/02/2015 07:28 AM, Archit Taneja wrote:
>>
>> On 10/30/2015 07:51 PM, Andrzej Hajda wrote:
>>> On 10/06/2015 11:24 AM, Archit Taneja wrote:
>>>> A driver calling mipi_dsi_device_new might want to unregister the device
>>>> once it's done. It might also require it in an error handling path in
>>>> case something didn't go right.
>>>>
>>>> When the dsi host driver calls mipi_dsi_host_unregister, the devices
>>>> created by both DT and and without DT will be removed. This does leave
>>>> the possibility of the host removing the dsi device without the
>>>> peripheral driver being aware of it. I don't know a good way to solve
>>>> this. Some suggestions here would be of help too.
>>> The 2nd paragraph is not relevant here. It is another issue. Some comments
>>> about it:
>> Yes, it's probably not the best to put it in the commit message of this
>> patch.
>>
>>> I am not sure, but I guess device should not be removed if it is refcounted
>>> properly, it will be just detached from the driver, bus and system (whatever it
>>> means:) ).
>>> It does not mean it will be usable and probably some races can occur anyway.
>>> I guess i2c and other buses have the same problem, am I right?
>> I was concerned about one particular sequence:
>>
>> 1) DSI host driver calls mipi_dsi_host_unregister: All dsi devices would
>> be unregistered.
>>
>> 2) dsi device driver calls mipi_dsi_device_unregister: This will try to
>> unregister our dsi device
>>
>> The problem here is that the device will cease to exist after step (1)
>> itself, because the refcount of our device will never be 2.
>>
>> mipi_dsi_host_register() will only register devices represented in DT,
>> not the one the drivers register manually.
>>
>> In other words, the dsi pointer in our driver will point to nothing
>> valid after mipi_dsi_host_unregister is called.
>>
>> As you said, I guess this exists in other buses too, and it's the
>> drivers job to not use them.
>
> I think the whole problem is due to fact we try to use devices
> as interfaces to some bus hosts (DSI in our case), these devices
> are owned by bus host and we cannot control their lifetime from other code.
> The best solution IMO would be to create separate lightweight framework
> as I suggested in previous discussion[1]. It should be cleaner solution
> without any 'dummy' proxy devices.
> But even in this case we would need some callbacks to notify that the provider
> is about to be removed.
>
> 2nd 'solution' is to leave it as is and pretend everything is OK,
> as in case of other frameworks :)
>
> Maybe it would be possible 3rd solution - we could use probe and remove callbacks
> from dsi driver to notify clients about adding/removal of dsi device to/from bus.
> So during dummy dsi dev creation we would provide some callbacks which would be
> called
> by dummy dsi driver probe/remove to notifiy client it can start/stop using dsi
> device.
> This crazy construction probably can work but looks insane :)
>
> [1]: http://www.spinics.net/lists/linux-arm-msm/msg16945.html

I'm okay with the 2nd solution :). We can add callbacks or a
notification mechanism if anyone needs it in the future.

Thanks,
Archit

>
> Regards
> Andrzej
>
>>
>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>>>> ---
>>>>    drivers/gpu/drm/drm_mipi_dsi.c | 7 +++++++
>>>>    include/drm/drm_mipi_dsi.h     | 2 ++
>>>>    2 files changed, 9 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>>>> index db6130a..cbb7373 100644
>>>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>>>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>>>> @@ -183,6 +183,13 @@ err:
>>>>    }
>>>>    EXPORT_SYMBOL(mipi_dsi_device_new);
>>>>
>>>> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
>>>> +{
>>>> +	if (dsi)
>>>> +		device_unregister(&dsi->dev);
>>>> +}
>>>> +EXPORT_SYMBOL(mipi_dsi_device_unregister);
>>>> +
>>> I guess NULL check can be removed and the whole function can be inlined.
>> Yeah, this check won't help anyway.
>>
>> I think I'll mention that drivers should use this only in error
>> handling paths, and not in the driver's remove() op.
>>
>> I'll also change this to inlined.
>>
>> Archit
>>
>>> Regards
>>> Andrzej
>>>>    static struct mipi_dsi_device *
>>>>    of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>>>    {
>>>> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
>>>> index 93dec7b..68f49f4 100644
>>>> --- a/include/drm/drm_mipi_dsi.h
>>>> +++ b/include/drm/drm_mipi_dsi.h
>>>> @@ -197,6 +197,8 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>>>>
>>>>    struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>>>    					    struct mipi_dsi_device_info *info);
>>>> +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
>>>> +
>>>>    /**
>>>>     * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
>>>>     * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [RFC v2 5/5] drm/dsi: Get DSI host by DT device node
  2015-11-02 10:50     ` Andrzej Hajda
@ 2015-11-03  7:20       ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-03  7:20 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula



On 11/02/2015 04:20 PM, Andrzej Hajda wrote:
> On 10/06/2015 11:24 AM, Archit Taneja wrote:
>> mipi_dsi_devices are inherently aware of their host because they
>> share a parent-child hierarchy in the device tree.
>>
>> Non-dsi drivers that create a dummy dsi device don't have this data.
>> In order to get this information, they require to a phandle to the dsi
>> host in the device tree.
>>
>> Maintain a list of all the hosts DSI that are currently registered.
>>
>> This list will be used to find the mipi_dsi_host corresponding to the
>> device_node passed in of_find_mipi_dsi_host_by_node.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>
> Looks OK, beside lack of documentation, after fixing it you can add
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>

I will add missing documentation before posting v3.

Thanks again for the review.

Archit

>
> Regards
> Andrzej
>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 30 ++++++++++++++++++++++++++++++
>>   include/drm/drm_mipi_dsi.h     |  2 ++
>>   2 files changed, 32 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index cbb7373..c51d73e 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -216,6 +216,28 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>   	return mipi_dsi_device_new(host, &info);
>>   }
>>
>> +static DEFINE_MUTEX(host_lock);
>> +static LIST_HEAD(host_list);
>> +
>> +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
>> +{
>> +	struct mipi_dsi_host *host;
>> +
>> +	mutex_lock(&host_lock);
>> +
>> +	list_for_each_entry(host, &host_list, list) {
>> +		if (host->dev->of_node == node) {
>> +			mutex_unlock(&host_lock);
>> +			return host;
>> +		}
>> +	}
>> +
>> +	mutex_unlock(&host_lock);
>> +
>> +	return NULL;
>> +}
>> +EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
>> +
>>   int mipi_dsi_host_register(struct mipi_dsi_host *host)
>>   {
>>   	struct device_node *node;
>> @@ -227,6 +249,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
>>   		of_mipi_dsi_device_add(host, node);
>>   	}
>>
>> +	mutex_lock(&host_lock);
>> +	list_add_tail(&host->list, &host_list);
>> +	mutex_unlock(&host_lock);
>> +
>>   	return 0;
>>   }
>>   EXPORT_SYMBOL(mipi_dsi_host_register);
>> @@ -243,6 +269,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
>>   void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
>>   {
>>   	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
>> +
>> +	mutex_lock(&host_lock);
>> +	list_del_init(&host->list);
>> +	mutex_unlock(&host_lock);
>>   }
>>   EXPORT_SYMBOL(mipi_dsi_host_unregister);
>>
>> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
>> index 68f49f4..15d3068 100644
>> --- a/include/drm/drm_mipi_dsi.h
>> +++ b/include/drm/drm_mipi_dsi.h
>> @@ -100,10 +100,12 @@ struct mipi_dsi_host_ops {
>>   struct mipi_dsi_host {
>>   	struct device *dev;
>>   	const struct mipi_dsi_host_ops *ops;
>> +	struct list_head list;
>>   };
>>
>>   int mipi_dsi_host_register(struct mipi_dsi_host *host);
>>   void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
>> +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
>>
>>   /* DSI mode flags */
>>
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus
  2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
                     ` (4 preceding siblings ...)
  2015-10-06  9:24   ` [RFC v2 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2015-11-30 12:01   ` Archit Taneja
  2015-11-30 12:01     ` [PATCH v3 1/5] drm/dsi: Refactor device creation Archit Taneja
                       ` (5 more replies)
  5 siblings, 6 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-30 12:01 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

We are currently restricted when it comes to supporting DSI on devices
that have a non-DSI control bus. For example, DSI encoder chips are
available in the market that are configured via i2c. Configuring their
registers via DSI bus is either optional or not available at all.

These devices still need to pass DSI parameters (data lanes, mode flags
etc) to the DSI host they are connected to. We don't have a way to do
that at the moment.

After some discussions on the previous RFC[1], we decided to support this
by providing additional API in drm_mipi_dsi which lets us create new DSI
devices without the need of them to have a DT node.

[1]: https://lkml.org/lkml/2015/6/30/42

Changes from v2 to v3:

- Incorporated misc comments by Andrzej. Changed from RFC to a PATCH set.
- Fixed htmldocs warnings.

Archit Taneja (5):
  drm/dsi: Refactor device creation
  drm/dsi: Try to match non-DT dsi devices
  drm/dsi: Check for used channels
  drm/dsi: Add routine to unregister dsi device
  drm/dsi: Get DSI host by DT device node

 drivers/gpu/drm/drm_mipi_dsi.c | 136 +++++++++++++++++++++++++++++++----------
 include/drm/drm_mipi_dsi.h     |  29 +++++++++
 2 files changed, 133 insertions(+), 32 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v3 1/5] drm/dsi: Refactor device creation
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
@ 2015-11-30 12:01     ` Archit Taneja
  2015-11-30 12:01     ` [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-30 12:01 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

Simplify the mipi dsi device creation process. device_initialize and
device_add don't need to be called separately when creating
mipi_dsi_device's. Use device_register instead to simplify things.

Create a helper function mipi_dsi_device_new which takes in struct
mipi_dsi_device_info and mipi_dsi_host. It clubs the functions
mipi_dsi_device_alloc and mipi_dsi_device_add into one.

mipi_dsi_device_info acts as a template to populate the dsi device
information. This is populated by of_mipi_dsi_device_add and passed to
mipi_dsi_device_new.

Later on, we'll provide mipi_dsi_device_new as a standalone way to create
a dsi device not available via DT.

The new device creation process tries to closely follow what's been done
in i2c_new_device in i2c-core.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 61 +++++++++++++++++-------------------------
 include/drm/drm_mipi_dsi.h     | 15 +++++++++++
 2 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 2d5ca8ee..82bcdcd 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -102,9 +102,18 @@ static const struct device_type mipi_dsi_device_type = {
 	.release = mipi_dsi_dev_release,
 };
 
-static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
+struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
+					    struct mipi_dsi_device_info *info)
 {
 	struct mipi_dsi_device *dsi;
+	struct device *dev = host->dev;
+	int ret;
+
+	if (info->reg > 3) {
+		dev_err(dev, "device node has invalid reg property: %u\n",
+			info->reg);
+		return ERR_PTR(-EINVAL);
+	}
 
 	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
 	if (!dsi)
@@ -114,26 +123,27 @@ static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
 	dsi->dev.bus = &mipi_dsi_bus_type;
 	dsi->dev.parent = host->dev;
 	dsi->dev.type = &mipi_dsi_device_type;
+	dsi->dev.of_node = info->node;
+	dsi->channel = info->reg;
 
-	device_initialize(&dsi->dev);
-
-	return dsi;
-}
-
-static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
-{
-	struct mipi_dsi_host *host = dsi->host;
+	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
-	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev),  dsi->channel);
+	ret = device_register(&dsi->dev);
+	if (ret) {
+		dev_err(dev, "failed to register device: %d\n", ret);
+		kfree(dsi);
+		return ERR_PTR(ret);
+	}
 
-	return device_add(&dsi->dev);
+	return dsi;
 }
+EXPORT_SYMBOL(mipi_dsi_device_new);
 
 static struct mipi_dsi_device *
 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 {
-	struct mipi_dsi_device *dsi;
 	struct device *dev = host->dev;
+	struct mipi_dsi_device_info info = { };
 	int ret;
 	u32 reg;
 
@@ -144,31 +154,10 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (reg > 3) {
-		dev_err(dev, "device node %s has invalid reg property: %u\n",
-			node->full_name, reg);
-		return ERR_PTR(-EINVAL);
-	}
-
-	dsi = mipi_dsi_device_alloc(host);
-	if (IS_ERR(dsi)) {
-		dev_err(dev, "failed to allocate DSI device %s: %ld\n",
-			node->full_name, PTR_ERR(dsi));
-		return dsi;
-	}
-
-	dsi->dev.of_node = of_node_get(node);
-	dsi->channel = reg;
+	info.reg = reg;
+	info.node = of_node_get(node);
 
-	ret = mipi_dsi_device_add(dsi);
-	if (ret) {
-		dev_err(dev, "failed to add DSI device %s: %d\n",
-			node->full_name, ret);
-		kfree(dsi);
-		return ERR_PTR(ret);
-	}
-
-	return dsi;
+	return mipi_dsi_device_new(host, &info);
 }
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index f1d8d0d..90f4f3c 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -140,6 +140,19 @@ enum mipi_dsi_pixel_format {
 };
 
 /**
+ * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @reg: DSI virtual channel assigned to peripheral
+ * @node: pointer to OF device node
+ *
+ * This is populated and passed to mipi_dsi_device_new to create a new
+ * DSI device
+ */
+struct mipi_dsi_device_info {
+	u32 reg;
+	struct device_node *node;
+};
+
+/**
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
@@ -174,6 +187,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
+struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
+					    struct mipi_dsi_device_info *info);
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
  2015-11-30 12:01     ` [PATCH v3 1/5] drm/dsi: Refactor device creation Archit Taneja
@ 2015-11-30 12:01     ` Archit Taneja
  2015-11-30 12:45       ` kbuild test robot
  2015-11-30 12:01     ` [PATCH v3 3/5] drm/dsi: Check for used channels Archit Taneja
                       ` (3 subsequent siblings)
  5 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-11-30 12:01 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

Add a device name field in mipi_dsi_device. This name is different from
the actual dev name (which is of the format "hostname.reg"). When the
device is created via DT, this name is set to the modalias string.
In the non-DT case, the driver creating the DSI device provides the
name by populating a filed in mipi_dsi_device_info.

Matching for DT case would be as it was before. For the non-DT case,
we compare the device and driver names. Other buses (like i2c/spi)
perform a non-DT match by comparing the device name and entries in the
driver's id_table. Such a mechanism isn't used for the dsi bus.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 25 ++++++++++++++++++++++++-
 include/drm/drm_mipi_dsi.h     |  6 ++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 82bcdcd..143cce4 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -45,9 +45,26 @@
  * subset of the MIPI DCS command set.
  */
 
+static const struct device_type mipi_dsi_device_type;
+
 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
 {
-	return of_driver_match_device(dev, drv);
+	struct mipi_dsi_device *dsi;
+
+	if (dev->type == &mipi_dsi_device_type)
+		dsi = to_mipi_dsi_device(dev);
+	else
+		return 0;
+
+	/* attempt OF style match */
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
+	/* compare dsi device and driver names */
+	if (!strcmp(dsi->name, drv->name))
+		return 1;
+
+	return 0;
 }
 
 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
@@ -125,6 +142,7 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 	dsi->dev.type = &mipi_dsi_device_type;
 	dsi->dev.of_node = info->node;
 	dsi->channel = info->reg;
+	strlcpy(dsi->name, info->type, sizeof(dsi->name));
 
 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
@@ -147,6 +165,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 	int ret;
 	u32 reg;
 
+	if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+		dev_err(dev, "modalias failure on %s\n", node->full_name);
+		return ERR_PTR(-EINVAL);
+	}
+
 	ret = of_property_read_u32(node, "reg", &reg);
 	if (ret) {
 		dev_err(dev, "device node %s has no valid reg property: %d\n",
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 90f4f3c..cb084af 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -139,8 +139,11 @@ enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB565,
 };
 
+#define DSI_DEV_NAME_SIZE		20
+
 /**
  * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @type: dsi peripheral chip type
  * @reg: DSI virtual channel assigned to peripheral
  * @node: pointer to OF device node
  *
@@ -148,6 +151,7 @@ enum mipi_dsi_pixel_format {
  * DSI device
  */
 struct mipi_dsi_device_info {
+	char type[DSI_DEV_NAME_SIZE];
 	u32 reg;
 	struct device_node *node;
 };
@@ -156,6 +160,7 @@ struct mipi_dsi_device_info {
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
+ * @name: dsi peripheral chip type
  * @channel: virtual channel assigned to the peripheral
  * @format: pixel format for video mode
  * @lanes: number of active data lanes
@@ -165,6 +170,7 @@ struct mipi_dsi_device {
 	struct mipi_dsi_host *host;
 	struct device dev;
 
+	char name[DSI_DEV_NAME_SIZE];
 	unsigned int channel;
 	unsigned int lanes;
 	enum mipi_dsi_pixel_format format;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v3 3/5] drm/dsi: Check for used channels
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
  2015-11-30 12:01     ` [PATCH v3 1/5] drm/dsi: Refactor device creation Archit Taneja
  2015-11-30 12:01     ` [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
@ 2015-11-30 12:01     ` Archit Taneja
  2015-11-30 12:01     ` [PATCH v3 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-30 12:01 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

We don't check whether a previously registered mipi_dsi_device under the
same host shares the same virtual channel.

Before registering, check if any of the registered devices doesn't
already have the same virtual channel.

This wasn't crucial when all the devices under a host were populated via
DT. Now that we also support creating devices manually, we could end up
in a situation where a driver tries to create a device with a virtual
channel already taken by a device populated in DT.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 143cce4..f73e434 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -119,6 +119,22 @@ static const struct device_type mipi_dsi_device_type = {
 	.release = mipi_dsi_dev_release,
 };
 
+static int __dsi_check_chan_busy(struct device *dev, void *data)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+	u32 *reg = data;
+
+	if (dsi && dsi->channel == *reg)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int mipi_dsi_check_chan_busy(struct mipi_dsi_host *host, u32 reg)
+{
+	return device_for_each_child(host->dev, &reg, __dsi_check_chan_busy);
+}
+
 struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 					    struct mipi_dsi_device_info *info)
 {
@@ -146,14 +162,20 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 
 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
+	ret = mipi_dsi_check_chan_busy(host, info->reg);
+	if (ret)
+		goto err;
+
 	ret = device_register(&dsi->dev);
 	if (ret) {
 		dev_err(dev, "failed to register device: %d\n", ret);
-		kfree(dsi);
-		return ERR_PTR(ret);
+		goto err;
 	}
 
 	return dsi;
+err:
+	kfree(dsi);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(mipi_dsi_device_new);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v3 4/5] drm/dsi: Add routine to unregister dsi device
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
                       ` (2 preceding siblings ...)
  2015-11-30 12:01     ` [PATCH v3 3/5] drm/dsi: Check for used channels Archit Taneja
@ 2015-11-30 12:01     ` Archit Taneja
  2015-11-30 12:34       ` Andrzej Hajda
  2015-11-30 12:01     ` [PATCH v3 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
  5 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-11-30 12:01 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

A driver calling mipi_dsi_device_new might want to unregister the device
once it's done. It might also require it in an error handling path in
case something didn't go right.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 include/drm/drm_mipi_dsi.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index cb084af..410d8b5 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -195,6 +195,11 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 
 struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 					    struct mipi_dsi_device_info *info);
+static inline void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
+{
+	device_unregister(&dsi->dev);
+}
+
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v3 5/5] drm/dsi: Get DSI host by DT device node
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
                       ` (3 preceding siblings ...)
  2015-11-30 12:01     ` [PATCH v3 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
@ 2015-11-30 12:01     ` Archit Taneja
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2015-11-30 12:01 UTC (permalink / raw)
  To: dri-devel, a.hajda
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

mipi_dsi_devices are inherently aware of their host because they
share a parent-child hierarchy in the device tree.

non-dsi drivers that create dsi device don't have this data. In order to
get this information, they require to a phandle to the dsi host in the
device tree.

Maintain a list of all the hosts DSI that are currently registered.

This list will be used to find the mipi_dsi_host corresponding to the
device_node passed in of_find_mipi_dsi_host_by_node.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 38 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     |  3 +++
 2 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index f73e434..e9c17e25 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -205,6 +205,36 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 	return mipi_dsi_device_new(host, &info);
 }
 
+static DEFINE_MUTEX(host_lock);
+static LIST_HEAD(host_list);
+
+/**
+ * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
+ *    device tree node
+ * @node: device tree node
+ *
+ * Return: A pointer to the MIPI DSI host corresponding to @np or NULL if no
+ *    such device exists (or has not been registered yet).
+ */
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
+{
+	struct mipi_dsi_host *host;
+
+	mutex_lock(&host_lock);
+
+	list_for_each_entry(host, &host_list, list) {
+		if (host->dev->of_node == node) {
+			mutex_unlock(&host_lock);
+			return host;
+		}
+	}
+
+	mutex_unlock(&host_lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
 	struct device_node *node;
@@ -216,6 +246,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
 		of_mipi_dsi_device_add(host, node);
 	}
 
+	mutex_lock(&host_lock);
+	list_add_tail(&host->list, &host_list);
+	mutex_unlock(&host_lock);
+
 	return 0;
 }
 EXPORT_SYMBOL(mipi_dsi_host_register);
@@ -232,6 +266,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
 {
 	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
+
+	mutex_lock(&host_lock);
+	list_del_init(&host->list);
+	mutex_unlock(&host_lock);
 }
 EXPORT_SYMBOL(mipi_dsi_host_unregister);
 
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 410d8b5..e5c1df9 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -96,14 +96,17 @@ struct mipi_dsi_host_ops {
  * struct mipi_dsi_host - DSI host device
  * @dev: driver model device node for this DSI host
  * @ops: DSI host operations
+ * @list: list management
  */
 struct mipi_dsi_host {
 	struct device *dev;
 	const struct mipi_dsi_host_ops *ops;
+	struct list_head list;
 };
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host);
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 
 /* DSI mode flags */
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* Re: [PATCH v3 4/5] drm/dsi: Add routine to unregister dsi device
  2015-11-30 12:01     ` [PATCH v3 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
@ 2015-11-30 12:34       ` Andrzej Hajda
  0 siblings, 0 replies; 84+ messages in thread
From: Andrzej Hajda @ 2015-11-30 12:34 UTC (permalink / raw)
  To: Archit Taneja, dri-devel
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

On 11/30/2015 01:01 PM, Archit Taneja wrote:
> A driver calling mipi_dsi_device_new might want to unregister the device
> once it's done. It might also require it in an error handling path in
> case something didn't go right.
>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>

Regards
Andrzej


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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-11-30 12:01     ` [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
@ 2015-11-30 12:45       ` kbuild test robot
  2015-12-07  5:29         ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: kbuild test robot @ 2015-11-30 12:45 UTC (permalink / raw)
  To: Archit Taneja
  Cc: kbuild-all, dri-devel, a.hajda, linux-kernel, airlied, daniel,
	treding, l.stach, robh, linux-arm-msm, jani.nikula,
	Archit Taneja

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

Hi Archit,

[auto build test ERROR on: v4.4-rc3]
[also build test ERROR on: next-20151127]

url:    https://github.com/0day-ci/linux/commits/Archit-Taneja/drm-dsi-DSI-for-devices-with-different-control-bus/20151130-200725
config: x86_64-allyesdebian (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/drm_mipi_dsi.c: In function 'of_mipi_dsi_device_add':
>> drivers/gpu/drm/drm_mipi_dsi.c:168:6: error: implicit declaration of function 'of_modalias_node' [-Werror=implicit-function-declaration]
     if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
         ^
   cc1: some warnings being treated as errors

vim +/of_modalias_node +168 drivers/gpu/drm/drm_mipi_dsi.c

   162	{
   163		struct device *dev = host->dev;
   164		struct mipi_dsi_device_info info = { };
   165		int ret;
   166		u32 reg;
   167	
 > 168		if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
   169			dev_err(dev, "modalias failure on %s\n", node->full_name);
   170			return ERR_PTR(-EINVAL);
   171		}

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

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 36065 bytes --]

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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-11-30 12:45       ` kbuild test robot
@ 2015-12-07  5:29         ` Archit Taneja
  2015-12-07  8:45           ` Jani Nikula
  0 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-07  5:29 UTC (permalink / raw)
  To: dri-devel, daniel
  Cc: a.hajda, linux-kernel, airlied, treding, l.stach, robh,
	linux-arm-msm, jani.nikula

Hi,

On 11/30/2015 06:15 PM, kbuild test robot wrote:
> Hi Archit,
>
> [auto build test ERROR on: v4.4-rc3]
> [also build test ERROR on: next-20151127]
>
> url:    https://github.com/0day-ci/linux/commits/Archit-Taneja/drm-dsi-DSI-for-devices-with-different-control-bus/20151130-200725
> config: x86_64-allyesdebian (attached as .config)
> reproduce:
>          # save the attached .config to linux build tree
>          make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>     drivers/gpu/drm/drm_mipi_dsi.c: In function 'of_mipi_dsi_device_add':
>>> drivers/gpu/drm/drm_mipi_dsi.c:168:6: error: implicit declaration of function 'of_modalias_node' [-Werror=implicit-function-declaration]
>       if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {

Any suggestions on how to fix this? Is it ok to make DRM_MIPI_DSI
depend on CONFIG_OF? Or is it better to wrap these funcs around
IF_ENABLED(CONFIG_OF)?

Archit

>           ^
>     cc1: some warnings being treated as errors
>
> vim +/of_modalias_node +168 drivers/gpu/drm/drm_mipi_dsi.c
>
>     162	{
>     163		struct device *dev = host->dev;
>     164		struct mipi_dsi_device_info info = { };
>     165		int ret;
>     166		u32 reg;
>     167	
>   > 168		if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
>     169			dev_err(dev, "modalias failure on %s\n", node->full_name);
>     170			return ERR_PTR(-EINVAL);
>     171		}
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-12-07  5:29         ` Archit Taneja
@ 2015-12-07  8:45           ` Jani Nikula
  2015-12-07  8:59             ` Archit Taneja
  2015-12-07 16:55             ` Rob Clark
  0 siblings, 2 replies; 84+ messages in thread
From: Jani Nikula @ 2015-12-07  8:45 UTC (permalink / raw)
  To: Archit Taneja, dri-devel, daniel
  Cc: a.hajda, linux-kernel, airlied, treding, l.stach, robh, linux-arm-msm

On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
> Hi,
>
> On 11/30/2015 06:15 PM, kbuild test robot wrote:
>> Hi Archit,
>>
>> [auto build test ERROR on: v4.4-rc3]
>> [also build test ERROR on: next-20151127]
>>
>> url:    https://github.com/0day-ci/linux/commits/Archit-Taneja/drm-dsi-DSI-for-devices-with-different-control-bus/20151130-200725
>> config: x86_64-allyesdebian (attached as .config)
>> reproduce:
>>          # save the attached .config to linux build tree
>>          make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>     drivers/gpu/drm/drm_mipi_dsi.c: In function 'of_mipi_dsi_device_add':
>>>> drivers/gpu/drm/drm_mipi_dsi.c:168:6: error: implicit declaration of function 'of_modalias_node' [-Werror=implicit-function-declaration]
>>       if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
>
> Any suggestions on how to fix this? Is it ok to make DRM_MIPI_DSI
> depend on CONFIG_OF?

Please don't.

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Technology Center

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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-12-07  8:45           ` Jani Nikula
@ 2015-12-07  8:59             ` Archit Taneja
  2015-12-07  9:10               ` Jani Nikula
  2015-12-07 16:55             ` Rob Clark
  1 sibling, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-07  8:59 UTC (permalink / raw)
  To: Jani Nikula, dri-devel, daniel
  Cc: a.hajda, linux-kernel, airlied, treding, l.stach, robh, linux-arm-msm



On 12/07/2015 02:15 PM, Jani Nikula wrote:
> On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
>> Hi,
>>
>> On 11/30/2015 06:15 PM, kbuild test robot wrote:
>>> Hi Archit,
>>>
>>> [auto build test ERROR on: v4.4-rc3]
>>> [also build test ERROR on: next-20151127]
>>>
>>> url:    https://github.com/0day-ci/linux/commits/Archit-Taneja/drm-dsi-DSI-for-devices-with-different-control-bus/20151130-200725
>>> config: x86_64-allyesdebian (attached as .config)
>>> reproduce:
>>>           # save the attached .config to linux build tree
>>>           make ARCH=x86_64
>>>
>>> All errors (new ones prefixed by >>):
>>>
>>>      drivers/gpu/drm/drm_mipi_dsi.c: In function 'of_mipi_dsi_device_add':
>>>>> drivers/gpu/drm/drm_mipi_dsi.c:168:6: error: implicit declaration of function 'of_modalias_node' [-Werror=implicit-function-declaration]
>>>        if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
>>
>> Any suggestions on how to fix this? Is it ok to make DRM_MIPI_DSI
>> depend on CONFIG_OF?
>
> Please don't.

Just curious, how did x86 use DSI if the only way to create DSI devices
until now was via DT?

Archit

>
> BR,
> Jani.
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-12-07  8:59             ` Archit Taneja
@ 2015-12-07  9:10               ` Jani Nikula
  2015-12-07  9:18                 ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Jani Nikula @ 2015-12-07  9:10 UTC (permalink / raw)
  To: Archit Taneja, dri-devel, daniel
  Cc: a.hajda, linux-kernel, airlied, treding, l.stach, robh, linux-arm-msm

On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
> On 12/07/2015 02:15 PM, Jani Nikula wrote:
>> On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
>>> Hi,
>>>
>>> On 11/30/2015 06:15 PM, kbuild test robot wrote:
>>>> Hi Archit,
>>>>
>>>> [auto build test ERROR on: v4.4-rc3]
>>>> [also build test ERROR on: next-20151127]
>>>>
>>>> url:    https://github.com/0day-ci/linux/commits/Archit-Taneja/drm-dsi-DSI-for-devices-with-different-control-bus/20151130-200725
>>>> config: x86_64-allyesdebian (attached as .config)
>>>> reproduce:
>>>>           # save the attached .config to linux build tree
>>>>           make ARCH=x86_64
>>>>
>>>> All errors (new ones prefixed by >>):
>>>>
>>>>      drivers/gpu/drm/drm_mipi_dsi.c: In function 'of_mipi_dsi_device_add':
>>>>>> drivers/gpu/drm/drm_mipi_dsi.c:168:6: error: implicit declaration of function 'of_modalias_node' [-Werror=implicit-function-declaration]
>>>>        if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
>>>
>>> Any suggestions on how to fix this? Is it ok to make DRM_MIPI_DSI
>>> depend on CONFIG_OF?
>>
>> Please don't.
>
> Just curious, how did x86 use DSI if the only way to create DSI devices
> until now was via DT?

Oh, you want the gory details... we use the DSI code as a library for
abstraction and helpers, without actually creating or registering the
devices.

BR,
Jani.


>
> Archit
>
>>
>> BR,
>> Jani.
>>

-- 
Jani Nikula, Intel Open Source Technology Center

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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-12-07  9:10               ` Jani Nikula
@ 2015-12-07  9:18                 ` Archit Taneja
  2015-12-07 10:07                   ` Jani Nikula
  0 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-07  9:18 UTC (permalink / raw)
  To: Jani Nikula, dri-devel, daniel
  Cc: a.hajda, linux-kernel, airlied, treding, l.stach, robh, linux-arm-msm



On 12/07/2015 02:40 PM, Jani Nikula wrote:
> On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
>> On 12/07/2015 02:15 PM, Jani Nikula wrote:
>>> On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
>>>> Hi,
>>>>
>>>> On 11/30/2015 06:15 PM, kbuild test robot wrote:
>>>>> Hi Archit,
>>>>>
>>>>> [auto build test ERROR on: v4.4-rc3]
>>>>> [also build test ERROR on: next-20151127]
>>>>>
>>>>> url:    https://github.com/0day-ci/linux/commits/Archit-Taneja/drm-dsi-DSI-for-devices-with-different-control-bus/20151130-200725
>>>>> config: x86_64-allyesdebian (attached as .config)
>>>>> reproduce:
>>>>>            # save the attached .config to linux build tree
>>>>>            make ARCH=x86_64
>>>>>
>>>>> All errors (new ones prefixed by >>):
>>>>>
>>>>>       drivers/gpu/drm/drm_mipi_dsi.c: In function 'of_mipi_dsi_device_add':
>>>>>>> drivers/gpu/drm/drm_mipi_dsi.c:168:6: error: implicit declaration of function 'of_modalias_node' [-Werror=implicit-function-declaration]
>>>>>         if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
>>>>
>>>> Any suggestions on how to fix this? Is it ok to make DRM_MIPI_DSI
>>>> depend on CONFIG_OF?
>>>
>>> Please don't.
>>
>> Just curious, how did x86 use DSI if the only way to create DSI devices
>> until now was via DT?
>
> Oh, you want the gory details... we use the DSI code as a library for
> abstraction and helpers, without actually creating or registering the
> devices.

Okay, got it. I'll go with the IS_ENABLED(CONFIG_OF) approach.

Humble request: Next time if I share something that doesn't make sense, 
please reply with something more than a "Please don't". That just sounds
condescending and doesn't really help me with my cause either.

Thanks,
Archit

>
> BR,
> Jani.
>
>
>>
>> Archit
>>
>>>
>>> BR,
>>> Jani.
>>>
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-12-07  9:18                 ` Archit Taneja
@ 2015-12-07 10:07                   ` Jani Nikula
  0 siblings, 0 replies; 84+ messages in thread
From: Jani Nikula @ 2015-12-07 10:07 UTC (permalink / raw)
  To: Archit Taneja, dri-devel, daniel
  Cc: a.hajda, linux-kernel, airlied, treding, l.stach, robh, linux-arm-msm

On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
> On 12/07/2015 02:40 PM, Jani Nikula wrote:
>> On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
>>> On 12/07/2015 02:15 PM, Jani Nikula wrote:
>>>> On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
>>>>> Any suggestions on how to fix this? Is it ok to make DRM_MIPI_DSI
>>>>> depend on CONFIG_OF?
>>>>
>>>> Please don't.
>>>
>>> Just curious, how did x86 use DSI if the only way to create DSI devices
>>> until now was via DT?
>>
>> Oh, you want the gory details... we use the DSI code as a library for
>> abstraction and helpers, without actually creating or registering the
>> devices.
>
> Okay, got it. I'll go with the IS_ENABLED(CONFIG_OF) approach.

Thanks, appreciated, so i915 doesn't need to depend on OF.

> Humble request: Next time if I share something that doesn't make sense, 
> please reply with something more than a "Please don't". That just sounds
> condescending and doesn't really help me with my cause either.

That's a fair request, no need to be humble about it. Apologies.

BR,
Jani.


-- 
Jani Nikula, Intel Open Source Technology Center

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

* Re: [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices
  2015-12-07  8:45           ` Jani Nikula
  2015-12-07  8:59             ` Archit Taneja
@ 2015-12-07 16:55             ` Rob Clark
  1 sibling, 0 replies; 84+ messages in thread
From: Rob Clark @ 2015-12-07 16:55 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Archit Taneja, dri-devel, Daniel Vetter, linux-arm-msm,
	Linux Kernel Mailing List, Andrzej Hajda, Thierry Reding

On Mon, Dec 7, 2015 at 3:45 AM, Jani Nikula <jani.nikula@linux.intel.com> wrote:
> On Mon, 07 Dec 2015, Archit Taneja <architt@codeaurora.org> wrote:
>> Hi,
>>
>> On 11/30/2015 06:15 PM, kbuild test robot wrote:
>>> Hi Archit,
>>>
>>> [auto build test ERROR on: v4.4-rc3]
>>> [also build test ERROR on: next-20151127]
>>>
>>> url:    https://github.com/0day-ci/linux/commits/Archit-Taneja/drm-dsi-DSI-for-devices-with-different-control-bus/20151130-200725
>>> config: x86_64-allyesdebian (attached as .config)
>>> reproduce:
>>>          # save the attached .config to linux build tree
>>>          make ARCH=x86_64
>>>
>>> All errors (new ones prefixed by >>):
>>>
>>>     drivers/gpu/drm/drm_mipi_dsi.c: In function 'of_mipi_dsi_device_add':
>>>>> drivers/gpu/drm/drm_mipi_dsi.c:168:6: error: implicit declaration of function 'of_modalias_node' [-Werror=implicit-function-declaration]
>>>       if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
>>
>> Any suggestions on how to fix this? Is it ok to make DRM_MIPI_DSI
>> depend on CONFIG_OF?
>
> Please don't.

I assume you are not using of_mipi_dsi_device_add()?  We could just
put this one fxn inside #ifdef CONFIG_OF / #endif, I think..

BR,
-R

> BR,
> Jani.
>
> --
> Jani Nikula, Intel Open Source Technology Center
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus
  2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
                       ` (4 preceding siblings ...)
  2015-11-30 12:01     ` [PATCH v3 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2015-12-10 12:41     ` Archit Taneja
  2015-12-10 12:41       ` [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
                         ` (7 more replies)
  5 siblings, 8 replies; 84+ messages in thread
From: Archit Taneja @ 2015-12-10 12:41 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, Archit Taneja

We are currently restricted when it comes to supporting DSI on devices
that have a non-DSI control bus. For example, DSI encoder chips are
available in the market that are configured via i2c. Configuring their
registers via DSI bus is either optional or not available at all.

These devices still need to pass DSI parameters (data lanes, mode flags
etc) to the DSI host they are connected to. We don't have a way to do
that at the moment.

After some discussions on the previous RFC[1], we decided to support this
by providing additional API in drm_mipi_dsi which lets us create new DSI
devices without the need of them to have a DT node.

[1]: https://lkml.org/lkml/2015/6/30/42

Changes in v4:
- Added a new patch that fixes build issues when CONFIG_OF is not set.

Changes in v3:

- Incorporated misc comments by Andrzej. Changed from RFC to a PATCH set.
- Fixed htmldocs warnings.

Archit Taneja (6):
  drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
  drm/dsi: Refactor device creation
  drm/dsi: Try to match non-DT dsi devices
  drm/dsi: Check for used channels
  drm/dsi: Add routine to unregister dsi device
  drm/dsi: Get DSI host by DT device node

 drivers/gpu/drm/drm_mipi_dsi.c | 144 ++++++++++++++++++++++++++++++++---------
 include/drm/drm_mipi_dsi.h     |  29 +++++++++
 2 files changed, 141 insertions(+), 32 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
@ 2015-12-10 12:41       ` Archit Taneja
  2016-01-21 15:31         ` Thierry Reding
  2015-12-10 12:41       ` [PATCH v4 2/6] drm/dsi: Refactor device creation Archit Taneja
                         ` (6 subsequent siblings)
  7 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-10 12:41 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, Archit Taneja

of_mipi_dsi_device_add is used only when CONFIG_OF is enabled. It
currently works if OF support is disabled, but this will change
when we add more functionality to it.

Define the original func if CONFIG_OF is enabled. Define a dummy func
otherwise.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 2d5ca8ee..bced235 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -129,6 +129,7 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
 	return device_add(&dsi->dev);
 }
 
+#if IS_ENABLED(CONFIG_OF)
 static struct mipi_dsi_device *
 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 {
@@ -170,6 +171,13 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 
 	return dsi;
 }
+#else
+static struct mipi_dsi_device *
+of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
+{
+	return NULL;
+}
+#endif
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v4 2/6] drm/dsi: Refactor device creation
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
  2015-12-10 12:41       ` [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
@ 2015-12-10 12:41       ` Archit Taneja
  2016-01-21 15:46         ` Thierry Reding
  2015-12-10 12:41       ` [PATCH v4 3/6] drm/dsi: Try to match non-DT dsi devices Archit Taneja
                         ` (5 subsequent siblings)
  7 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-10 12:41 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, Archit Taneja

Simplify the mipi dsi device creation process. device_initialize and
device_add don't need to be called separately when creating
mipi_dsi_device's. Use device_register instead to simplify things.

Create a helper function mipi_dsi_device_new which takes in struct
mipi_dsi_device_info and mipi_dsi_host. It clubs the functions
mipi_dsi_device_alloc and mipi_dsi_device_add into one.

mipi_dsi_device_info acts as a template to populate the dsi device
information. This is populated by of_mipi_dsi_device_add and passed to
mipi_dsi_device_new.

Later on, we'll provide mipi_dsi_device_new as a standalone way to create
a dsi device not available via DT.

The new device creation process tries to closely follow what's been done
in i2c_new_device in i2c-core.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 61 +++++++++++++++++-------------------------
 include/drm/drm_mipi_dsi.h     | 15 +++++++++++
 2 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index bced235..9434585 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -102,9 +102,18 @@ static const struct device_type mipi_dsi_device_type = {
 	.release = mipi_dsi_dev_release,
 };
 
-static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
+struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
+					    struct mipi_dsi_device_info *info)
 {
 	struct mipi_dsi_device *dsi;
+	struct device *dev = host->dev;
+	int ret;
+
+	if (info->reg > 3) {
+		dev_err(dev, "device node has invalid reg property: %u\n",
+			info->reg);
+		return ERR_PTR(-EINVAL);
+	}
 
 	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
 	if (!dsi)
@@ -114,27 +123,28 @@ static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
 	dsi->dev.bus = &mipi_dsi_bus_type;
 	dsi->dev.parent = host->dev;
 	dsi->dev.type = &mipi_dsi_device_type;
+	dsi->dev.of_node = info->node;
+	dsi->channel = info->reg;
 
-	device_initialize(&dsi->dev);
-
-	return dsi;
-}
-
-static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
-{
-	struct mipi_dsi_host *host = dsi->host;
+	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
-	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev),  dsi->channel);
+	ret = device_register(&dsi->dev);
+	if (ret) {
+		dev_err(dev, "failed to register device: %d\n", ret);
+		kfree(dsi);
+		return ERR_PTR(ret);
+	}
 
-	return device_add(&dsi->dev);
+	return dsi;
 }
+EXPORT_SYMBOL(mipi_dsi_device_new);
 
 #if IS_ENABLED(CONFIG_OF)
 static struct mipi_dsi_device *
 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 {
-	struct mipi_dsi_device *dsi;
 	struct device *dev = host->dev;
+	struct mipi_dsi_device_info info = { };
 	int ret;
 	u32 reg;
 
@@ -145,31 +155,10 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (reg > 3) {
-		dev_err(dev, "device node %s has invalid reg property: %u\n",
-			node->full_name, reg);
-		return ERR_PTR(-EINVAL);
-	}
-
-	dsi = mipi_dsi_device_alloc(host);
-	if (IS_ERR(dsi)) {
-		dev_err(dev, "failed to allocate DSI device %s: %ld\n",
-			node->full_name, PTR_ERR(dsi));
-		return dsi;
-	}
-
-	dsi->dev.of_node = of_node_get(node);
-	dsi->channel = reg;
+	info.reg = reg;
+	info.node = of_node_get(node);
 
-	ret = mipi_dsi_device_add(dsi);
-	if (ret) {
-		dev_err(dev, "failed to add DSI device %s: %d\n",
-			node->full_name, ret);
-		kfree(dsi);
-		return ERR_PTR(ret);
-	}
-
-	return dsi;
+	return mipi_dsi_device_new(host, &info);
 }
 #else
 static struct mipi_dsi_device *
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index f1d8d0d..90f4f3c 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -140,6 +140,19 @@ enum mipi_dsi_pixel_format {
 };
 
 /**
+ * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @reg: DSI virtual channel assigned to peripheral
+ * @node: pointer to OF device node
+ *
+ * This is populated and passed to mipi_dsi_device_new to create a new
+ * DSI device
+ */
+struct mipi_dsi_device_info {
+	u32 reg;
+	struct device_node *node;
+};
+
+/**
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
@@ -174,6 +187,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
+struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
+					    struct mipi_dsi_device_info *info);
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v4 3/6] drm/dsi: Try to match non-DT dsi devices
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
  2015-12-10 12:41       ` [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
  2015-12-10 12:41       ` [PATCH v4 2/6] drm/dsi: Refactor device creation Archit Taneja
@ 2015-12-10 12:41       ` Archit Taneja
  2016-01-21 16:05         ` Thierry Reding
  2015-12-10 12:41       ` [PATCH v4 4/6] drm/dsi: Check for used channels Archit Taneja
                         ` (4 subsequent siblings)
  7 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-10 12:41 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, Archit Taneja

Add a device name field in mipi_dsi_device. This name is different from
the actual dev name (which is of the format "hostname.reg"). When the
device is created via DT, this name is set to the modalias string.
In the non-DT case, the driver creating the DSI device provides the
name by populating a filed in mipi_dsi_device_info.

Matching for DT case would be as it was before. For the non-DT case,
we compare the device and driver names. Other buses (like i2c/spi)
perform a non-DT match by comparing the device name and entries in the
driver's id_table. Such a mechanism isn't used for the dsi bus.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 25 ++++++++++++++++++++++++-
 include/drm/drm_mipi_dsi.h     |  6 ++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 9434585..5a46802 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -45,9 +45,26 @@
  * subset of the MIPI DCS command set.
  */
 
+static const struct device_type mipi_dsi_device_type;
+
 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
 {
-	return of_driver_match_device(dev, drv);
+	struct mipi_dsi_device *dsi;
+
+	if (dev->type == &mipi_dsi_device_type)
+		dsi = to_mipi_dsi_device(dev);
+	else
+		return 0;
+
+	/* attempt OF style match */
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
+	/* compare dsi device and driver names */
+	if (!strcmp(dsi->name, drv->name))
+		return 1;
+
+	return 0;
 }
 
 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
@@ -125,6 +142,7 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 	dsi->dev.type = &mipi_dsi_device_type;
 	dsi->dev.of_node = info->node;
 	dsi->channel = info->reg;
+	strlcpy(dsi->name, info->type, sizeof(dsi->name));
 
 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
@@ -148,6 +166,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 	int ret;
 	u32 reg;
 
+	if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+		dev_err(dev, "modalias failure on %s\n", node->full_name);
+		return ERR_PTR(-EINVAL);
+	}
+
 	ret = of_property_read_u32(node, "reg", &reg);
 	if (ret) {
 		dev_err(dev, "device node %s has no valid reg property: %d\n",
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 90f4f3c..cb084af 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -139,8 +139,11 @@ enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB565,
 };
 
+#define DSI_DEV_NAME_SIZE		20
+
 /**
  * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @type: dsi peripheral chip type
  * @reg: DSI virtual channel assigned to peripheral
  * @node: pointer to OF device node
  *
@@ -148,6 +151,7 @@ enum mipi_dsi_pixel_format {
  * DSI device
  */
 struct mipi_dsi_device_info {
+	char type[DSI_DEV_NAME_SIZE];
 	u32 reg;
 	struct device_node *node;
 };
@@ -156,6 +160,7 @@ struct mipi_dsi_device_info {
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
+ * @name: dsi peripheral chip type
  * @channel: virtual channel assigned to the peripheral
  * @format: pixel format for video mode
  * @lanes: number of active data lanes
@@ -165,6 +170,7 @@ struct mipi_dsi_device {
 	struct mipi_dsi_host *host;
 	struct device dev;
 
+	char name[DSI_DEV_NAME_SIZE];
 	unsigned int channel;
 	unsigned int lanes;
 	enum mipi_dsi_pixel_format format;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v4 4/6] drm/dsi: Check for used channels
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
                         ` (2 preceding siblings ...)
  2015-12-10 12:41       ` [PATCH v4 3/6] drm/dsi: Try to match non-DT dsi devices Archit Taneja
@ 2015-12-10 12:41       ` Archit Taneja
  2016-01-21 16:11         ` Thierry Reding
  2015-12-10 12:41       ` [PATCH v4 5/6] drm/dsi: Add routine to unregister dsi device Archit Taneja
                         ` (3 subsequent siblings)
  7 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-10 12:41 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, Archit Taneja

We don't check whether a previously registered mipi_dsi_device under the
same host shares the same virtual channel.

Before registering, check if any of the registered devices doesn't
already have the same virtual channel.

This wasn't crucial when all the devices under a host were populated via
DT. Now that we also support creating devices manually, we could end up
in a situation where a driver tries to create a device with a virtual
channel already taken by a device populated in DT.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 5a46802..7a81171 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -119,6 +119,22 @@ static const struct device_type mipi_dsi_device_type = {
 	.release = mipi_dsi_dev_release,
 };
 
+static int __dsi_check_chan_busy(struct device *dev, void *data)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+	u32 *reg = data;
+
+	if (dsi && dsi->channel == *reg)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int mipi_dsi_check_chan_busy(struct mipi_dsi_host *host, u32 reg)
+{
+	return device_for_each_child(host->dev, &reg, __dsi_check_chan_busy);
+}
+
 struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 					    struct mipi_dsi_device_info *info)
 {
@@ -146,14 +162,20 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 
 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
 
+	ret = mipi_dsi_check_chan_busy(host, info->reg);
+	if (ret)
+		goto err;
+
 	ret = device_register(&dsi->dev);
 	if (ret) {
 		dev_err(dev, "failed to register device: %d\n", ret);
-		kfree(dsi);
-		return ERR_PTR(ret);
+		goto err;
 	}
 
 	return dsi;
+err:
+	kfree(dsi);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(mipi_dsi_device_new);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v4 5/6] drm/dsi: Add routine to unregister dsi device
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
                         ` (3 preceding siblings ...)
  2015-12-10 12:41       ` [PATCH v4 4/6] drm/dsi: Check for used channels Archit Taneja
@ 2015-12-10 12:41       ` Archit Taneja
  2016-01-21 16:12         ` Thierry Reding
  2015-12-10 12:41       ` [PATCH v4 6/6] drm/dsi: Get DSI host by DT device node Archit Taneja
                         ` (2 subsequent siblings)
  7 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-10 12:41 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, Archit Taneja

A driver calling mipi_dsi_device_new might want to unregister the device
once it's done. It might also require it in an error handling path in
case something didn't go right.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 include/drm/drm_mipi_dsi.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index cb084af..410d8b5 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -195,6 +195,11 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 
 struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
 					    struct mipi_dsi_device_info *info);
+static inline void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
+{
+	device_unregister(&dsi->dev);
+}
+
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* [PATCH v4 6/6] drm/dsi: Get DSI host by DT device node
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
                         ` (4 preceding siblings ...)
  2015-12-10 12:41       ` [PATCH v4 5/6] drm/dsi: Add routine to unregister dsi device Archit Taneja
@ 2015-12-10 12:41       ` Archit Taneja
  2016-01-21 16:16         ` Thierry Reding
  2016-01-05  5:29       ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
  7 siblings, 1 reply; 84+ messages in thread
From: Archit Taneja @ 2015-12-10 12:41 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula
  Cc: linux-kernel, airlied, daniel, treding, l.stach, robh,
	linux-arm-msm, Archit Taneja

mipi_dsi_devices are inherently aware of their host because they
share a parent-child hierarchy in the device tree.

non-dsi drivers that create dsi device don't have this data. In order to
get this information, they require to a phandle to the dsi host in the
device tree.

Maintain a list of all the hosts DSI that are currently registered.

This list will be used to find the mipi_dsi_host corresponding to the
device_node passed in of_find_mipi_dsi_host_by_node.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 38 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     |  3 +++
 2 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 7a81171..e40a665 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -213,6 +213,36 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 }
 #endif
 
+static DEFINE_MUTEX(host_lock);
+static LIST_HEAD(host_list);
+
+/**
+ * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
+ *    device tree node
+ * @node: device tree node
+ *
+ * Return: A pointer to the MIPI DSI host corresponding to @np or NULL if no
+ *    such device exists (or has not been registered yet).
+ */
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
+{
+	struct mipi_dsi_host *host;
+
+	mutex_lock(&host_lock);
+
+	list_for_each_entry(host, &host_list, list) {
+		if (host->dev->of_node == node) {
+			mutex_unlock(&host_lock);
+			return host;
+		}
+	}
+
+	mutex_unlock(&host_lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
 	struct device_node *node;
@@ -224,6 +254,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
 		of_mipi_dsi_device_add(host, node);
 	}
 
+	mutex_lock(&host_lock);
+	list_add_tail(&host->list, &host_list);
+	mutex_unlock(&host_lock);
+
 	return 0;
 }
 EXPORT_SYMBOL(mipi_dsi_host_register);
@@ -240,6 +274,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
 {
 	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
+
+	mutex_lock(&host_lock);
+	list_del_init(&host->list);
+	mutex_unlock(&host_lock);
 }
 EXPORT_SYMBOL(mipi_dsi_host_unregister);
 
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 410d8b5..e5c1df9 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -96,14 +96,17 @@ struct mipi_dsi_host_ops {
  * struct mipi_dsi_host - DSI host device
  * @dev: driver model device node for this DSI host
  * @ops: DSI host operations
+ * @list: list management
  */
 struct mipi_dsi_host {
 	struct device *dev;
 	const struct mipi_dsi_host_ops *ops;
+	struct list_head list;
 };
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host);
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 
 /* DSI mode flags */
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


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

* Re: [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
                         ` (5 preceding siblings ...)
  2015-12-10 12:41       ` [PATCH v4 6/6] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2016-01-05  5:29       ` Archit Taneja
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
  7 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-01-05  5:29 UTC (permalink / raw)
  To: dri-devel, a.hajda, jani.nikula, treding
  Cc: linux-kernel, airlied, daniel, l.stach, robh, linux-arm-msm

Hi Thierry,

Can you pick up these DSI patches, or would it make more sense for
these to go via someone else?

Thanks,
Archit

On 12/10/2015 06:11 PM, Archit Taneja wrote:
> We are currently restricted when it comes to supporting DSI on devices
> that have a non-DSI control bus. For example, DSI encoder chips are
> available in the market that are configured via i2c. Configuring their
> registers via DSI bus is either optional or not available at all.
>
> These devices still need to pass DSI parameters (data lanes, mode flags
> etc) to the DSI host they are connected to. We don't have a way to do
> that at the moment.
>
> After some discussions on the previous RFC[1], we decided to support this
> by providing additional API in drm_mipi_dsi which lets us create new DSI
> devices without the need of them to have a DT node.
>
> [1]: https://lkml.org/lkml/2015/6/30/42
>
> Changes in v4:
> - Added a new patch that fixes build issues when CONFIG_OF is not set.
>
> Changes in v3:
>
> - Incorporated misc comments by Andrzej. Changed from RFC to a PATCH set.
> - Fixed htmldocs warnings.
>
> Archit Taneja (6):
>    drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
>    drm/dsi: Refactor device creation
>    drm/dsi: Try to match non-DT dsi devices
>    drm/dsi: Check for used channels
>    drm/dsi: Add routine to unregister dsi device
>    drm/dsi: Get DSI host by DT device node
>
>   drivers/gpu/drm/drm_mipi_dsi.c | 144 ++++++++++++++++++++++++++++++++---------
>   include/drm/drm_mipi_dsi.h     |  29 +++++++++
>   2 files changed, 141 insertions(+), 32 deletions(-)
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
  2015-12-10 12:41       ` [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
@ 2016-01-21 15:31         ` Thierry Reding
  2016-01-26 14:59           ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2016-01-21 15:31 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm

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

On Thu, Dec 10, 2015 at 06:11:35PM +0530, Archit Taneja wrote:
> of_mipi_dsi_device_add is used only when CONFIG_OF is enabled. It
> currently works if OF support is disabled, but this will change
> when we add more functionality to it.
> 
> Define the original func if CONFIG_OF is enabled. Define a dummy func
> otherwise.
> 
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 2d5ca8ee..bced235 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -129,6 +129,7 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
>  	return device_add(&dsi->dev);
>  }
>  
> +#if IS_ENABLED(CONFIG_OF)
>  static struct mipi_dsi_device *
>  of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  {
> @@ -170,6 +171,13 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  
>  	return dsi;
>  }
> +#else
> +static struct mipi_dsi_device *
> +of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
> +{
> +	return NULL;
> +}
> +#endif

The OF implementation of this function never returns NULL, so perhaps
this should return an ERR_PTR()-encoded error code instead? This isn't
really important because we never check the return value in the one
call-site that we have, which I guess could be an argument for removing
the return value altogether...

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v4 2/6] drm/dsi: Refactor device creation
  2015-12-10 12:41       ` [PATCH v4 2/6] drm/dsi: Refactor device creation Archit Taneja
@ 2016-01-21 15:46         ` Thierry Reding
  2016-01-26 17:05           ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2016-01-21 15:46 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm

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

On Thu, Dec 10, 2015 at 06:11:36PM +0530, Archit Taneja wrote:
> Simplify the mipi dsi device creation process. device_initialize and

"MIPI" and "DSI", please.

> device_add don't need to be called separately when creating
> mipi_dsi_device's. Use device_register instead to simplify things.
> 
> Create a helper function mipi_dsi_device_new which takes in struct
> mipi_dsi_device_info and mipi_dsi_host. It clubs the functions
> mipi_dsi_device_alloc and mipi_dsi_device_add into one.
> 
> mipi_dsi_device_info acts as a template to populate the dsi device
> information. This is populated by of_mipi_dsi_device_add and passed to
> mipi_dsi_device_new.
> 
> Later on, we'll provide mipi_dsi_device_new as a standalone way to create
> a dsi device not available via DT.
> 
> The new device creation process tries to closely follow what's been done
> in i2c_new_device in i2c-core.
> 
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 61 +++++++++++++++++-------------------------
>  include/drm/drm_mipi_dsi.h     | 15 +++++++++++
>  2 files changed, 40 insertions(+), 36 deletions(-)

To be honest, I'm not sure I like this. If you want to have a simpler
helper, why not implement it using the lower-level helpers. Really the
only thing you're doing here is add a high-level helper that takes an
info struct, whereas previously the same would be done by storing the
info directly in the structure between allocation and addition of the
device.

Initially the implementation was following that of platform devices, I
see no reason to deviate from that. What you want here can easily be
done by something like:

	struct mipi_dsi_device *
	mipi_dsi_device_register_full(struct mipi_dsi_host *host,
				      const struct mipi_dsi_device_info *info)
	{
		struct mipi_dsi_device *dsi;

		dsi = mipi_dsi_device_alloc(host);
		if (IS_ERR(dsi))
			return dsi;

		dsi->dev.of_node = info->node;
		dsi->channel = info->channel;

		err = mipi_dsi_device_add(dsi);
		if (err < 0) {
			...
		}

		return dsi;
	}

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v4 3/6] drm/dsi: Try to match non-DT dsi devices
  2015-12-10 12:41       ` [PATCH v4 3/6] drm/dsi: Try to match non-DT dsi devices Archit Taneja
@ 2016-01-21 16:05         ` Thierry Reding
  2016-01-26 18:04           ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2016-01-21 16:05 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm

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

On Thu, Dec 10, 2015 at 06:11:37PM +0530, Archit Taneja wrote:
> Add a device name field in mipi_dsi_device. This name is different from
> the actual dev name (which is of the format "hostname.reg"). When the
> device is created via DT, this name is set to the modalias string.

Why? What's the use of setting this to the modalias string?

> In the non-DT case, the driver creating the DSI device provides the
> name by populating a filed in mipi_dsi_device_info.
> 
> Matching for DT case would be as it was before. For the non-DT case,
> we compare the device and driver names. Other buses (like i2c/spi)

"I2C" and "SPI", please.

> perform a non-DT match by comparing the device name and entries in the
> driver's id_table. Such a mechanism isn't used for the dsi bus.

"DSI", please.

> 
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 25 ++++++++++++++++++++++++-
>  include/drm/drm_mipi_dsi.h     |  6 ++++++
>  2 files changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 9434585..5a46802 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -45,9 +45,26 @@
>   * subset of the MIPI DCS command set.
>   */
>  
> +static const struct device_type mipi_dsi_device_type;
> +
>  static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
>  {
> -	return of_driver_match_device(dev, drv);
> +	struct mipi_dsi_device *dsi;
> +
> +	if (dev->type == &mipi_dsi_device_type)
> +		dsi = to_mipi_dsi_device(dev);
> +	else
> +		return 0;

I think this check is redundant. I'm not aware of any case where the bus
->match() callback is called on a device that isn't on said bus.

> +	/* attempt OF style match */
> +	if (of_driver_match_device(dev, drv))
> +		return 1;
> +
> +	/* compare dsi device and driver names */

"DSI", please.

> +	if (!strcmp(dsi->name, drv->name))
> +		return 1;
> +
> +	return 0;
>  }
>  
>  static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
> @@ -125,6 +142,7 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>  	dsi->dev.type = &mipi_dsi_device_type;
>  	dsi->dev.of_node = info->node;
>  	dsi->channel = info->reg;
> +	strlcpy(dsi->name, info->type, sizeof(dsi->name));

Don't you need to check info->type != NULL before doing this?

>  
>  	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
>  
> @@ -148,6 +166,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>  	int ret;
>  	u32 reg;
>  
> +	if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
> +		dev_err(dev, "modalias failure on %s\n", node->full_name);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
>  	ret = of_property_read_u32(node, "reg", &reg);
>  	if (ret) {
>  		dev_err(dev, "device node %s has no valid reg property: %d\n",
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 90f4f3c..cb084af 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -139,8 +139,11 @@ enum mipi_dsi_pixel_format {
>  	MIPI_DSI_FMT_RGB565,
>  };
>  
> +#define DSI_DEV_NAME_SIZE		20
> +
>  /**
>   * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
> + * @type: dsi peripheral chip type
>   * @reg: DSI virtual channel assigned to peripheral
>   * @node: pointer to OF device node
>   *
> @@ -148,6 +151,7 @@ enum mipi_dsi_pixel_format {
>   * DSI device
>   */
>  struct mipi_dsi_device_info {
> +	char type[DSI_DEV_NAME_SIZE];

Why limit ourselves to 20 characters? And why even so complicated? Isn't
the type always static when someone specifies this? Couldn't we simply
use a const char *name here instead?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v4 4/6] drm/dsi: Check for used channels
  2015-12-10 12:41       ` [PATCH v4 4/6] drm/dsi: Check for used channels Archit Taneja
@ 2016-01-21 16:11         ` Thierry Reding
  2016-01-27  5:16           ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2016-01-21 16:11 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm

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

On Thu, Dec 10, 2015 at 06:11:38PM +0530, Archit Taneja wrote:
> We don't check whether a previously registered mipi_dsi_device under the
> same host shares the same virtual channel.
> 
> Before registering, check if any of the registered devices doesn't
> already have the same virtual channel.
> 
> This wasn't crucial when all the devices under a host were populated via
> DT. Now that we also support creating devices manually, we could end up
> in a situation where a driver tries to create a device with a virtual
> channel already taken by a device populated in DT.
> 
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)

I don't think this is necessary. The device name will be composed of the
host's name, a '.' and the virtual channel ID, and the device core will
refuse to create two devices with the same name.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v4 5/6] drm/dsi: Add routine to unregister dsi device
  2015-12-10 12:41       ` [PATCH v4 5/6] drm/dsi: Add routine to unregister dsi device Archit Taneja
@ 2016-01-21 16:12         ` Thierry Reding
  2016-01-27  5:20           ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2016-01-21 16:12 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm

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

On Thu, Dec 10, 2015 at 06:11:39PM +0530, Archit Taneja wrote:
> A driver calling mipi_dsi_device_new might want to unregister the device
> once it's done. It might also require it in an error handling path in
> case something didn't go right.
> 
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  include/drm/drm_mipi_dsi.h | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index cb084af..410d8b5 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -195,6 +195,11 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>  
>  struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>  					    struct mipi_dsi_device_info *info);
> +static inline void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
> +{
> +	device_unregister(&dsi->dev);
> +}

This is the same, essentially, as mipi_dsi_remove_device_fn(). I think
this should move into drm_mipi_dsi.c and mipi_dsi_remove_device_fn()
should call this new function so that both OF and !OF share the same
code for this.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v4 6/6] drm/dsi: Get DSI host by DT device node
  2015-12-10 12:41       ` [PATCH v4 6/6] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2016-01-21 16:16         ` Thierry Reding
  2016-01-27  5:21           ` Archit Taneja
  0 siblings, 1 reply; 84+ messages in thread
From: Thierry Reding @ 2016-01-21 16:16 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm

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

On Thu, Dec 10, 2015 at 06:11:40PM +0530, Archit Taneja wrote:
> mipi_dsi_devices are inherently aware of their host because they
> share a parent-child hierarchy in the device tree.
> 
> non-dsi drivers that create dsi device don't have this data. In order to
> get this information, they require to a phandle to the dsi host in the
> device tree.
> 
> Maintain a list of all the hosts DSI that are currently registered.
> 
> This list will be used to find the mipi_dsi_host corresponding to the
> device_node passed in of_find_mipi_dsi_host_by_node.
> 
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 38 ++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_mipi_dsi.h     |  3 +++
>  2 files changed, 41 insertions(+)

Please be more consistent with the spelling. Abbreviations should be all
capitals. Also s/mipi_dsi_devices/MIPI DSI devices/, and so on.

Otherwise I guess this makes sense.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
  2016-01-21 15:31         ` Thierry Reding
@ 2016-01-26 14:59           ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-01-26 14:59 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm



On 1/21/2016 9:01 PM, Thierry Reding wrote:
> On Thu, Dec 10, 2015 at 06:11:35PM +0530, Archit Taneja wrote:
>> of_mipi_dsi_device_add is used only when CONFIG_OF is enabled. It
>> currently works if OF support is disabled, but this will change
>> when we add more functionality to it.
>>
>> Define the original func if CONFIG_OF is enabled. Define a dummy func
>> otherwise.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index 2d5ca8ee..bced235 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -129,6 +129,7 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
>>   	return device_add(&dsi->dev);
>>   }
>>
>> +#if IS_ENABLED(CONFIG_OF)
>>   static struct mipi_dsi_device *
>>   of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>   {
>> @@ -170,6 +171,13 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>
>>   	return dsi;
>>   }
>> +#else
>> +static struct mipi_dsi_device *
>> +of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>> +{
>> +	return NULL;
>> +}
>> +#endif
>
> The OF implementation of this function never returns NULL, so perhaps
> this should return an ERR_PTR()-encoded error code instead? This isn't
> really important because we never check the return value in the one
> call-site that we have, which I guess could be an argument for removing
> the return value altogether...

You're right. I'll replace this with ERR_PTR(-ENODEV). Maybe we could
keep the return value in case we use it in the future.

Thanks,
Archit

>
> Thierry
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH v4 2/6] drm/dsi: Refactor device creation
  2016-01-21 15:46         ` Thierry Reding
@ 2016-01-26 17:05           ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-01-26 17:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm



On 1/21/2016 9:16 PM, Thierry Reding wrote:
> On Thu, Dec 10, 2015 at 06:11:36PM +0530, Archit Taneja wrote:
>> Simplify the mipi dsi device creation process. device_initialize and
>
> "MIPI" and "DSI", please.

Sure, I'll replace with these and in the other patches.

>
>> device_add don't need to be called separately when creating
>> mipi_dsi_device's. Use device_register instead to simplify things.
>>
>> Create a helper function mipi_dsi_device_new which takes in struct
>> mipi_dsi_device_info and mipi_dsi_host. It clubs the functions
>> mipi_dsi_device_alloc and mipi_dsi_device_add into one.
>>
>> mipi_dsi_device_info acts as a template to populate the dsi device
>> information. This is populated by of_mipi_dsi_device_add and passed to
>> mipi_dsi_device_new.
>>
>> Later on, we'll provide mipi_dsi_device_new as a standalone way to create
>> a dsi device not available via DT.
>>
>> The new device creation process tries to closely follow what's been done
>> in i2c_new_device in i2c-core.
>>
>> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 61 +++++++++++++++++-------------------------
>>   include/drm/drm_mipi_dsi.h     | 15 +++++++++++
>>   2 files changed, 40 insertions(+), 36 deletions(-)
>
> To be honest, I'm not sure I like this. If you want to have a simpler
> helper, why not implement it using the lower-level helpers. Really the
> only thing you're doing here is add a high-level helper that takes an
> info struct, whereas previously the same would be done by storing the
> info directly in the structure between allocation and addition of the
> device.
>
> Initially the implementation was following that of platform devices, I
> see no reason to deviate from that. What you want here can easily be

I don't see why we need to call device_initialize and device_add
separately for DSI devices. From my (limited) understanding, we should
call these separately if we want to take a reference (using 
get_device()), or set up some private data before the bus's
notifier kicks in.

Since the main purpose of the series is not to simplify the device
creation code, I can drop this.

> done by something like:
>
> 	struct mipi_dsi_device *
> 	mipi_dsi_device_register_full(struct mipi_dsi_host *host,
> 				      const struct mipi_dsi_device_info *info)
> 	{
> 		struct mipi_dsi_device *dsi;
>
> 		dsi = mipi_dsi_device_alloc(host);
> 		if (IS_ERR(dsi))
> 			return dsi;
>
> 		dsi->dev.of_node = info->node;
> 		dsi->channel = info->channel;
>
> 		err = mipi_dsi_device_add(dsi);
> 		if (err < 0) {
> 			...
> 		}
>
> 		return dsi;
> 	}
>
> Thierry
>

This does look less intrusive. I'll consider switching to this.

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH v4 3/6] drm/dsi: Try to match non-DT dsi devices
  2016-01-21 16:05         ` Thierry Reding
@ 2016-01-26 18:04           ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-01-26 18:04 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm



On 1/21/2016 9:35 PM, Thierry Reding wrote:
> On Thu, Dec 10, 2015 at 06:11:37PM +0530, Archit Taneja wrote:
>> Add a device name field in mipi_dsi_device. This name is different from
>> the actual dev name (which is of the format "hostname.reg"). When the
>> device is created via DT, this name is set to the modalias string.
>
> Why? What's the use of setting this to the modalias string?

There is no use to set it in the DT case. It's just set for the sake
of consistency between the non-DT and DT devices. For now, dsi->name
is just used for device/driver matching for non-DT devices. There's
no harm in setting it to a valid name for DT devices.

>
>> In the non-DT case, the driver creating the DSI device provides the
>> name by populating a filed in mipi_dsi_device_info.
>>
>> Matching for DT case would be as it was before. For the non-DT case,
>> we compare the device and driver names. Other buses (like i2c/spi)
>
> "I2C" and "SPI", please.
>
>> perform a non-DT match by comparing the device name and entries in the
>> driver's id_table. Such a mechanism isn't used for the dsi bus.
>
> "DSI", please.
>
>>
>> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 25 ++++++++++++++++++++++++-
>>   include/drm/drm_mipi_dsi.h     |  6 ++++++
>>   2 files changed, 30 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index 9434585..5a46802 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -45,9 +45,26 @@
>>    * subset of the MIPI DCS command set.
>>    */
>>
>> +static const struct device_type mipi_dsi_device_type;
>> +
>>   static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
>>   {
>> -	return of_driver_match_device(dev, drv);
>> +	struct mipi_dsi_device *dsi;
>> +
>> +	if (dev->type == &mipi_dsi_device_type)
>> +		dsi = to_mipi_dsi_device(dev);
>> +	else
>> +		return 0;
>
> I think this check is redundant. I'm not aware of any case where the bus
> ->match() callback is called on a device that isn't on said bus.

You're right. I'll drop this.

>
>> +	/* attempt OF style match */
>> +	if (of_driver_match_device(dev, drv))
>> +		return 1;
>> +
>> +	/* compare dsi device and driver names */
>
> "DSI", please.
>
>> +	if (!strcmp(dsi->name, drv->name))
>> +		return 1;
>> +
>> +	return 0;
>>   }
>>
>>   static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
>> @@ -125,6 +142,7 @@ struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>   	dsi->dev.type = &mipi_dsi_device_type;
>>   	dsi->dev.of_node = info->node;
>>   	dsi->channel = info->reg;
>> +	strlcpy(dsi->name, info->type, sizeof(dsi->name));
>
> Don't you need to check info->type != NULL before doing this?

It's not needed with the way struct mipi_dsi_device_info is currently
defined.

>
>>
>>   	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), info->reg);
>>
>> @@ -148,6 +166,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
>>   	int ret;
>>   	u32 reg;
>>
>> +	if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
>> +		dev_err(dev, "modalias failure on %s\n", node->full_name);
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>>   	ret = of_property_read_u32(node, "reg", &reg);
>>   	if (ret) {
>>   		dev_err(dev, "device node %s has no valid reg property: %d\n",
>> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
>> index 90f4f3c..cb084af 100644
>> --- a/include/drm/drm_mipi_dsi.h
>> +++ b/include/drm/drm_mipi_dsi.h
>> @@ -139,8 +139,11 @@ enum mipi_dsi_pixel_format {
>>   	MIPI_DSI_FMT_RGB565,
>>   };
>>
>> +#define DSI_DEV_NAME_SIZE		20
>> +
>>   /**
>>    * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
>> + * @type: dsi peripheral chip type
>>    * @reg: DSI virtual channel assigned to peripheral
>>    * @node: pointer to OF device node
>>    *
>> @@ -148,6 +151,7 @@ enum mipi_dsi_pixel_format {
>>    * DSI device
>>    */
>>   struct mipi_dsi_device_info {
>> +	char type[DSI_DEV_NAME_SIZE];
>
> Why limit ourselves to 20 characters? And why even so complicated? Isn't
> the type always static when someone specifies this? Couldn't we simply
> use a const char *name here instead?

In the case where the device is registered via DT, we would need
space allocated for 'type' to copy the modalias string into it.
Having const char *type would make it a bit complicated for the
DT path.

The mipi_dsi_device_info struct was based on
the i2c_board_info/spi_board_info structs, and they have
type/modalias members declared as array of chars. I kind of
followed suit without putting to much thought on member type.

Archit

>
> Thierry
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH v4 4/6] drm/dsi: Check for used channels
  2016-01-21 16:11         ` Thierry Reding
@ 2016-01-27  5:16           ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-01-27  5:16 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm



On 01/21/2016 09:41 PM, Thierry Reding wrote:
> On Thu, Dec 10, 2015 at 06:11:38PM +0530, Archit Taneja wrote:
>> We don't check whether a previously registered mipi_dsi_device under the
>> same host shares the same virtual channel.
>>
>> Before registering, check if any of the registered devices doesn't
>> already have the same virtual channel.
>>
>> This wasn't crucial when all the devices under a host were populated via
>> DT. Now that we also support creating devices manually, we could end up
>> in a situation where a driver tries to create a device with a virtual
>> channel already taken by a device populated in DT.
>>
>> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 26 ++++++++++++++++++++++++--
>>   1 file changed, 24 insertions(+), 2 deletions(-)
>
> I don't think this is necessary. The device name will be composed of the
> host's name, a '.' and the virtual channel ID, and the device core will
> refuse to create two devices with the same name.

That's a good point. I'll drop this patch.

Archit

>
> Thierry
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [PATCH v4 5/6] drm/dsi: Add routine to unregister dsi device
  2016-01-21 16:12         ` Thierry Reding
@ 2016-01-27  5:20           ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-01-27  5:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm



On 01/21/2016 09:42 PM, Thierry Reding wrote:
> On Thu, Dec 10, 2015 at 06:11:39PM +0530, Archit Taneja wrote:
>> A driver calling mipi_dsi_device_new might want to unregister the device
>> once it's done. It might also require it in an error handling path in
>> case something didn't go right.
>>
>> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   include/drm/drm_mipi_dsi.h | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
>> index cb084af..410d8b5 100644
>> --- a/include/drm/drm_mipi_dsi.h
>> +++ b/include/drm/drm_mipi_dsi.h
>> @@ -195,6 +195,11 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>>
>>   struct mipi_dsi_device *mipi_dsi_device_new(struct mipi_dsi_host *host,
>>   					    struct mipi_dsi_device_info *info);
>> +static inline void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
>> +{
>> +	device_unregister(&dsi->dev);
>> +}
>
> This is the same, essentially, as mipi_dsi_remove_device_fn(). I think
> this should move into drm_mipi_dsi.c and mipi_dsi_remove_device_fn()
> should call this new function so that both OF and !OF share the same
> code for this.

I can do this.

Thanks,
Archit


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* Re: [PATCH v4 6/6] drm/dsi: Get DSI host by DT device node
  2016-01-21 16:16         ` Thierry Reding
@ 2016-01-27  5:21           ` Archit Taneja
  0 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-01-27  5:21 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel, a.hajda, jani.nikula, linux-kernel, airlied, daniel,
	l.stach, robh, linux-arm-msm



On 01/21/2016 09:46 PM, Thierry Reding wrote:
> On Thu, Dec 10, 2015 at 06:11:40PM +0530, Archit Taneja wrote:
>> mipi_dsi_devices are inherently aware of their host because they
>> share a parent-child hierarchy in the device tree.
>>
>> non-dsi drivers that create dsi device don't have this data. In order to
>> get this information, they require to a phandle to the dsi host in the
>> device tree.
>>
>> Maintain a list of all the hosts DSI that are currently registered.
>>
>> This list will be used to find the mipi_dsi_host corresponding to the
>> device_node passed in of_find_mipi_dsi_host_by_node.
>>
>> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/drm_mipi_dsi.c | 38 ++++++++++++++++++++++++++++++++++++++
>>   include/drm/drm_mipi_dsi.h     |  3 +++
>>   2 files changed, 41 insertions(+)
>
> Please be more consistent with the spelling. Abbreviations should be all
> capitals. Also s/mipi_dsi_devices/MIPI DSI devices/, and so on.

I'll ensure the abbreviations are consistent in the next revision.

>
> Otherwise I guess this makes sense.

Thanks for the review.

Thanks,
Archit

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum, hosted by The Linux Foundation

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

* [PATCH v5 0/5] drm/dsi: DSI for devices with different control bus
  2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
                         ` (6 preceding siblings ...)
  2016-01-05  5:29       ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
@ 2016-02-12  9:18       ` Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 1/5] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
                           ` (5 more replies)
  7 siblings, 6 replies; 84+ messages in thread
From: Archit Taneja @ 2016-02-12  9:18 UTC (permalink / raw)
  To: dri-devel, treding
  Cc: linux-kernel, a.hajda, airlied, daniel, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

We are currently restricted when it comes to supporting DSI on devices
that have a non-DSI control bus. For example, DSI encoder chips are
available in the market that are configured via i2c. Configuring their
registers via DSI bus is either optional or not available at all.

These devices still need to pass DSI parameters (data lanes, mode flags
etc) to the DSI host they are connected to. We don't have a way to do
that at the moment.

After some discussions on the previous RFC[1], we decided to support this
by providing additional API in drm_mipi_dsi.c which lets us create new DSI
devices without the need of them to have a DT node.

[1]: https://lkml.org/lkml/2015/6/30/42

Changes in v5:
- Simplify refactoring as suggested by Thierry.
- Use abbreviations correctly.
- Drop "drm/dsi: Check for used channels"
- Return the correct encoded error code for of_mipi_dsi_device_add
  when CONFIG_OF is disabled.
- Use mipi_dsi_device_unregister to implement mipi_dsi_remove_device_fn()
  too.

Changes in v4:
- Added a new patch that fixes build issues when CONFIG_OF is not set.

Changes in v3:

- Incorporated misc comments by Andrzej. Changed from RFC to a PATCH set.
- Fixed htmldocs warnings.


Archit Taneja (5):
  drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
  drm/dsi: Use mipi_dsi_device_register_full for DSI device creation
  drm/dsi: Try to match non-DT DSI devices
  drm/dsi: Add routine to unregister a DSI device
  drm/dsi: Get DSI host by DT device node

 drivers/gpu/drm/drm_mipi_dsi.c | 127 +++++++++++++++++++++++++++++++++++++----
 include/drm/drm_mipi_dsi.h     |  26 +++++++++
 2 files changed, 141 insertions(+), 12 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v5 1/5] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
@ 2016-02-12  9:18         ` Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 2/5] drm/dsi: Use mipi_dsi_device_register_full for DSI device creation Archit Taneja
                           ` (4 subsequent siblings)
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-02-12  9:18 UTC (permalink / raw)
  To: dri-devel, treding
  Cc: linux-kernel, a.hajda, airlied, daniel, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

of_mipi_dsi_device_add is used only when CONFIG_OF is enabled. It
currently works if OF support is disabled, but this will change
when we add more functionality to it.

Define the original func if CONFIG_OF is enabled. Define a dummy func
otherwise.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 6e6a9c5..4f2a704 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -129,6 +129,7 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
 	return device_add(&dsi->dev);
 }
 
+#if IS_ENABLED(CONFIG_OF)
 static struct mipi_dsi_device *
 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 {
@@ -170,6 +171,13 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 
 	return dsi;
 }
+#else
+static struct mipi_dsi_device *
+of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
+{
+	return ERR_PTR(-ENODEV);
+}
+#endif
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v5 2/5] drm/dsi: Use mipi_dsi_device_register_full for DSI device creation
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 1/5] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
@ 2016-02-12  9:18         ` Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 3/5] drm/dsi: Try to match non-DT DSI devices Archit Taneja
                           ` (3 subsequent siblings)
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-02-12  9:18 UTC (permalink / raw)
  To: dri-devel, treding
  Cc: linux-kernel, a.hajda, airlied, daniel, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

Use mipi_dsi_device_register_full for device creation. This takes in
mipi_dsi_device_info as a template to populate the DSI device information.

The reason to introduce this is to have a way to create DSI devices not
available via DT. Drivers that want to create a DSI device can populate
mipi_dsi_device_info and call this function. For DSI devices available
via DT, of_mipi_dsi_device_add is used as before, but this now calls
mipi_dsi_device_register_full internally.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 64 +++++++++++++++++++++++++++++++-----------
 include/drm/drm_mipi_dsi.h     | 16 +++++++++++
 2 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 4f2a704..5d7243d 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -133,8 +133,8 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
 static struct mipi_dsi_device *
 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 {
-	struct mipi_dsi_device *dsi;
 	struct device *dev = host->dev;
+	struct mipi_dsi_device_info info = { };
 	int ret;
 	u32 reg;
 
@@ -145,39 +145,69 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (reg > 3) {
-		dev_err(dev, "device node %s has invalid reg property: %u\n",
-			node->full_name, reg);
+	info.channel = reg;
+	info.node = of_node_get(node);
+
+	return mipi_dsi_device_register_full(host, &info);
+}
+#else
+static struct mipi_dsi_device *
+of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
+{
+	return ERR_PTR(-ENODEV);
+}
+#endif
+
+/**
+ * mipi_dsi_device_register_full - create a MIPI DSI device
+ * @host: DSI host to which this device is connected
+ * @info: pointer to template containing DSI device information
+ *
+ * Create a MIPI DSI device by using the device information provided by
+ * mipi_dsi_device_info template
+ *
+ * Returns:
+ * A pointer to the newly created MIPI DSI device, or, a pointer encoded
+ * with an error
+ */
+struct mipi_dsi_device *
+mipi_dsi_device_register_full(struct mipi_dsi_host *host,
+			      const struct mipi_dsi_device_info *info)
+{
+	struct mipi_dsi_device *dsi;
+	struct device *dev = host->dev;
+	int ret;
+
+	if (!info) {
+		dev_err(dev, "invalid mipi_dsi_device_info pointer\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (info->channel > 3) {
+		dev_err(dev, "invalid virtual channel: %u\n", info->channel);
 		return ERR_PTR(-EINVAL);
 	}
 
 	dsi = mipi_dsi_device_alloc(host);
 	if (IS_ERR(dsi)) {
-		dev_err(dev, "failed to allocate DSI device %s: %ld\n",
-			node->full_name, PTR_ERR(dsi));
+		dev_err(dev, "failed to allocate DSI device %ld\n",
+			PTR_ERR(dsi));
 		return dsi;
 	}
 
-	dsi->dev.of_node = of_node_get(node);
-	dsi->channel = reg;
+	dsi->dev.of_node = info->node;
+	dsi->channel = info->channel;
 
 	ret = mipi_dsi_device_add(dsi);
 	if (ret) {
-		dev_err(dev, "failed to add DSI device %s: %d\n",
-			node->full_name, ret);
+		dev_err(dev, "failed to add DSI device %d\n", ret);
 		kfree(dsi);
 		return ERR_PTR(ret);
 	}
 
 	return dsi;
 }
-#else
-static struct mipi_dsi_device *
-of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
-{
-	return ERR_PTR(-ENODEV);
-}
-#endif
+EXPORT_SYMBOL(mipi_dsi_device_register_full);
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 1b3b1f8..ce5eae43 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -139,6 +139,19 @@ enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB565,
 };
 
+ /**
+ * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @channel: DSI virtual channel assigned to peripheral
+ * @node: pointer to OF device node
+ *
+ * This is populated and passed to mipi_dsi_device_new to create a new
+ * DSI device
+ */
+struct mipi_dsi_device_info {
+	u32 channel;
+	struct device_node *node;
+};
+
 /**
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
@@ -188,6 +201,9 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
 	return -EINVAL;
 }
 
+struct mipi_dsi_device *
+mipi_dsi_device_register_full(struct mipi_dsi_host *host,
+			      const struct mipi_dsi_device_info *info);
 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
 int mipi_dsi_attach(struct mipi_dsi_device *dsi);
 int mipi_dsi_detach(struct mipi_dsi_device *dsi);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v5 3/5] drm/dsi: Try to match non-DT DSI devices
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 1/5] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 2/5] drm/dsi: Use mipi_dsi_device_register_full for DSI device creation Archit Taneja
@ 2016-02-12  9:18         ` Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 4/5] drm/dsi: Add routine to unregister a DSI device Archit Taneja
                           ` (2 subsequent siblings)
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-02-12  9:18 UTC (permalink / raw)
  To: dri-devel, treding
  Cc: linux-kernel, a.hajda, airlied, daniel, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

Add a device name field in mipi_dsi_device. This name is different from
the actual dev name (which is of the format "hostname.reg"). When the
device is created via DT, this name is set to the modalias string.
In the non-DT case, the driver creating the DSI device provides the
name by populating a filed in mipi_dsi_device_info.

Matching for DT case would be as it was before. For the non-DT case,
we compare the device and driver names. Other buses (like I2C/SPI)
perform a non-DT match by comparing the device name and entries in the
driver's id_table. Such a mechanism isn't used for the DSI bus.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 18 +++++++++++++++++-
 include/drm/drm_mipi_dsi.h     | 10 ++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 5d7243d..42a7aac 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -47,7 +47,17 @@
 
 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
 {
-	return of_driver_match_device(dev, drv);
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+
+	/* attempt OF style match */
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
+	/* compare DSI device and driver names */
+	if (!strcmp(dsi->name, drv->name))
+		return 1;
+
+	return 0;
 }
 
 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
@@ -138,6 +148,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
 	int ret;
 	u32 reg;
 
+	if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+		dev_err(dev, "modalias failure on %s\n", node->full_name);
+		return ERR_PTR(-EINVAL);
+	}
+
 	ret = of_property_read_u32(node, "reg", &reg);
 	if (ret) {
 		dev_err(dev, "device node %s has no valid reg property: %d\n",
@@ -197,6 +212,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
 
 	dsi->dev.of_node = info->node;
 	dsi->channel = info->channel;
+	strlcpy(dsi->name, info->type, sizeof(dsi->name));
 
 	ret = mipi_dsi_device_add(dsi);
 	if (ret) {
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index ce5eae43..a914116 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -139,15 +139,19 @@ enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB565,
 };
 
- /**
+#define DSI_DEV_NAME_SIZE		20
+
+/**
  * struct mipi_dsi_device_info - template for creating a mipi_dsi_device
+ * @type: DSI peripheral chip type
  * @channel: DSI virtual channel assigned to peripheral
- * @node: pointer to OF device node
+ * @node: pointer to OF device node or NULL
  *
  * This is populated and passed to mipi_dsi_device_new to create a new
  * DSI device
  */
 struct mipi_dsi_device_info {
+	char type[DSI_DEV_NAME_SIZE];
 	u32 channel;
 	struct device_node *node;
 };
@@ -156,6 +160,7 @@ struct mipi_dsi_device_info {
  * struct mipi_dsi_device - DSI peripheral device
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
+ * @name: DSI peripheral chip type
  * @channel: virtual channel assigned to the peripheral
  * @format: pixel format for video mode
  * @lanes: number of active data lanes
@@ -165,6 +170,7 @@ struct mipi_dsi_device {
 	struct mipi_dsi_host *host;
 	struct device dev;
 
+	char name[DSI_DEV_NAME_SIZE];
 	unsigned int channel;
 	unsigned int lanes;
 	enum mipi_dsi_pixel_format format;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v5 4/5] drm/dsi: Add routine to unregister a DSI device
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
                           ` (2 preceding siblings ...)
  2016-02-12  9:18         ` [PATCH v5 3/5] drm/dsi: Try to match non-DT DSI devices Archit Taneja
@ 2016-02-12  9:18         ` Archit Taneja
  2016-02-12  9:18         ` [PATCH v5 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
  2016-03-02 16:05         ` [PATCH v5 0/5] drm/dsi: DSI for devices with different control bus Thierry Reding
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-02-12  9:18 UTC (permalink / raw)
  To: dri-devel, treding
  Cc: linux-kernel, a.hajda, airlied, daniel, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

A driver calling mipi_dsi_device_register_full might want to unregister
the device once it's done. It might also require it in an error handling
path in case something didn't go right.

Create mipi_dsi_device_unregister for this purpse, use it within
mipi_dsi_remove_device_fn as it does the same thing.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 12 +++++++++++-
 include/drm/drm_mipi_dsi.h     |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 42a7aac..f2f5a6d 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -225,6 +225,16 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
 }
 EXPORT_SYMBOL(mipi_dsi_device_register_full);
 
+/**
+ * mipi_dsi_device_unregister - unregister MIPI DSI device
+ * @dsi: DSI peripheral device
+ */
+void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
+{
+	device_unregister(&dsi->dev);
+}
+EXPORT_SYMBOL(mipi_dsi_device_unregister);
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
 	struct device_node *node;
@@ -244,7 +254,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
 {
 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
 
-	device_unregister(&dsi->dev);
+	mipi_dsi_device_unregister(dsi);
 
 	return 0;
 }
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index a914116..06e0a93 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -210,6 +210,7 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
 struct mipi_dsi_device *
 mipi_dsi_device_register_full(struct mipi_dsi_host *host,
 			      const struct mipi_dsi_device_info *info);
+void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
 int mipi_dsi_attach(struct mipi_dsi_device *dsi);
 int mipi_dsi_detach(struct mipi_dsi_device *dsi);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v5 5/5] drm/dsi: Get DSI host by DT device node
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
                           ` (3 preceding siblings ...)
  2016-02-12  9:18         ` [PATCH v5 4/5] drm/dsi: Add routine to unregister a DSI device Archit Taneja
@ 2016-02-12  9:18         ` Archit Taneja
  2016-03-02 16:05         ` [PATCH v5 0/5] drm/dsi: DSI for devices with different control bus Thierry Reding
  5 siblings, 0 replies; 84+ messages in thread
From: Archit Taneja @ 2016-02-12  9:18 UTC (permalink / raw)
  To: dri-devel, treding
  Cc: linux-kernel, a.hajda, airlied, daniel, l.stach, robh,
	linux-arm-msm, jani.nikula, Archit Taneja

MIPI DSI devices are inherently aware of their host because they share a
parent-child hierarchy in the device tree.

Non-DSI drivers that create DSI device don't have this data. In order to
get this information, they require to a phandle to the DSI host in the
device tree.

Maintain a list of all the hosts DSI that are currently registered. This
list will be used to find the mipi_dsi_host corresponding to the
device_node passed in of_find_mipi_dsi_host_by_node.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 39 +++++++++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     |  3 +++
 2 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index f2f5a6d..f5d8083 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -235,6 +235,37 @@ void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
 }
 EXPORT_SYMBOL(mipi_dsi_device_unregister);
 
+static DEFINE_MUTEX(host_lock);
+static LIST_HEAD(host_list);
+
+/**
+ * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
+ *				     device tree node
+ * @node: device tree node
+ *
+ * Returns:
+ * A pointer to the MIPI DSI host corresponding to @node or NULL if no
+ * such device exists (or has not been registered yet).
+ */
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
+{
+	struct mipi_dsi_host *host;
+
+	mutex_lock(&host_lock);
+
+	list_for_each_entry(host, &host_list, list) {
+		if (host->dev->of_node == node) {
+			mutex_unlock(&host_lock);
+			return host;
+		}
+	}
+
+	mutex_unlock(&host_lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
 	struct device_node *node;
@@ -246,6 +277,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
 		of_mipi_dsi_device_add(host, node);
 	}
 
+	mutex_lock(&host_lock);
+	list_add_tail(&host->list, &host_list);
+	mutex_unlock(&host_lock);
+
 	return 0;
 }
 EXPORT_SYMBOL(mipi_dsi_host_register);
@@ -262,6 +297,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
 {
 	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
+
+	mutex_lock(&host_lock);
+	list_del_init(&host->list);
+	mutex_unlock(&host_lock);
 }
 EXPORT_SYMBOL(mipi_dsi_host_unregister);
 
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 06e0a93..7a9840f 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -96,14 +96,17 @@ struct mipi_dsi_host_ops {
  * struct mipi_dsi_host - DSI host device
  * @dev: driver model device node for this DSI host
  * @ops: DSI host operations
+ * @list: list management
  */
 struct mipi_dsi_host {
 	struct device *dev;
 	const struct mipi_dsi_host_ops *ops;
+	struct list_head list;
 };
 
 int mipi_dsi_host_register(struct mipi_dsi_host *host);
 void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
+struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 
 /* DSI mode flags */
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH v5 0/5] drm/dsi: DSI for devices with different control bus
  2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
                           ` (4 preceding siblings ...)
  2016-02-12  9:18         ` [PATCH v5 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
@ 2016-03-02 16:05         ` Thierry Reding
  5 siblings, 0 replies; 84+ messages in thread
From: Thierry Reding @ 2016-03-02 16:05 UTC (permalink / raw)
  To: Archit Taneja
  Cc: dri-devel, linux-kernel, a.hajda, airlied, daniel, l.stach, robh,
	linux-arm-msm, jani.nikula

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

On Fri, Feb 12, 2016 at 02:48:29PM +0530, Archit Taneja wrote:
> We are currently restricted when it comes to supporting DSI on devices
> that have a non-DSI control bus. For example, DSI encoder chips are
> available in the market that are configured via i2c. Configuring their
> registers via DSI bus is either optional or not available at all.
> 
> These devices still need to pass DSI parameters (data lanes, mode flags
> etc) to the DSI host they are connected to. We don't have a way to do
> that at the moment.
> 
> After some discussions on the previous RFC[1], we decided to support this
> by providing additional API in drm_mipi_dsi.c which lets us create new DSI
> devices without the need of them to have a DT node.
> 
> [1]: https://lkml.org/lkml/2015/6/30/42
> 
> Changes in v5:
> - Simplify refactoring as suggested by Thierry.
> - Use abbreviations correctly.
> - Drop "drm/dsi: Check for used channels"
> - Return the correct encoded error code for of_mipi_dsi_device_add
>   when CONFIG_OF is disabled.
> - Use mipi_dsi_device_unregister to implement mipi_dsi_remove_device_fn()
>   too.
> 
> Changes in v4:
> - Added a new patch that fixes build issues when CONFIG_OF is not set.
> 
> Changes in v3:
> 
> - Incorporated misc comments by Andrzej. Changed from RFC to a PATCH set.
> - Fixed htmldocs warnings.
> 
> 
> Archit Taneja (5):
>   drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add
>   drm/dsi: Use mipi_dsi_device_register_full for DSI device creation
>   drm/dsi: Try to match non-DT DSI devices
>   drm/dsi: Add routine to unregister a DSI device
>   drm/dsi: Get DSI host by DT device node
> 
>  drivers/gpu/drm/drm_mipi_dsi.c | 127 +++++++++++++++++++++++++++++++++++++----
>  include/drm/drm_mipi_dsi.h     |  26 +++++++++
>  2 files changed, 141 insertions(+), 12 deletions(-)

I've applied this with minor fixups and cleanups to the commit messages.

Thanks,
Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

end of thread, other threads:[~2016-03-02 16:06 UTC | newest]

Thread overview: 84+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-30  5:24 [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
2015-06-30  5:24 ` [RFC 1/2] drm/dsi: Create dummy DSI devices Archit Taneja
2015-08-19  8:10   ` Andrzej Hajda
2015-08-19  9:30     ` Archit Taneja
2015-06-30  5:24 ` [RFC 2/2] drm/dsi: Get DSI host by DT device node Archit Taneja
2015-08-19  8:46   ` Andrzej Hajda
2015-08-19  5:07 ` [RFC 0/2] drm/dsi: DSI for devices with different control bus Archit Taneja
2015-08-19 13:13   ` Thierry Reding
2015-08-19 14:17     ` Lucas Stach
2015-08-19 14:34       ` Thierry Reding
2015-08-19 14:52         ` Lucas Stach
2015-08-19 15:02           ` Thierry Reding
2015-08-19 15:39             ` Jani Nikula
2015-08-20  4:16             ` Archit Taneja
2015-08-20 11:48               ` Thierry Reding
2015-08-21  6:09                 ` Archit Taneja
2015-09-07 11:46                   ` Archit Taneja
2015-09-08 10:27                     ` Andrzej Hajda
2015-09-10  6:15                       ` Archit Taneja
2015-09-10  7:32                         ` Thierry Reding
2015-09-15 10:32                           ` Archit Taneja
2015-09-15 15:43                             ` Rob Herring
2015-09-17  8:56                               ` Archit Taneja
2015-09-15 10:41                           ` Archit Taneja
2015-10-06  9:24 ` [RFC v2 0/5] " Archit Taneja
2015-10-06  9:24   ` [RFC v2 1/5] drm/dsi: Refactor device creation Archit Taneja
2015-10-30 11:28     ` Andrzej Hajda
2015-10-06  9:24   ` [RFC v2 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
2015-10-30 12:42     ` Andrzej Hajda
2015-11-02  5:26       ` Archit Taneja
2015-10-06  9:24   ` [RFC v2 3/5] drm/dsi: Check for used channels Archit Taneja
2015-10-30 12:52     ` Andrzej Hajda
2015-11-02  5:28       ` Archit Taneja
2015-10-06  9:24   ` [RFC v2 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
2015-10-30 14:21     ` Andrzej Hajda
2015-11-02  6:28       ` Archit Taneja
2015-11-02 10:42         ` Andrzej Hajda
2015-11-03  7:18           ` Archit Taneja
2015-10-06  9:24   ` [RFC v2 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
2015-10-06 10:00     ` kbuild test robot
2015-11-02 10:50     ` Andrzej Hajda
2015-11-03  7:20       ` Archit Taneja
2015-11-30 12:01   ` [PATCH v3 0/5] drm/dsi: DSI for devices with different control bus Archit Taneja
2015-11-30 12:01     ` [PATCH v3 1/5] drm/dsi: Refactor device creation Archit Taneja
2015-11-30 12:01     ` [PATCH v3 2/5] drm/dsi: Try to match non-DT dsi devices Archit Taneja
2015-11-30 12:45       ` kbuild test robot
2015-12-07  5:29         ` Archit Taneja
2015-12-07  8:45           ` Jani Nikula
2015-12-07  8:59             ` Archit Taneja
2015-12-07  9:10               ` Jani Nikula
2015-12-07  9:18                 ` Archit Taneja
2015-12-07 10:07                   ` Jani Nikula
2015-12-07 16:55             ` Rob Clark
2015-11-30 12:01     ` [PATCH v3 3/5] drm/dsi: Check for used channels Archit Taneja
2015-11-30 12:01     ` [PATCH v3 4/5] drm/dsi: Add routine to unregister dsi device Archit Taneja
2015-11-30 12:34       ` Andrzej Hajda
2015-11-30 12:01     ` [PATCH v3 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
2015-12-10 12:41     ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
2015-12-10 12:41       ` [PATCH v4 1/6] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
2016-01-21 15:31         ` Thierry Reding
2016-01-26 14:59           ` Archit Taneja
2015-12-10 12:41       ` [PATCH v4 2/6] drm/dsi: Refactor device creation Archit Taneja
2016-01-21 15:46         ` Thierry Reding
2016-01-26 17:05           ` Archit Taneja
2015-12-10 12:41       ` [PATCH v4 3/6] drm/dsi: Try to match non-DT dsi devices Archit Taneja
2016-01-21 16:05         ` Thierry Reding
2016-01-26 18:04           ` Archit Taneja
2015-12-10 12:41       ` [PATCH v4 4/6] drm/dsi: Check for used channels Archit Taneja
2016-01-21 16:11         ` Thierry Reding
2016-01-27  5:16           ` Archit Taneja
2015-12-10 12:41       ` [PATCH v4 5/6] drm/dsi: Add routine to unregister dsi device Archit Taneja
2016-01-21 16:12         ` Thierry Reding
2016-01-27  5:20           ` Archit Taneja
2015-12-10 12:41       ` [PATCH v4 6/6] drm/dsi: Get DSI host by DT device node Archit Taneja
2016-01-21 16:16         ` Thierry Reding
2016-01-27  5:21           ` Archit Taneja
2016-01-05  5:29       ` [PATCH v4 0/6] drm/dsi: DSI for devices with different control bus Archit Taneja
2016-02-12  9:18       ` [PATCH v5 0/5] " Archit Taneja
2016-02-12  9:18         ` [PATCH v5 1/5] drm/dsi: check for CONFIG_OF when defining of_mipi_dsi_device_add Archit Taneja
2016-02-12  9:18         ` [PATCH v5 2/5] drm/dsi: Use mipi_dsi_device_register_full for DSI device creation Archit Taneja
2016-02-12  9:18         ` [PATCH v5 3/5] drm/dsi: Try to match non-DT DSI devices Archit Taneja
2016-02-12  9:18         ` [PATCH v5 4/5] drm/dsi: Add routine to unregister a DSI device Archit Taneja
2016-02-12  9:18         ` [PATCH v5 5/5] drm/dsi: Get DSI host by DT device node Archit Taneja
2016-03-02 16:05         ` [PATCH v5 0/5] drm/dsi: DSI for devices with different control bus Thierry Reding

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