Re: [PATCHv9 2/2] drm: tda998x: set the connector info

2019-10-17 Thread Hans Verkuil
On 10/17/19 10:11 AM, Russell King - ARM Linux admin wrote:
> On Thu, Oct 17, 2019 at 09:28:42AM +0200, Hans Verkuil wrote:
>> From: Dariusz Marcinkiewicz 
>>
>> Fill in the cec_connector_info when calling cec_notifier_conn_register().
>>
>> Signed-off-by: Dariusz Marcinkiewicz 
>> Tested-by: Hans Verkuil 
>> Signed-off-by: Hans Verkuil 
>> ---
>>  drivers/gpu/drm/i2c/tda998x_drv.c | 33 +++
>>  1 file changed, 25 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
>> b/drivers/gpu/drm/i2c/tda998x_drv.c
>> index dde8decb52a6..b0620842fa3a 100644
>> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
>> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
>> @@ -82,6 +82,9 @@ struct tda998x_priv {
>>  u8 audio_port_enable[AUDIO_ROUTE_NUM];
>>  struct tda9950_glue cec_glue;
>>  struct gpio_desc *calib;
>> +
>> +/* protect cec_notify */
>> +struct mutex cec_notify_mutex;
>>  struct cec_notifier *cec_notify;
>>  };
>>  
>> @@ -805,8 +808,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void 
>> *data)
>>  tda998x_edid_delay_start(priv);
>>  } else {
>>  schedule_work(>detect_work);
>> +
>> +mutex_lock(>cec_notify_mutex);
>>  cec_notifier_phys_addr_invalidate(
>>  priv->cec_notify);
>> +mutex_unlock(>cec_notify_mutex);
>>  }
>>  
>>  handled = true;
>> @@ -1331,6 +1337,8 @@ static int tda998x_connector_init(struct tda998x_priv 
>> *priv,
>>struct drm_device *drm)
>>  {
>>  struct drm_connector *connector = >connector;
>> +struct cec_connector_info conn_info;
>> +struct cec_notifier *notifier;
>>  int ret;
>>  
>>  connector->interlace_allowed = 1;
>> @@ -1347,6 +1355,17 @@ static int tda998x_connector_init(struct tda998x_priv 
>> *priv,
>>  if (ret)
>>  return ret;
>>  
>> +cec_fill_conn_info_from_drm(_info, connector);
>> +
>> +notifier = cec_notifier_conn_register(priv->cec_glue.parent,
>> +  NULL, _info);
>> +if (!notifier)
>> +return -ENOMEM;
>> +
>> +mutex_lock(>cec_notify_mutex);
>> +priv->cec_notify = notifier;
>> +mutex_unlock(>cec_notify_mutex);
> 
> You haven't taken on board what I said about the mutex in this
> instance.

That's because I didn't. See the cover letter.

I need this info from the author of the patch, Dariusz. Once I have that,
and we agree with the reasoning, then I'll post a new patch for it.

For now all I am interested in is getting patch 1/2 merged. Patch 2/2 won't
be merged any time soon.

Regards,

Hans

> 
>> +
>>  drm_connector_attach_encoder(>connector,
>>   priv->bridge.encoder);
>>  
>> @@ -1366,6 +1385,11 @@ static void tda998x_bridge_detach(struct drm_bridge 
>> *bridge)
>>  {
>>  struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
>>  
>> +mutex_lock(>cec_notify_mutex);
>> +cec_notifier_conn_unregister(priv->cec_notify);
>> +priv->cec_notify = NULL;
>> +mutex_unlock(>cec_notify_mutex);
>> +
>>  drm_connector_cleanup(>connector);
>>  }
>>  
>> @@ -1789,8 +1813,6 @@ static void tda998x_destroy(struct device *dev)
>>  cancel_work_sync(>detect_work);
>>  
>>  i2c_unregister_device(priv->cec);
>> -
>> -cec_notifier_conn_unregister(priv->cec_notify);
>>  }
>>  
>>  static int tda998x_create(struct device *dev)
>> @@ -1811,6 +1833,7 @@ static int tda998x_create(struct device *dev)
>>  mutex_init(>mutex);   /* protect the page access */
>>  mutex_init(>audio_mutex); /* protect access from audio thread */
>>  mutex_init(>edid_mutex);
>> +mutex_init(>cec_notify_mutex);
>>  INIT_LIST_HEAD(>bridge.list);
>>  init_waitqueue_head(>edid_delay_waitq);
>>  timer_setup(>edid_delay_timer, tda998x_edid_delay_done, 0);
>> @@ -1915,12 +1938,6 @@ static int tda998x_create(struct device *dev)
>>  cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
>>  }
>>  
>> -priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
>> -if (!priv->cec_notify) {
>> -ret = -ENOMEM;
>> -goto fail;
>> -}
>> -
>>  priv->cec_glue.parent = dev;
>>  priv->cec_glue.data = priv;
>>  priv->cec_glue.init = tda998x_cec_hook_init;
>> -- 
>> 2.23.0
>>
>>
> 



Re: [PATCHv8 1/2] drm: tda998x: use cec_notifier_conn_(un)register

2019-10-17 Thread Hans Verkuil
On 10/17/19 9:03 AM, Hans Verkuil wrote:
> On 10/16/19 6:14 PM, Russell King - ARM Linux admin wrote:
>> On Wed, Oct 16, 2019 at 03:39:15PM +0200, Hans Verkuil wrote:
>>> From: Dariusz Marcinkiewicz 
>>>
>>> Use the new cec_notifier_conn_(un)register() functions to
>>> (un)register the notifier for the HDMI connector.
>>>
>>> Signed-off-by: Dariusz Marcinkiewicz 
>>> Signed-off-by: Hans Verkuil 
>>
>> Please explain in detail what this mutex actually achieves.
> 
> Dariusz, since you're the author, can you reply to Russell?
> 
> If this is going to be a delaying factor, then I'll post a new version
> without the mutex that just replaces the cec_notifier API.

I decided to post a v9, moving the mutex to the second patch, which should
make the first patch acceptable to everyone for v5.5.

Regards,

Hans

> 
> Regards,
> 
>   Hans
> 
>>
>>> ---
>>>  drivers/gpu/drm/i2c/tda998x_drv.c | 21 -
>>>  1 file changed, 16 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
>>> b/drivers/gpu/drm/i2c/tda998x_drv.c
>>> index 84c6d4c91c65..8262b44b776e 100644
>>> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
>>> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
>>> @@ -82,6 +82,9 @@ struct tda998x_priv {
>>> u8 audio_port_enable[AUDIO_ROUTE_NUM];
>>> struct tda9950_glue cec_glue;
>>> struct gpio_desc *calib;
>>> +
>>> +   /* protect cec_notify */
>>> +   struct mutex cec_notify_mutex;
>>> struct cec_notifier *cec_notify;
>>>  };
>>>  
>>> @@ -805,8 +808,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void 
>>> *data)
>>> tda998x_edid_delay_start(priv);
>>> } else {
>>> schedule_work(>detect_work);
>>> -   cec_notifier_set_phys_addr(priv->cec_notify,
>>> -  CEC_PHYS_ADDR_INVALID);
>>> +
>>> +   mutex_lock(>cec_notify_mutex);
>>> +   cec_notifier_phys_addr_invalidate(
>>> +   priv->cec_notify);
>>> +   mutex_unlock(>cec_notify_mutex);
>>> }
>>>  
>>> handled = true;
>>> @@ -1790,8 +1796,10 @@ static void tda998x_destroy(struct device *dev)
>>>  
>>> i2c_unregister_device(priv->cec);
>>>  
>>> -   if (priv->cec_notify)
>>> -   cec_notifier_put(priv->cec_notify);
>>> +   mutex_lock(>cec_notify_mutex);
>>> +   cec_notifier_conn_unregister(priv->cec_notify);
>>> +   priv->cec_notify = NULL;
>>> +   mutex_unlock(>cec_notify_mutex);
>>
>> By the time we get here:
>>
>> 1) The interrupt has been freed (which is a synchronous operation)
>>tda998x_irq_thread() can't be called and can't be running, and
>>therefore cec_notifier_phys_addr_invalidate() also can't be called
>>or be running.
>> 2) You don't touch the cec_notifier_set_phys_addr_from_edid() site;
>>if there's any case that _might_ possibly conflict, it is that one.
>> 3) tda998x_destroy() and tda998x_create() can't be called concurrently
>>in any case; the driver model guarantees that ->probe and ->remove
>>for the same device are serialised.
>>
>>>  }
>>>  
>>>  static int tda998x_create(struct device *dev)
>>> @@ -1812,6 +1820,7 @@ static int tda998x_create(struct device *dev)
>>> mutex_init(>mutex);   /* protect the page access */
>>> mutex_init(>audio_mutex); /* protect access from audio thread */
>>> mutex_init(>edid_mutex);
>>> +   mutex_init(>cec_notify_mutex);
>>> INIT_LIST_HEAD(>bridge.list);
>>> init_waitqueue_head(>edid_delay_waitq);
>>> timer_setup(>edid_delay_timer, tda998x_edid_delay_done, 0);
>>> @@ -1916,7 +1925,9 @@ static int tda998x_create(struct device *dev)
>>> cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
>>> }
>>>  
>>> -   priv->cec_notify = cec_notifier_get(dev);
>>> +   mutex_lock(>cec_notify_mutex);
>>> +   priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
>>> +   mutex_unlock(>cec_notify_mutex);
>>
>> and:
>>
>> 4) priv->cec_notify

[PATCHv9 0/2] drm: tda998x: use cec_notifier_conn_(un)register

2019-10-17 Thread Hans Verkuil
This splits the previous v7.2 patch (1) into two parts: one that replaces
cec_notifier_get/put by cec_notifier_conn_(un)register, and one that
sets the connector info.

That second patch moves the CEC notifier code to tda998x_bridge_detach,
but Laurent is making changes in that area and prefers that this isn't
implemented yet.

Dariusz, can you comment on the use of the mutex in the second patch?
This second patch won't be merged for v5.5 so you can take your time :-)

But the replacement of the cec_notifier_get/put functions is something
that needs to be finished for v5.5.

By splitting this patch up I can merge the first half, but delay the
second half. This tda driver just won't be able to report the connector
information in the meantime.

Changes since v8:

- Moved the mutex addition to the second patch where I think it actually
  belongs.

Regards,

Hans

(1) https://patchwork.linuxtv.org/patch/58464/

Dariusz Marcinkiewicz (2):
  drm: tda998x: use cec_notifier_conn_(un)register
  drm: tda998x: set the connector info

 drivers/gpu/drm/i2c/tda998x_drv.c | 38 ++-
 1 file changed, 27 insertions(+), 11 deletions(-)

-- 
2.23.0



[PATCHv9 1/2] drm: tda998x: use cec_notifier_conn_(un)register

2019-10-17 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 84c6d4c91c65..dde8decb52a6 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -805,8 +805,8 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
tda998x_edid_delay_start(priv);
} else {
schedule_work(>detect_work);
-   cec_notifier_set_phys_addr(priv->cec_notify,
-  CEC_PHYS_ADDR_INVALID);
+   cec_notifier_phys_addr_invalidate(
+   priv->cec_notify);
}
 
handled = true;
@@ -1790,8 +1790,7 @@ static void tda998x_destroy(struct device *dev)
 
i2c_unregister_device(priv->cec);
 
-   if (priv->cec_notify)
-   cec_notifier_put(priv->cec_notify);
+   cec_notifier_conn_unregister(priv->cec_notify);
 }
 
 static int tda998x_create(struct device *dev)
@@ -1916,7 +1915,7 @@ static int tda998x_create(struct device *dev)
cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
}
 
-   priv->cec_notify = cec_notifier_get(dev);
+   priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
if (!priv->cec_notify) {
ret = -ENOMEM;
goto fail;
-- 
2.23.0



[PATCHv9 2/2] drm: tda998x: set the connector info

2019-10-17 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Fill in the cec_connector_info when calling cec_notifier_conn_register().

Signed-off-by: Dariusz Marcinkiewicz 
Tested-by: Hans Verkuil 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 33 +++
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index dde8decb52a6..b0620842fa3a 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -82,6 +82,9 @@ struct tda998x_priv {
u8 audio_port_enable[AUDIO_ROUTE_NUM];
struct tda9950_glue cec_glue;
struct gpio_desc *calib;
+
+   /* protect cec_notify */
+   struct mutex cec_notify_mutex;
struct cec_notifier *cec_notify;
 };
 
@@ -805,8 +808,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
tda998x_edid_delay_start(priv);
} else {
schedule_work(>detect_work);
+
+   mutex_lock(>cec_notify_mutex);
cec_notifier_phys_addr_invalidate(
priv->cec_notify);
+   mutex_unlock(>cec_notify_mutex);
}
 
handled = true;
@@ -1331,6 +1337,8 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
  struct drm_device *drm)
 {
struct drm_connector *connector = >connector;
+   struct cec_connector_info conn_info;
+   struct cec_notifier *notifier;
int ret;
 
connector->interlace_allowed = 1;
@@ -1347,6 +1355,17 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
if (ret)
return ret;
 
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   notifier = cec_notifier_conn_register(priv->cec_glue.parent,
+ NULL, _info);
+   if (!notifier)
+   return -ENOMEM;
+
+   mutex_lock(>cec_notify_mutex);
+   priv->cec_notify = notifier;
+   mutex_unlock(>cec_notify_mutex);
+
drm_connector_attach_encoder(>connector,
 priv->bridge.encoder);
 
@@ -1366,6 +1385,11 @@ static void tda998x_bridge_detach(struct drm_bridge 
*bridge)
 {
struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
 
+   mutex_lock(>cec_notify_mutex);
+   cec_notifier_conn_unregister(priv->cec_notify);
+   priv->cec_notify = NULL;
+   mutex_unlock(>cec_notify_mutex);
+
drm_connector_cleanup(>connector);
 }
 
@@ -1789,8 +1813,6 @@ static void tda998x_destroy(struct device *dev)
cancel_work_sync(>detect_work);
 
i2c_unregister_device(priv->cec);
-
-   cec_notifier_conn_unregister(priv->cec_notify);
 }
 
 static int tda998x_create(struct device *dev)
@@ -1811,6 +1833,7 @@ static int tda998x_create(struct device *dev)
mutex_init(>mutex);   /* protect the page access */
mutex_init(>audio_mutex); /* protect access from audio thread */
mutex_init(>edid_mutex);
+   mutex_init(>cec_notify_mutex);
INIT_LIST_HEAD(>bridge.list);
init_waitqueue_head(>edid_delay_waitq);
timer_setup(>edid_delay_timer, tda998x_edid_delay_done, 0);
@@ -1915,12 +1938,6 @@ static int tda998x_create(struct device *dev)
cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
}
 
-   priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
-   if (!priv->cec_notify) {
-   ret = -ENOMEM;
-   goto fail;
-   }
-
priv->cec_glue.parent = dev;
priv->cec_glue.data = priv;
priv->cec_glue.init = tda998x_cec_hook_init;
-- 
2.23.0



Re: [PATCHv8 1/2] drm: tda998x: use cec_notifier_conn_(un)register

2019-10-17 Thread Hans Verkuil
On 10/16/19 6:14 PM, Russell King - ARM Linux admin wrote:
> On Wed, Oct 16, 2019 at 03:39:15PM +0200, Hans Verkuil wrote:
>> From: Dariusz Marcinkiewicz 
>>
>> Use the new cec_notifier_conn_(un)register() functions to
>> (un)register the notifier for the HDMI connector.
>>
>> Signed-off-by: Dariusz Marcinkiewicz 
>> Signed-off-by: Hans Verkuil 
> 
> Please explain in detail what this mutex actually achieves.

Dariusz, since you're the author, can you reply to Russell?

If this is going to be a delaying factor, then I'll post a new version
without the mutex that just replaces the cec_notifier API.

Regards,

Hans

> 
>> ---
>>  drivers/gpu/drm/i2c/tda998x_drv.c | 21 -
>>  1 file changed, 16 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
>> b/drivers/gpu/drm/i2c/tda998x_drv.c
>> index 84c6d4c91c65..8262b44b776e 100644
>> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
>> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
>> @@ -82,6 +82,9 @@ struct tda998x_priv {
>>  u8 audio_port_enable[AUDIO_ROUTE_NUM];
>>  struct tda9950_glue cec_glue;
>>  struct gpio_desc *calib;
>> +
>> +/* protect cec_notify */
>> +struct mutex cec_notify_mutex;
>>  struct cec_notifier *cec_notify;
>>  };
>>  
>> @@ -805,8 +808,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void 
>> *data)
>>  tda998x_edid_delay_start(priv);
>>  } else {
>>  schedule_work(>detect_work);
>> -cec_notifier_set_phys_addr(priv->cec_notify,
>> -   CEC_PHYS_ADDR_INVALID);
>> +
>> +mutex_lock(>cec_notify_mutex);
>> +cec_notifier_phys_addr_invalidate(
>> +priv->cec_notify);
>> +mutex_unlock(>cec_notify_mutex);
>>  }
>>  
>>  handled = true;
>> @@ -1790,8 +1796,10 @@ static void tda998x_destroy(struct device *dev)
>>  
>>  i2c_unregister_device(priv->cec);
>>  
>> -if (priv->cec_notify)
>> -cec_notifier_put(priv->cec_notify);
>> +mutex_lock(>cec_notify_mutex);
>> +cec_notifier_conn_unregister(priv->cec_notify);
>> +priv->cec_notify = NULL;
>> +mutex_unlock(>cec_notify_mutex);
> 
> By the time we get here:
> 
> 1) The interrupt has been freed (which is a synchronous operation)
>tda998x_irq_thread() can't be called and can't be running, and
>therefore cec_notifier_phys_addr_invalidate() also can't be called
>or be running.
> 2) You don't touch the cec_notifier_set_phys_addr_from_edid() site;
>if there's any case that _might_ possibly conflict, it is that one.
> 3) tda998x_destroy() and tda998x_create() can't be called concurrently
>in any case; the driver model guarantees that ->probe and ->remove
>for the same device are serialised.
> 
>>  }
>>  
>>  static int tda998x_create(struct device *dev)
>> @@ -1812,6 +1820,7 @@ static int tda998x_create(struct device *dev)
>>  mutex_init(>mutex);   /* protect the page access */
>>  mutex_init(>audio_mutex); /* protect access from audio thread */
>>  mutex_init(>edid_mutex);
>> +mutex_init(>cec_notify_mutex);
>>  INIT_LIST_HEAD(>bridge.list);
>>  init_waitqueue_head(>edid_delay_waitq);
>>  timer_setup(>edid_delay_timer, tda998x_edid_delay_done, 0);
>> @@ -1916,7 +1925,9 @@ static int tda998x_create(struct device *dev)
>>  cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
>>  }
>>  
>> -priv->cec_notify = cec_notifier_get(dev);
>> +mutex_lock(>cec_notify_mutex);
>> +priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
>> +mutex_unlock(>cec_notify_mutex);
> 
> and:
> 
> 4) priv->cec_notify will be NULL here until such time that
>cec_notifier_conn_register() has returned.  If the mutex is trying
>to protect something, it's very unclear what it is.
>
> Trying to guess what it's protecting against:
> 
> - Is it protecting against NULL priv->cec_notify?  No, because it can
>   be NULL just before we take the lock.
> - Is it protecting the internals of cec_notifier_conn_register()
>   against the other calls - no, because priv->cec_notify will be NULL
>   until the function has finished.
> -

[PATCHv8 0/2] drm: tda998x: use cec_notifier_conn_(un)register

2019-10-16 Thread Hans Verkuil
This splits the previous v7.2 patch (1) into two parts: one that replaces
cec_notifier_get/put by cec_notifier_conn_(un)register, and one that
sets the connector info.

That second patch moves the CEC notifier code to tda998x_bridge_detach,
but Laurent is making changes in that area and prefers that this isn't
implemented yet.

But the replacement of the cec_notifier_get/put functions is something
that needs to be finished for v5.5.

By splitting this patch up I can merge the first half, but delay the
second half. This tda driver just won't be able to report the connector
information in the meantime.

Regards,

Hans

(1) https://patchwork.linuxtv.org/patch/58464/

Dariusz Marcinkiewicz (2):
  drm: tda998x: use cec_notifier_conn_(un)register
  drm: tda998x: set the connector info

 drivers/gpu/drm/i2c/tda998x_drv.c | 38 ++-
 1 file changed, 27 insertions(+), 11 deletions(-)

-- 
2.23.0



[PATCHv8 1/2] drm: tda998x: use cec_notifier_conn_(un)register

2019-10-16 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 84c6d4c91c65..8262b44b776e 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -82,6 +82,9 @@ struct tda998x_priv {
u8 audio_port_enable[AUDIO_ROUTE_NUM];
struct tda9950_glue cec_glue;
struct gpio_desc *calib;
+
+   /* protect cec_notify */
+   struct mutex cec_notify_mutex;
struct cec_notifier *cec_notify;
 };
 
@@ -805,8 +808,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
tda998x_edid_delay_start(priv);
} else {
schedule_work(>detect_work);
-   cec_notifier_set_phys_addr(priv->cec_notify,
-  CEC_PHYS_ADDR_INVALID);
+
+   mutex_lock(>cec_notify_mutex);
+   cec_notifier_phys_addr_invalidate(
+   priv->cec_notify);
+   mutex_unlock(>cec_notify_mutex);
}
 
handled = true;
@@ -1790,8 +1796,10 @@ static void tda998x_destroy(struct device *dev)
 
i2c_unregister_device(priv->cec);
 
-   if (priv->cec_notify)
-   cec_notifier_put(priv->cec_notify);
+   mutex_lock(>cec_notify_mutex);
+   cec_notifier_conn_unregister(priv->cec_notify);
+   priv->cec_notify = NULL;
+   mutex_unlock(>cec_notify_mutex);
 }
 
 static int tda998x_create(struct device *dev)
@@ -1812,6 +1820,7 @@ static int tda998x_create(struct device *dev)
mutex_init(>mutex);   /* protect the page access */
mutex_init(>audio_mutex); /* protect access from audio thread */
mutex_init(>edid_mutex);
+   mutex_init(>cec_notify_mutex);
INIT_LIST_HEAD(>bridge.list);
init_waitqueue_head(>edid_delay_waitq);
timer_setup(>edid_delay_timer, tda998x_edid_delay_done, 0);
@@ -1916,7 +1925,9 @@ static int tda998x_create(struct device *dev)
cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
}
 
-   priv->cec_notify = cec_notifier_get(dev);
+   mutex_lock(>cec_notify_mutex);
+   priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
+   mutex_unlock(>cec_notify_mutex);
if (!priv->cec_notify) {
ret = -ENOMEM;
goto fail;
-- 
2.23.0



[PATCHv8 2/2] drm: tda998x: set the connector info

2019-10-16 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Fill in the cec_connector_info when calling cec_notifier_conn_register().

Signed-off-by: Dariusz Marcinkiewicz 
Tested-by: Hans Verkuil 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 8262b44b776e..b0620842fa3a 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1337,6 +1337,8 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
  struct drm_device *drm)
 {
struct drm_connector *connector = >connector;
+   struct cec_connector_info conn_info;
+   struct cec_notifier *notifier;
int ret;
 
connector->interlace_allowed = 1;
@@ -1353,6 +1355,17 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
if (ret)
return ret;
 
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   notifier = cec_notifier_conn_register(priv->cec_glue.parent,
+ NULL, _info);
+   if (!notifier)
+   return -ENOMEM;
+
+   mutex_lock(>cec_notify_mutex);
+   priv->cec_notify = notifier;
+   mutex_unlock(>cec_notify_mutex);
+
drm_connector_attach_encoder(>connector,
 priv->bridge.encoder);
 
@@ -1372,6 +1385,11 @@ static void tda998x_bridge_detach(struct drm_bridge 
*bridge)
 {
struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
 
+   mutex_lock(>cec_notify_mutex);
+   cec_notifier_conn_unregister(priv->cec_notify);
+   priv->cec_notify = NULL;
+   mutex_unlock(>cec_notify_mutex);
+
drm_connector_cleanup(>connector);
 }
 
@@ -1795,11 +1813,6 @@ static void tda998x_destroy(struct device *dev)
cancel_work_sync(>detect_work);
 
i2c_unregister_device(priv->cec);
-
-   mutex_lock(>cec_notify_mutex);
-   cec_notifier_conn_unregister(priv->cec_notify);
-   priv->cec_notify = NULL;
-   mutex_unlock(>cec_notify_mutex);
 }
 
 static int tda998x_create(struct device *dev)
@@ -1925,14 +1938,6 @@ static int tda998x_create(struct device *dev)
cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
}
 
-   mutex_lock(>cec_notify_mutex);
-   priv->cec_notify = cec_notifier_conn_register(dev, NULL, NULL);
-   mutex_unlock(>cec_notify_mutex);
-   if (!priv->cec_notify) {
-   ret = -ENOMEM;
-   goto fail;
-   }
-
priv->cec_glue.parent = dev;
priv->cec_glue.data = priv;
priv->cec_glue.init = tda998x_cec_hook_init;
-- 
2.23.0



Re: [PATCH v7 7/9] drm: tegra: use cec_notifier_conn_(un)register

2019-10-14 Thread Hans Verkuil
Thierry,

Another reminder :-)

If you want me to do this, then just let me know!

Regards,

Hans

On 10/4/19 10:48 AM, Hans Verkuil wrote:
> Hi Thierry,
> 
> Just a reminder: this patch hasn't been merged yet for v5.5.
> 
> Thanks!
> 
>   Hans
> 
> On 8/28/19 1:54 PM, Thierry Reding wrote:
>> On Wed, Aug 28, 2019 at 12:06:34PM +0200, Hans Verkuil wrote:
>>> On 8/28/19 11:38 AM, Thierry Reding wrote:
>>>> On Wed, Aug 28, 2019 at 10:09:30AM +0200, Hans Verkuil wrote:
>>>>> Thierry,
>>>>>
>>>>> Can you review this patch?
>>>>>
>>>>> Thanks!
>>>>>
>>>>>   Hans
>>>>
>>>> Did you want me to pick this up into the drm/tegra tree? Or do you want
>>>> to pick it up into your tree?
>>>
>>> Can you pick it up for the next cycle? As you mentioned, we missed the
>>> deadline for 5.4, so this feature won't be enabled in the public CEC API
>>> until 5.5.
>>>
>>> Thanks!
>>
>> Sure, will do.
>>
>> Thierry
>>
> 



Re: [PATCH v1 1/2] drm_dp_cec: drop use of drmP.h

2019-10-09 Thread Hans Verkuil
On 10/7/19 7:12 PM, Sam Ravnborg wrote:
> drmP.h is deprecated and will be deleted.
> Replace use with proper header.
> 
> Divide header includes in blocks while touching these.
> 
> Build tested with various archtectures and configs.

Acked-by: Hans Verkuil 

Regards,

Hans

> 
> Signed-off-by: Sam Ravnborg 
> Fixes: ae85b0df124f6928 ("drm_dp_cec: add connector info support.")
> Cc: Dariusz Marcinkiewicz 
> Cc: Hans Verkuil 
> Cc: Lyude Paul 
> Cc: Ben Skeggs 
> ---
>  drivers/gpu/drm/drm_dp_cec.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
> index b457c16c3a8b..3ab2609f9ec7 100644
> --- a/drivers/gpu/drm/drm_dp_cec.c
> +++ b/drivers/gpu/drm/drm_dp_cec.c
> @@ -8,10 +8,12 @@
>  #include 
>  #include 
>  #include 
> +
> +#include 
> +
>  #include 
> +#include 
>  #include 
> -#include 
> -#include 
>  
>  /*
>   * Unfortunately it turns out that we have a chicken-and-egg situation
> 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: linux-next: build failure after merge of the drm-misc tree

2019-10-08 Thread Hans Verkuil
On 10/8/19 1:30 AM, Stephen Rothwell wrote:
> Hi all,
> 
> After merging the drm-misc tree, today's linux-next build (x86_64
> allmodconfig) failed like this:
> 
> 
> Caused by commit
> 
>   10d8f308ba3e ("cec: add cec_adapter to cec_notifier_cec_adap_unregister()")
> 
> interacting with commit
> 
>   7e86efa2ff03 ("media: cec-gpio: add notifier support")
> 
> form the v4l-dvb tree.
> 
> I have applied the following merge fix patch.

That's the correct fix, thank you!

Regards,

Hans

> 
> From: Stephen Rothwell 
> Date: Tue, 8 Oct 2019 10:26:05 +1100
> Subject: [PATCH] cec: fix up for "cec: add cec_adapter to
>  cec_notifier_cec_adap_unregister()"
> 
> Signed-off-by: Stephen Rothwell 
> ---
>  drivers/media/platform/cec-gpio/cec-gpio.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/cec-gpio/cec-gpio.c 
> b/drivers/media/platform/cec-gpio/cec-gpio.c
> index 7be91e712c4a..42d2c2cd9a78 100644
> --- a/drivers/media/platform/cec-gpio/cec-gpio.c
> +++ b/drivers/media/platform/cec-gpio/cec-gpio.c
> @@ -259,7 +259,7 @@ static int cec_gpio_probe(struct platform_device *pdev)
>   return 0;
>  
>  unreg_notifier:
> - cec_notifier_cec_adap_unregister(cec->notifier);
> + cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
>  del_adap:
>   cec_delete_adapter(cec->adap);
>   return ret;
> @@ -269,7 +269,7 @@ static int cec_gpio_remove(struct platform_device *pdev)
>  {
>   struct cec_gpio *cec = platform_get_drvdata(pdev);
>  
> - cec_notifier_cec_adap_unregister(cec->notifier);
> + cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
>   cec_unregister_adapter(cec->adap);
>   return 0;
>  }
> 



[PATCH] cec: add cec_adapter to cec_notifier_cec_adap_unregister()

2019-10-04 Thread Hans Verkuil
It is possible for one HDMI connector to have multiple CEC adapters. The
typical real-world scenario is that where one adapter is used when the device
is in standby, and one that's better/smarter when the device is powered up.

The cec-notifier changes were made with that in mind, but I missed that in
order to support this you need to tell cec_notifier_cec_adap_unregister()
which adapter you are unregistering from the notifier.

Add this additional argument. It is currently unused, but once all drivers
use this, the CEC core will be adapted for these use-cases.

Signed-off-by: Hans Verkuil 
---
This patch should go in via the drm subsystem since all CEC adapters in the
drm subsystem have been converted to use cec_notifier_cec_adap_unregister().
The media subsystem still has older drm drivers that weren't converted to use
cec_notifier_cec_adap_unregister().

This will only be a problem if a new CEC adapter driver is added to the media
subsystem for v5.5, but I am not aware of any plans for that. Should it happen,
then that just means that the media subsystem needs to resolve a fairly trivial
merge conflict.

Ville, Mauro, can you review/ack?
---
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
index ac1e001d0882..70ab4fbdc23e 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -285,7 +285,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)

ret = cec_register_adapter(cec->adap, pdev->dev.parent);
if (ret < 0) {
-   cec_notifier_cec_adap_unregister(cec->notify);
+   cec_notifier_cec_adap_unregister(cec->notify, cec->adap);
return ret;
}

@@ -302,7 +302,7 @@ static int dw_hdmi_cec_remove(struct platform_device *pdev)
 {
struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);

-   cec_notifier_cec_adap_unregister(cec->notify);
+   cec_notifier_cec_adap_unregister(cec->notify, cec->adap);
cec_unregister_adapter(cec->adap);

return 0;
diff --git a/drivers/gpu/drm/i2c/tda9950.c b/drivers/gpu/drm/i2c/tda9950.c
index a5a75bdeb7a5..5b03fdd1eaa4 100644
--- a/drivers/gpu/drm/i2c/tda9950.c
+++ b/drivers/gpu/drm/i2c/tda9950.c
@@ -465,7 +465,7 @@ static int tda9950_probe(struct i2c_client *client,

ret = cec_register_adapter(priv->adap, priv->hdmi);
if (ret < 0) {
-   cec_notifier_cec_adap_unregister(priv->notify);
+   cec_notifier_cec_adap_unregister(priv->notify, priv->adap);
return ret;
}

@@ -482,7 +482,7 @@ static int tda9950_remove(struct i2c_client *client)
 {
struct tda9950_priv *priv = i2c_get_clientdata(client);

-   cec_notifier_cec_adap_unregister(priv->notify);
+   cec_notifier_cec_adap_unregister(priv->notify, priv->adap);
cec_unregister_adapter(priv->adap);

return 0;
diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 4d82a5522072..7cf42b133dbc 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -153,13 +153,14 @@ cec_notifier_cec_adap_register(struct device *hdmi_dev, 
const char *conn_name,
 }
 EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_register);

-void cec_notifier_cec_adap_unregister(struct cec_notifier *n)
+void cec_notifier_cec_adap_unregister(struct cec_notifier *n,
+ struct cec_adapter *adap)
 {
if (!n)
return;

mutex_lock(>lock);
-   n->cec_adap->notifier = NULL;
+   adap->notifier = NULL;
n->cec_adap = NULL;
n->callback = NULL;
mutex_unlock(>lock);
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c 
b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
index 4a3b3810fd89..f048e8994785 100644
--- a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -314,7 +314,8 @@ static int cros_ec_cec_probe(struct platform_device *pdev)
return 0;

 out_probe_notify:
-   cec_notifier_cec_adap_unregister(cros_ec_cec->notify);
+   cec_notifier_cec_adap_unregister(cros_ec_cec->notify,
+cros_ec_cec->adap);
 out_probe_adapter:
cec_delete_adapter(cros_ec_cec->adap);
return ret;
@@ -335,7 +336,8 @@ static int cros_ec_cec_remove(struct platform_device *pdev)
return ret;
}

-   cec_notifier_cec_adap_unregister(cros_ec_cec->notify);
+   cec_notifier_cec_adap_unregister(cros_ec_cec->notify,
+cros_ec_cec->adap);
cec_unregister_adapter(cros_ec_cec->adap);

return 0;
diff --git a/drivers/media/platform/meson/ao-cec-g12a.c 
b/drivers/media/platform/meson/ao-cec-g12a.c
index 3b39e875292e..70f875b4a01e 100644
--- a/dri

Re: [PATCH v7 7/9] drm: tegra: use cec_notifier_conn_(un)register

2019-10-04 Thread Hans Verkuil
Hi Thierry,

Just a reminder: this patch hasn't been merged yet for v5.5.

Thanks!

Hans

On 8/28/19 1:54 PM, Thierry Reding wrote:
> On Wed, Aug 28, 2019 at 12:06:34PM +0200, Hans Verkuil wrote:
>> On 8/28/19 11:38 AM, Thierry Reding wrote:
>>> On Wed, Aug 28, 2019 at 10:09:30AM +0200, Hans Verkuil wrote:
>>>> Thierry,
>>>>
>>>> Can you review this patch?
>>>>
>>>> Thanks!
>>>>
>>>>Hans
>>>
>>> Did you want me to pick this up into the drm/tegra tree? Or do you want
>>> to pick it up into your tree?
>>
>> Can you pick it up for the next cycle? As you mentioned, we missed the
>> deadline for 5.4, so this feature won't be enabled in the public CEC API
>> until 5.5.
>>
>> Thanks!
> 
> Sure, will do.
> 
> Thierry
> 



Re: [PATCH] drivers: video: hdmi: log ext colorimetry applicability

2019-10-03 Thread Hans Verkuil
On 10/3/19 3:44 PM, Ville Syrjälä wrote:
> On Thu, Oct 03, 2019 at 09:15:49AM +0200, Johan Korsnes wrote:
>> When logging the AVI InfoFrame, clearly indicate whether or not the
>> extended colorimetry attribute is active. This is only the case when
>> the AVI InfoFrame colorimetry attribute is set to extended. [0]
>>
>> [0] CTA-861-G section 6.4 page 57
>>
>> Signed-off-by: Johan Korsnes 
>> ---
>>  drivers/video/hdmi.c | 8 +++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
>> index f29db728ff29..a709e38a53ca 100644
>> --- a/drivers/video/hdmi.c
>> +++ b/drivers/video/hdmi.c
>> @@ -682,8 +682,14 @@ static void hdmi_avi_infoframe_log(const char *level,
>>  hdmi_log("active aspect: %s\n",
>>  hdmi_active_aspect_get_name(frame->active_aspect));
>>  hdmi_log("itc: %s\n", frame->itc ? "IT Content" : "No Data");
>> -hdmi_log("extended colorimetry: %s\n",
>> +
>> +if (frame->colorimetry == HDMI_COLORIMETRY_EXTENDED)
>> +hdmi_log("extended colorimetry: %s\n",
>>  
>> hdmi_extended_colorimetry_get_name(frame->extended_colorimetry));
>> +else
>> +hdmi_log("extended colorimetry: N/A (0x%x)\n",
>> +frame->extended_colorimetry);
> 
> Yeah, seems fine. Might make the logs a bit less confusing at least.
> 
> Reviewed-by: Ville Syrjälä 
> 
> PS. would be nice it someone were to extend this code to deal with the
> ACE bits too. Do you have plans/interest in doing that?

If we tackle this, then it would be part of a larger effort in updating
this code. There are more fields missing in other InfoFrames as well.

So yes, we have interest in this, but no, there are no plans :-)

Regards,

Hans

> 
>> +
>>  hdmi_log("quantization range: %s\n",
>>  
>> hdmi_quantization_range_get_name(frame->quantization_range));
>>  hdmi_log("nups: %s\n", hdmi_nups_get_name(frame->nups));
>> -- 
>> 2.20.1
>>
>> ___
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



Re: [PATCH] drivers: video: hdmi: log ext colorimetry applicability

2019-10-03 Thread Hans Verkuil
On 10/3/19 9:15 AM, Johan Korsnes wrote:
> When logging the AVI InfoFrame, clearly indicate whether or not the
> extended colorimetry attribute is active. This is only the case when
> the AVI InfoFrame colorimetry attribute is set to extended. [0]
> 
> [0] CTA-861-G section 6.4 page 57
> 
> Signed-off-by: Johan Korsnes 
> ---
>  drivers/video/hdmi.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> index f29db728ff29..a709e38a53ca 100644
> --- a/drivers/video/hdmi.c
> +++ b/drivers/video/hdmi.c
> @@ -682,8 +682,14 @@ static void hdmi_avi_infoframe_log(const char *level,
>   hdmi_log("active aspect: %s\n",
>   hdmi_active_aspect_get_name(frame->active_aspect));
>   hdmi_log("itc: %s\n", frame->itc ? "IT Content" : "No Data");
> - hdmi_log("extended colorimetry: %s\n",
> +
> + if (frame->colorimetry == HDMI_COLORIMETRY_EXTENDED)
> + hdmi_log("extended colorimetry: %s\n",
>   
> hdmi_extended_colorimetry_get_name(frame->extended_colorimetry));
> + else
> + hdmi_log("extended colorimetry: N/A (0x%x)\n",
> + frame->extended_colorimetry);
> +
>   hdmi_log("quantization range: %s\n",
>   
> hdmi_quantization_range_get_name(frame->quantization_range));
>   hdmi_log("nups: %s\n", hdmi_nups_get_name(frame->nups));
> 

I just realized that there are more fields like that:

content_type is only valid if itc == true

quantization_range is only valid if colorspace is RGB

ycc_quantization_range is only valid if colorspace is YCC

Can you make a v2 where these fields are handled in the same way?
That would really help reduce the confusion when logging the
AVI InfoFrame.

Regards,

Hans


Re: [PATCH v7 7/9] drm: tegra: use cec_notifier_conn_(un)register

2019-08-28 Thread Hans Verkuil
On 8/28/19 11:38 AM, Thierry Reding wrote:
> On Wed, Aug 28, 2019 at 10:09:30AM +0200, Hans Verkuil wrote:
>> Thierry,
>>
>> Can you review this patch?
>>
>> Thanks!
>>
>>  Hans
> 
> Did you want me to pick this up into the drm/tegra tree? Or do you want
> to pick it up into your tree?

Can you pick it up for the next cycle? As you mentioned, we missed the
deadline for 5.4, so this feature won't be enabled in the public CEC API
until 5.5.

Thanks!

Hans

> 
> We're just past the DRM subsystem deadline, so it'll have to wait until
> the next cycle if we go that way. If you're in a hurry you may want to
> pick it up yourself, in which case:
> 
> Acked-by: Thierry Reding 
> 
>> On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
>>> Use the new cec_notifier_conn_(un)register() functions to
>>> (un)register the notifier for the HDMI connector, and fill in
>>> the cec_connector_info.
>>>
>>> Changes since v4:
>>> - only create a CEC notifier for HDMI connectors
>>>
>>> Signed-off-by: Dariusz Marcinkiewicz 
>>> Tested-by: Hans Verkuil 
>>> ---
>>>  drivers/gpu/drm/tegra/output.c | 28 +---
>>>  1 file changed, 21 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
>>> index bdcaa4c7168cf..34373734ff689 100644
>>> --- a/drivers/gpu/drm/tegra/output.c
>>> +++ b/drivers/gpu/drm/tegra/output.c
>>> @@ -70,6 +70,11 @@ tegra_output_connector_detect(struct drm_connector 
>>> *connector, bool force)
>>>  
>>>  void tegra_output_connector_destroy(struct drm_connector *connector)
>>>  {
>>> +   struct tegra_output *output = connector_to_output(connector);
>>> +
>>> +   if (output->cec)
>>> +   cec_notifier_conn_unregister(output->cec);
>>> +
>>> drm_connector_unregister(connector);
>>> drm_connector_cleanup(connector);
>>>  }
>>> @@ -163,18 +168,11 @@ int tegra_output_probe(struct tegra_output *output)
>>> disable_irq(output->hpd_irq);
>>> }
>>>  
>>> -   output->cec = cec_notifier_get(output->dev);
>>> -   if (!output->cec)
>>> -   return -ENOMEM;
>>> -
>>> return 0;
>>>  }
>>>  
>>>  void tegra_output_remove(struct tegra_output *output)
>>>  {
>>> -   if (output->cec)
>>> -   cec_notifier_put(output->cec);
>>> -
>>> if (output->hpd_gpio)
>>> free_irq(output->hpd_irq, output);
>>>  
>>> @@ -184,6 +182,7 @@ void tegra_output_remove(struct tegra_output *output)
>>>  
>>>  int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
>>>  {
>>> +   int connector_type;
>>> int err;
>>>  
>>> if (output->panel) {
>>> @@ -199,6 +198,21 @@ int tegra_output_init(struct drm_device *drm, struct 
>>> tegra_output *output)
>>> if (output->hpd_gpio)
>>> enable_irq(output->hpd_irq);
>>>  
>>> +   connector_type = output->connector.connector_type;
>>> +   /*
>>> +* Create a CEC notifier for HDMI connector.
>>> +*/
>>> +   if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
>>> +   connector_type == DRM_MODE_CONNECTOR_HDMIB) {
>>> +   struct cec_connector_info conn_info;
>>> +
>>> +   cec_fill_conn_info_from_drm(_info, >connector);
>>> +   output->cec = cec_notifier_conn_register(output->dev, NULL,
>>> +_info);
>>> +   if (!output->cec)
>>> +   return -ENOMEM;
>>> +   }
>>> +
>>> return 0;
>>>  }
>>>  
>>>
>>



Re: [PATCH v7 7/9] drm: tegra: use cec_notifier_conn_(un)register

2019-08-28 Thread Hans Verkuil
Thierry,

Can you review this patch?

Thanks!

Hans

On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill in
> the cec_connector_info.
> 
> Changes since v4:
>   - only create a CEC notifier for HDMI connectors
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> Tested-by: Hans Verkuil 
> ---
>  drivers/gpu/drm/tegra/output.c | 28 +---
>  1 file changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
> index bdcaa4c7168cf..34373734ff689 100644
> --- a/drivers/gpu/drm/tegra/output.c
> +++ b/drivers/gpu/drm/tegra/output.c
> @@ -70,6 +70,11 @@ tegra_output_connector_detect(struct drm_connector 
> *connector, bool force)
>  
>  void tegra_output_connector_destroy(struct drm_connector *connector)
>  {
> + struct tegra_output *output = connector_to_output(connector);
> +
> + if (output->cec)
> + cec_notifier_conn_unregister(output->cec);
> +
>   drm_connector_unregister(connector);
>   drm_connector_cleanup(connector);
>  }
> @@ -163,18 +168,11 @@ int tegra_output_probe(struct tegra_output *output)
>   disable_irq(output->hpd_irq);
>   }
>  
> - output->cec = cec_notifier_get(output->dev);
> - if (!output->cec)
> - return -ENOMEM;
> -
>   return 0;
>  }
>  
>  void tegra_output_remove(struct tegra_output *output)
>  {
> - if (output->cec)
> - cec_notifier_put(output->cec);
> -
>   if (output->hpd_gpio)
>   free_irq(output->hpd_irq, output);
>  
> @@ -184,6 +182,7 @@ void tegra_output_remove(struct tegra_output *output)
>  
>  int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
>  {
> + int connector_type;
>   int err;
>  
>   if (output->panel) {
> @@ -199,6 +198,21 @@ int tegra_output_init(struct drm_device *drm, struct 
> tegra_output *output)
>   if (output->hpd_gpio)
>   enable_irq(output->hpd_irq);
>  
> + connector_type = output->connector.connector_type;
> + /*
> +  * Create a CEC notifier for HDMI connector.
> +  */
> + if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
> + connector_type == DRM_MODE_CONNECTOR_HDMIB) {
> + struct cec_connector_info conn_info;
> +
> + cec_fill_conn_info_from_drm(_info, >connector);
> + output->cec = cec_notifier_conn_register(output->dev, NULL,
> +  _info);
> + if (!output->cec)
> + return -ENOMEM;
> + }
> +
>   return 0;
>  }
>  
> 



Re: [PATCHv10 2/2] cec: document CEC_ADAP_G_CONNECTOR_INFO and capability

2019-08-28 Thread Hans Verkuil
On 8/28/19 9:27 AM, Dariusz Marcinkiewicz wrote:
> Hi.
> 
> Should this patch also have an explicit From tag?

Oops, sorry, it was lost at some point.

This is the list of all cec patches for drm:

https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=cec-drm

The first 5 patches are pushed (drm_dp_cec up to vc4), but the
drm_dp_cec/i915/vc4 patches were pushed too late for kernel 5.4 :-(

So my plan is to get the others in for 5.5. I'll merge the last
two patches that enable the API early in the 5.5 cycle in the media
tree (so right after v5.4-rc1 is released) and work to get the remaining
Acks for the other drm cec patches.

Regards,

Hans

> 
> On Fri, Aug 23, 2019 at 2:21 PM Hans Verkuil  wrote:
>>
>> Document the new CEC_ADAP_G_CONNECTOR_INFO ioctl and the new
>> CEC_CAP_CONNECTOR_INFO capability.
>>
>> Signed-off-by: Dariusz Marcinkiewicz 
>> Co-developed-by: Hans Verkuil 
>> [hverkuil-ci...@xs4all.nl: added CEC_CAP_CONNECTOR_INFO]
>> [hverkuil-ci...@xs4all.nl: added DQEVENT have_conn_info]
>> Signed-off-by: Hans Verkuil 
>> ---
> ...
> 



Re: [PATCH v2 44/50] drm/omap: dpi: Register a drm_bridge

2019-08-27 Thread Hans Verkuil
Hi Laurent,

I tried this series with my Pandaboard, but it broke my Pandaboard. After
doing a git bisect it ended up with this patch as the culprit.

If I boot my Pandaboard I get this:

[3.271881] omapdss_dss 5800.dss: 5800.dss supply vdda_video not 
found, using dummy regulator
[3.285369] omapdss_dss 5800.dss: 5800.dss supply vdda_video not 
found, using dummy regulator
[   24.286773] rcu: INFO: rcu_sched self-detected stall on CPU
[   24.292388] rcu: 0-...!: (1306 ticks this GP) idle=6b6/1/0x4002 
softirq=85/85 fqs=19
[   24.300689]  (t=2100 jiffies g=-1063 q=10)
[   24.304809] rcu: rcu_sched kthread starved for 2058 jiffies! g-1063 f0x0 
RCU_GP_WAIT_FQS(5) ->state=0x402 ->cpu=1
[   24.315124] rcu: RCU grace-period kthread stack dump:
[   24.315124] rcu_sched   I010  2 0x
[   24.325805] [] (__schedule) from [] (schedule+0x40/0xc0)
[   24.332885] [] (schedule) from [] 
(schedule_timeout+0x174/0x2a8)
[   24.340698] [] (schedule_timeout) from [] 
(rcu_gp_kthread+0x49c/0x9f4)
[   24.349121] [] (rcu_gp_kthread) from [] 
(kthread+0x13c/0x148)
[   24.356658] [] (kthread) from [] 
(ret_from_fork+0x14/0x2c)
[   24.363922] Exception stack(0xe70a1fb0 to 0xe70a1ff8)
[   24.363922] 1fa0:   
 
[   24.363922] 1fc0:       
 
[   24.385437] 1fe0:     0013 
[   24.392089] NMI backtrace for cpu 0
[   24.392120] CPU: 0 PID: 105 Comm: kworker/0:2 Not tainted 5.3.0-rc3-arm #152
[   24.392120] Hardware name: Generic OMAP4 (Flattened Device Tree)
[   24.408721] Workqueue: events deferred_probe_work_func
[   24.408721] [] (unwind_backtrace) from [] 
(show_stack+0x10/0x14)
[   24.421783] [] (show_stack) from [] 
(dump_stack+0x84/0x9c)
[   24.429077] [] (dump_stack) from [] 
(nmi_cpu_backtrace+0x8c/0xc0)
[   24.436950] [] (nmi_cpu_backtrace) from [] 
(nmi_trigger_cpumask_backtrace+0x114/0x12c)
[   24.446655] [] (nmi_trigger_cpumask_backtrace) from [] 
(rcu_dump_cpu_stacks+0xa4/0xcc)
[   24.456359] [] (rcu_dump_cpu_stacks) from [] 
(rcu_sched_clock_irq+0x608/0x7f8)
[   24.465362] [] (rcu_sched_clock_irq) from [] 
(update_process_times+0x34/0x6c)
[   24.465362] [] (update_process_times) from [] 
(tick_sched_timer+0x4c/0xa8)
[   24.483001] [] (tick_sched_timer) from [] 
(__hrtimer_run_queues+0x154/0x1fc)
[   24.491851] [] (__hrtimer_run_queues) from [] 
(hrtimer_interrupt+0x11c/0x2ac)
[   24.500762] [] (hrtimer_interrupt) from [] 
(twd_handler+0x30/0x38)
[   24.500762] [] (twd_handler) from [] 
(handle_percpu_devid_irq+0x78/0x138)
[   24.517333] [] (handle_percpu_devid_irq) from [] 
(generic_handle_irq+0x24/0x34)
[   24.526458] [] (generic_handle_irq) from [] 
(__handle_domain_irq+0x5c/0xb4)
[   24.526458] [] (__handle_domain_irq) from [] 
(gic_handle_irq+0x58/0x9c)
[   24.526458] [] (gic_handle_irq) from [] 
(__irq_svc+0x6c/0x90)
[   24.526458] Exception stack(0xe6439d68 to 0xe6439db0)
[   24.551177] 9d60:   c0f783e8   efdb49d0 
e647f2e8 efdb7f74
[   24.551177] 9d80: e647f2e8  e647f294 e647f2e8  efdb5a98 
 e6439db8
[   24.551177] 9da0: c04e9830 c04e9858 2153 
[   24.577789] [] (__irq_svc) from [] 
(of_drm_find_bridge+0x40/0x84)
[   24.577789] [] (of_drm_find_bridge) from [] 
(omapdss_device_init_output+0x38/0x140)
[   24.595153] [] (omapdss_device_init_output) from [] 
(dpi_init_port+0x208/0x294)
[   24.604248] [] (dpi_init_port) from [] 
(dss_probe+0x2b4/0x550)
[   24.604248] [] (dss_probe) from [] 
(platform_drv_probe+0x48/0x98)
[   24.604248] [] (platform_drv_probe) from [] 
(really_probe+0xf0/0x2c4)
[   24.627990] [] (really_probe) from [] 
(driver_probe_device+0x60/0x168)
[   24.627990] [] (driver_probe_device) from [] 
(bus_for_each_drv+0x84/0xc8)
[   24.644866] [] (bus_for_each_drv) from [] 
(__device_attach+0xd4/0x140)
[   24.644866] [] (__device_attach) from [] 
(bus_probe_device+0x84/0x8c)
[   24.661376] [] (bus_probe_device) from [] 
(deferred_probe_work_func+0x64/0x90)
[   24.670379] [] (deferred_probe_work_func) from [] 
(process_one_work+0x204/0x41c)
[   24.670410] [] (process_one_work) from [] 
(worker_thread+0x2a8/0x5bc)
[   24.687805] [] (worker_thread) from [] 
(kthread+0x13c/0x148)
[   24.687805] [] (kthread) from [] 
(ret_from_fork+0x14/0x2c)
[   24.702484] Exception stack(0xe6439fb0 to 0xe6439ff8)
[   24.702484] 9fa0:   
 
[   24.702484] 9fc0:       
 
[   24.723999] 9fe0:     0013 

I can send my .config upon request if needed.

CONFIG_OMAP2_DSS_DPI is 'y', but there is nothing connected to the DPI port.

Regards,

Hans

On 8/20/19 3:17 AM, Laurent Pinchart wrote:
> In order to integrate with a chain of drm_bridge, the internal DPI
> 

Re: [PATCH v7 1/9] drm_dp_cec: add connector info support.

2019-08-27 Thread Hans Verkuil
On 8/22/19 10:08 AM, Hans Verkuil wrote:
> Alex, Ville/Rodrigo, Ben,
> 
> Can you (hopefully) Ack this patch so that I can merge it?

Ping!

Regards,

Hans

> 
> Thank you!
> 
>   Hans
> 
> On 8/14/19 12:44 PM, Dariusz Marcinkiewicz wrote:
>> Pass the connector info to the CEC adapter. This makes it possible
>> to associate the CEC adapter with the corresponding drm connector.
>>
>> Signed-off-by: Dariusz Marcinkiewicz 
>> Signed-off-by: Hans Verkuil 
>> Tested-by: Hans Verkuil 
>> ---
>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  2 +-
>>  drivers/gpu/drm/drm_dp_cec.c  | 25 ---
>>  drivers/gpu/drm/i915/display/intel_dp.c   |  4 +--
>>  drivers/gpu/drm/nouveau/nouveau_connector.c   |  3 +--
>>  include/drm/drm_dp_helper.h   | 17 ++---
>>  5 files changed, 27 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> index 16218a202b591..5ec14efd4d8cb 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> @@ -416,7 +416,7 @@ void amdgpu_dm_initialize_dp_connector(struct 
>> amdgpu_display_manager *dm,
>>  
>>  drm_dp_aux_register(>dm_dp_aux.aux);
>>  drm_dp_cec_register_connector(>dm_dp_aux.aux,
>> -  aconnector->base.name, dm->adev->dev);
>> +  >base);
>>  aconnector->mst_mgr.cbs = _mst_cbs;
>>  drm_dp_mst_topology_mgr_init(
>>  >mst_mgr,
>> diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
>> index b15cee85b702b..b457c16c3a8bb 100644
>> --- a/drivers/gpu/drm/drm_dp_cec.c
>> +++ b/drivers/gpu/drm/drm_dp_cec.c
>> @@ -8,7 +8,9 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>> +#include 
>>  #include 
>>  
>>  /*
>> @@ -295,7 +297,10 @@ static void drm_dp_cec_unregister_work(struct 
>> work_struct *work)
>>   */
>>  void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
>>  {
>> -u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
>> +struct drm_connector *connector = aux->cec.connector;
>> +u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
>> +   CEC_CAP_CONNECTOR_INFO;
>> +struct cec_connector_info conn_info;
>>  unsigned int num_las = 1;
>>  u8 cap;
>>  
>> @@ -344,13 +349,17 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
>> struct edid *edid)
>>  
>>  /* Create a new adapter */
>>  aux->cec.adap = cec_allocate_adapter(_dp_cec_adap_ops,
>> - aux, aux->cec.name, cec_caps,
>> + aux, connector->name, cec_caps,
>>   num_las);
>>  if (IS_ERR(aux->cec.adap)) {
>>  aux->cec.adap = NULL;
>>  goto unlock;
>>  }
>> -if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
>> +
>> +cec_fill_conn_info_from_drm(_info, connector);
>> +cec_s_conn_info(aux->cec.adap, _info);
>> +
>> +if (cec_register_adapter(aux->cec.adap, connector->dev->dev)) {
>>  cec_delete_adapter(aux->cec.adap);
>>  aux->cec.adap = NULL;
>>  } else {
>> @@ -406,22 +415,20 @@ EXPORT_SYMBOL(drm_dp_cec_unset_edid);
>>  /**
>>   * drm_dp_cec_register_connector() - register a new connector
>>   * @aux: DisplayPort AUX channel
>> - * @name: name of the CEC device
>> - * @parent: parent device
>> + * @connector: drm connector
>>   *
>>   * A new connector was registered with associated CEC adapter name and
>>   * CEC adapter parent device. After registering the name and parent
>>   * drm_dp_cec_set_edid() is called to check if the connector supports
>>   * CEC and to register a CEC adapter if that is the case.
>>   */
>> -void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
>> -   struct device *parent)
>> +void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
>> +   struct drm_connector *connector)
>>  {
>>  WARN_ON(aux->cec.adap);
>>  if (WARN_ON(!aux->transfer))
>> 

Re: [PATCH 3/3] drm/bridge/adv7511: enable CEC connector info

2019-08-26 Thread Hans Verkuil
On 8/26/19 12:13 PM, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Mon, Aug 26, 2019 at 11:01:40AM +0200, Hans Verkuil wrote:
>> On 8/23/19 9:01 PM, Laurent Pinchart wrote:
>>> (And CC'ing Andrzej Hajda and Neil Armstrong as the new DRM bridge
>>> maintainers, as well as Boris Brezillon, to make sure they're aware of
>>> the problem)
>>>
>>> I would really appreciate if we could delay merging this series and
>>> other similar changes until we find a proper solution.
>>>
>>> On Fri, Aug 23, 2019 at 09:58:47PM +0300, Laurent Pinchart wrote:
>>>> On Fri, Aug 23, 2019 at 01:24:27PM +0200, Hans Verkuil wrote:
>>>>> Set the connector info to help userspace associate the CEC adapter
>>>>> with the HDMI connector.
>>>>>
>>>>> This required that the cec initialization and unregistering the
>>>>> CEC adapter takes place in the bridge attach and detach ops.
>>>>>
>>>>> Tested on an R-Car Koelsch board.
>>>>>
>>>>> Signed-off-by: Hans Verkuil 
>>>>> Tested-by: Hans Verkuil 
>>>>> ---
>>>>>  drivers/gpu/drm/bridge/adv7511/adv7511_cec.c |  7 ++-
>>>>>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++--
>>>>>  2 files changed, 17 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c 
>>>>> b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>>>>> index a20a45c0b353..accf5e232396 100644
>>>>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>>>>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>>>>> @@ -302,6 +302,7 @@ static int adv7511_cec_parse_dt(struct device *dev, 
>>>>> struct adv7511 *adv7511)
>>>>>  
>>>>>  int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
>>>>>  {
>>>>> + struct cec_connector_info conn_info;
>>>>>   unsigned int offset = adv7511->type == ADV7533 ?
>>>>>   ADV7533_REG_CEC_OFFSET : 0;
>>>>>   int ret = adv7511_cec_parse_dt(dev, adv7511);
>>>>> @@ -310,7 +311,8 @@ int adv7511_cec_init(struct device *dev, struct 
>>>>> adv7511 *adv7511)
>>>>>   goto err_cec_parse_dt;
>>>>>  
>>>>>   adv7511->cec_adap = cec_allocate_adapter(_cec_adap_ops,
>>>>> - adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS);
>>>>> + adv7511, dev_name(dev),
>>>>> + CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO, ADV7511_MAX_ADDRS);
>>>>>   if (IS_ERR(adv7511->cec_adap)) {
>>>>>   ret = PTR_ERR(adv7511->cec_adap);
>>>>>   goto err_cec_alloc;
>>>>> @@ -331,6 +333,9 @@ int adv7511_cec_init(struct device *dev, struct 
>>>>> adv7511 *adv7511)
>>>>>ADV7511_REG_CEC_CLK_DIV + offset,
>>>>>((adv7511->cec_clk_freq / 75) - 1) << 2);
>>>>>  
>>>>> + cec_fill_conn_info_from_drm(_info, >connector);
>>>>> + cec_s_conn_info(adv7511->cec_adap, _info);
>>>>
>>>> I'm painfully trying to decouple bridges and connectors, if we keep
>>>> merging patches that go in the opposite direction, I'll never manage to
>>>> complete this :-(
>>>>
>>>> Bridges are moving to a model where they won't create connectors
>>>> themselves, so any new access to drm_connector contained in a bridge
>>>> structure is a no-go I'm afraid (I'm replying to this patch as I know
>>>> this driver best, but this comment applies to the other two patches in
>>>> the series as well).
>>>>
>>>> Here's what I wrote in a private e-mail, regarding similar changes for
>>>> the omapdrm driver.
>>>>
>>>> 
>>>> Please have a look at "[PATCH 00/60] drm/omap: Replace custom display
>>>> drivers with drm_bridge and drm_panel", available in a new version at
>>>>
>>>>git://linuxtv.org/pinchartl/media.git omapdrm/bridge/devel
>>>>
>>>> (I will post v2 soon)
>>>>
>>>> The patches show the direction the omapdrm driver is taking. The goal is
>>>> to decouple connectors from bridges, which I'm afraid will have an
>>>> impact on associating drm_connect

Re: [PATCH 3/3] drm/bridge/adv7511: enable CEC connector info

2019-08-26 Thread Hans Verkuil
On 8/23/19 9:01 PM, Laurent Pinchart wrote:
> (And CC'ing Andrzej Hajda and Neil Armstrong as the new DRM bridge
> maintainers, as well as Boris Brezillon, to make sure they're aware of
> the problem)
> 
> I would really appreciate if we could delay merging this series and
> other similar changes until we find a proper solution.
> 
> On Fri, Aug 23, 2019 at 09:58:47PM +0300, Laurent Pinchart wrote:
>> Hi Hans,
>>
>> Thank you for the patch.
>>
>> On Fri, Aug 23, 2019 at 01:24:27PM +0200, Hans Verkuil wrote:
>>> Set the connector info to help userspace associate the CEC adapter
>>> with the HDMI connector.
>>>
>>> This required that the cec initialization and unregistering the
>>> CEC adapter takes place in the bridge attach and detach ops.
>>>
>>> Tested on an R-Car Koelsch board.
>>>
>>> Signed-off-by: Hans Verkuil 
>>> Tested-by: Hans Verkuil 
>>> ---
>>>  drivers/gpu/drm/bridge/adv7511/adv7511_cec.c |  7 ++-
>>>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++--
>>>  2 files changed, 17 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c 
>>> b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>>> index a20a45c0b353..accf5e232396 100644
>>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>>> @@ -302,6 +302,7 @@ static int adv7511_cec_parse_dt(struct device *dev, 
>>> struct adv7511 *adv7511)
>>>  
>>>  int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
>>>  {
>>> +   struct cec_connector_info conn_info;
>>> unsigned int offset = adv7511->type == ADV7533 ?
>>> ADV7533_REG_CEC_OFFSET : 0;
>>> int ret = adv7511_cec_parse_dt(dev, adv7511);
>>> @@ -310,7 +311,8 @@ int adv7511_cec_init(struct device *dev, struct adv7511 
>>> *adv7511)
>>> goto err_cec_parse_dt;
>>>  
>>> adv7511->cec_adap = cec_allocate_adapter(_cec_adap_ops,
>>> -   adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS);
>>> +   adv7511, dev_name(dev),
>>> +   CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO, ADV7511_MAX_ADDRS);
>>> if (IS_ERR(adv7511->cec_adap)) {
>>> ret = PTR_ERR(adv7511->cec_adap);
>>> goto err_cec_alloc;
>>> @@ -331,6 +333,9 @@ int adv7511_cec_init(struct device *dev, struct adv7511 
>>> *adv7511)
>>>  ADV7511_REG_CEC_CLK_DIV + offset,
>>>  ((adv7511->cec_clk_freq / 75) - 1) << 2);
>>>  
>>> +   cec_fill_conn_info_from_drm(_info, >connector);
>>> +   cec_s_conn_info(adv7511->cec_adap, _info);
>>
>> I'm painfully trying to decouple bridges and connectors, if we keep
>> merging patches that go in the opposite direction, I'll never manage to
>> complete this :-(
>>
>> Bridges are moving to a model where they won't create connectors
>> themselves, so any new access to drm_connector contained in a bridge
>> structure is a no-go I'm afraid (I'm replying to this patch as I know
>> this driver best, but this comment applies to the other two patches in
>> the series as well).
>>
>> Here's what I wrote in a private e-mail, regarding similar changes for
>> the omapdrm driver.
>>
>> 
>> Please have a look at "[PATCH 00/60] drm/omap: Replace custom display
>> drivers with drm_bridge and drm_panel", available in a new version at
>>
>>  git://linuxtv.org/pinchartl/media.git omapdrm/bridge/devel
>>
>> (I will post v2 soon)
>>
>> The patches show the direction the omapdrm driver is taking. The goal is
>> to decouple connectors from bridges, which I'm afraid will have an
>> impact on associating drm_connector with a CEC adapter. This should be
>> implemented through new drm_bridge operations, as bridges, when created,
>> will not create drm_connector anymore.
>>
>> I've solved a similar problem related to associating DRM connectors with
>> an I2C adapter for DDC. Please see the drm_bridge_connector_init()
>> function and how the DDC adapter is handled. Something similar could be
>> done for CEC.
>> 
>>
>> Since then v2 has been posted ("[PATCH v2 00/50] drm/omap: Replace
>> custom display drivers with drm_bridge and drm_panel") and v3 is in
>> preparation.
>>
>> So, please, let's both

Re: [PATCH v7 2/9] drm/i915/intel_hdmi: use cec_notifier_conn_(un)register

2019-08-26 Thread Hans Verkuil
On 8/22/19 10:03 AM, Hans Verkuil wrote:
> Ville or Rodrigo,
> 
> Can one of you either merge this patch or Ack it so that I can merge this?

Ping!

Regards,

Hans

> 
> Thank you!
> 
> Regards,
> 
>   Hans
> 
> On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
>> Use the new cec_notifier_conn_(un)register() functions to
>> (un)register the notifier for the HDMI connector, and fill in
>> the cec_connector_info.
>>
>> Signed-off-by: Dariusz Marcinkiewicz 
>> Signed-off-by: Hans Verkuil 
>> Tested-by: Hans Verkuil 
>> ---
>>  drivers/gpu/drm/i915/display/intel_hdmi.c | 13 +
>>  1 file changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
>> b/drivers/gpu/drm/i915/display/intel_hdmi.c
>> index b1ca8e5bdb56d..9fcf2c58c29c5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
>> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
>> @@ -2752,8 +2752,9 @@ intel_hdmi_connector_register(struct drm_connector 
>> *connector)
>>  
>>  static void intel_hdmi_destroy(struct drm_connector *connector)
>>  {
>> -if (intel_attached_hdmi(connector)->cec_notifier)
>> -cec_notifier_put(intel_attached_hdmi(connector)->cec_notifier);
>> +struct cec_notifier *n = intel_attached_hdmi(connector)->cec_notifier;
>> +
>> +cec_notifier_conn_unregister(n);
>>  
>>  intel_connector_destroy(connector);
>>  }
>> @@ -3068,6 +3069,7 @@ void intel_hdmi_init_connector(struct 
>> intel_digital_port *intel_dig_port,
>>  struct drm_device *dev = intel_encoder->base.dev;
>>  struct drm_i915_private *dev_priv = to_i915(dev);
>>  enum port port = intel_encoder->port;
>> +struct cec_connector_info conn_info;
>>  
>>  DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
>>port_name(port));
>> @@ -3120,8 +3122,11 @@ void intel_hdmi_init_connector(struct 
>> intel_digital_port *intel_dig_port,
>>  I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
>>  }
>>  
>> -intel_hdmi->cec_notifier = cec_notifier_get_conn(dev->dev,
>> - port_identifier(port));
>> +cec_fill_conn_info_from_drm(_info, connector);
>> +
>> +intel_hdmi->cec_notifier =
>> +cec_notifier_conn_register(dev->dev, port_identifier(port),
>> +   _info);
>>  if (!intel_hdmi->cec_notifier)
>>  DRM_DEBUG_KMS("CEC notifier get failed\n");
>>  }
>>
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



[PATCHv10 1/2] cec: expose the new connector info API

2019-08-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Until now the connector info API was a kernel-internal API only.
This moves it to the public API and adds the new ioctl to retrieve
this information.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-adap.c |  2 ++
 drivers/media/cec/cec-api.c  | 20 ++
 drivers/media/cec/cec-core.c |  5 -
 include/media/cec.h  | 31 
 include/uapi/linux/cec.h | 40 
 5 files changed, 62 insertions(+), 36 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 451c61bde4d4..059c83525024 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -319,6 +319,8 @@ static void cec_post_state_event(struct cec_adapter *adap)
 
ev.state_change.phys_addr = adap->phys_addr;
ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+   ev.state_change.have_conn_info =
+   adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
cec_queue_event(adap, );
 }
 
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 12d676484472..17d1cb2e5f97 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -187,6 +187,21 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, 
struct cec_fh *fh,
return 0;
 }
 
+static long cec_adap_g_connector_info(struct cec_adapter *adap,
+ struct cec_log_addrs __user *parg)
+{
+   int ret = 0;
+
+   if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
+   return -ENOTTY;
+
+   mutex_lock(>lock);
+   if (copy_to_user(parg, >conn_info, sizeof(adap->conn_info)))
+   ret = -EFAULT;
+   mutex_unlock(>lock);
+   return ret;
+}
+
 static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
 bool block, struct cec_msg __user *parg)
 {
@@ -506,6 +521,9 @@ static long cec_ioctl(struct file *filp, unsigned int cmd, 
unsigned long arg)
case CEC_ADAP_S_LOG_ADDRS:
return cec_adap_s_log_addrs(adap, fh, block, parg);
 
+   case CEC_ADAP_G_CONNECTOR_INFO:
+   return cec_adap_g_connector_info(adap, parg);
+
case CEC_TRANSMIT:
return cec_transmit(adap, fh, block, parg);
 
@@ -578,6 +596,8 @@ static int cec_open(struct inode *inode, struct file *filp)
/* Queue up initial state events */
ev.state_change.phys_addr = adap->phys_addr;
ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+   ev.state_change.have_conn_info =
+   adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
cec_queue_event_fh(fh, , 0);
 #ifdef CONFIG_CEC_PIN
if (adap->pin && adap->pin->ops->read_hpd) {
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index 9c610e1e99b8..db7adffcdc76 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -257,11 +257,6 @@ struct cec_adapter *cec_allocate_adapter(const struct 
cec_adap_ops *ops,
struct cec_adapter *adap;
int res;
 
-   /*
-* Disable this capability until the connector info public API
-* is ready.
-*/
-   caps &= ~CEC_CAP_CONNECTOR_INFO;
 #ifndef CONFIG_MEDIA_CEC_RC
caps &= ~CEC_CAP_RC;
 #endif
diff --git a/include/media/cec.h b/include/media/cec.h
index 4d59387bc61b..0a4f69cc9dd4 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -18,9 +18,6 @@
 #include 
 #include 
 
-/* CEC_ADAP_G_CONNECTOR_INFO is available */
-#define CEC_CAP_CONNECTOR_INFO (1 << 8)
-
 #define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
  CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
 
@@ -147,34 +144,6 @@ struct cec_adap_ops {
  */
 #define CEC_MAX_MSG_TX_QUEUE_SZ(18 * 1)
 
-/**
- * struct cec_drm_connector_info - tells which drm connector is
- * associated with the CEC adapter.
- * @card_no: drm card number
- * @connector_id: drm connector ID
- */
-struct cec_drm_connector_info {
-   __u32 card_no;
-   __u32 connector_id;
-};
-
-#define CEC_CONNECTOR_TYPE_NO_CONNECTOR0
-#define CEC_CONNECTOR_TYPE_DRM 1
-
-/**
- * struct cec_connector_info - tells if and which connector is
- * associated with the CEC adapter.
- * @type: connector type (if any)
- * @drm: drm connector info
- */
-struct cec_connector_info {
-   __u32 type;
-   union {
-   struct cec_drm_connector_info drm;
-   __u32 raw[16];
-   };
-};
-
 struct cec_adapter {
struct module *owner;
char name[32];
diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
index 5704fa0292b5..0115c5aa0d36 100644
--- a/include/uapi/linux/cec.h
+++ b/include/uapi/linux/cec.h
@@ -317,6 +317,8 @@ static inline int cec_is_un

[PATCH 1/3] drm/vc4/vc4_hdmi: fill in connector info

2019-08-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Fill in the connector info, allowing userspace to associate
the CEC device with the drm connector.

Tested on a Raspberry Pi 3B.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index ee7d4e7b0ee3..0853b980bcb3 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1285,6 +1285,9 @@ static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
 
 static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 {
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+   struct cec_connector_info conn_info;
+#endif
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = drm->dev_private;
@@ -1403,13 +1406,15 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 #ifdef CONFIG_DRM_VC4_HDMI_CEC
hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
  vc4, "vc4",
- CEC_CAP_TRANSMIT |
- CEC_CAP_LOG_ADDRS |
- CEC_CAP_PASSTHROUGH |
- CEC_CAP_RC, 1);
+ CEC_CAP_DEFAULTS |
+ CEC_CAP_CONNECTOR_INFO, 1);
ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
if (ret < 0)
goto err_destroy_conn;
+
+   cec_fill_conn_info_from_drm(_info, hdmi->connector);
+   cec_s_conn_info(hdmi->cec_adap, _info);
+
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0x);
value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 3/3] drm/bridge/adv7511: enable CEC connector info

2019-08-25 Thread Hans Verkuil
Set the connector info to help userspace associate the CEC adapter
with the HDMI connector.

This required that the cec initialization and unregistering the
CEC adapter takes place in the bridge attach and detach ops.

Tested on an R-Car Koelsch board.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/gpu/drm/bridge/adv7511/adv7511_cec.c |  7 ++-
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++--
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
index a20a45c0b353..accf5e232396 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
@@ -302,6 +302,7 @@ static int adv7511_cec_parse_dt(struct device *dev, struct 
adv7511 *adv7511)
 
 int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
 {
+   struct cec_connector_info conn_info;
unsigned int offset = adv7511->type == ADV7533 ?
ADV7533_REG_CEC_OFFSET : 0;
int ret = adv7511_cec_parse_dt(dev, adv7511);
@@ -310,7 +311,8 @@ int adv7511_cec_init(struct device *dev, struct adv7511 
*adv7511)
goto err_cec_parse_dt;
 
adv7511->cec_adap = cec_allocate_adapter(_cec_adap_ops,
-   adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS);
+   adv7511, dev_name(dev),
+   CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO, ADV7511_MAX_ADDRS);
if (IS_ERR(adv7511->cec_adap)) {
ret = PTR_ERR(adv7511->cec_adap);
goto err_cec_alloc;
@@ -331,6 +333,9 @@ int adv7511_cec_init(struct device *dev, struct adv7511 
*adv7511)
 ADV7511_REG_CEC_CLK_DIV + offset,
 ((adv7511->cec_clk_freq / 75) - 1) << 2);
 
+   cec_fill_conn_info_from_drm(_info, >connector);
+   cec_s_conn_info(adv7511->cec_adap, _info);
+
ret = cec_register_adapter(adv7511->cec_adap, dev);
if (ret)
goto err_cec_register;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index f6d2681f6927..bbcb996c4d4f 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -881,14 +881,24 @@ static int adv7511_bridge_attach(struct drm_bridge 
*bridge)
regmap_write(adv->regmap, ADV7511_REG_INT_ENABLE(0),
 ADV7511_INT0_HPD);
 
+   if (!ret)
+   ret = adv7511_cec_init(>i2c_main->dev, adv);
return ret;
 }
 
+static void adv7511_bridge_detach(struct drm_bridge *bridge)
+{
+   struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+   cec_unregister_adapter(adv->cec_adap);
+}
+
 static const struct drm_bridge_funcs adv7511_bridge_funcs = {
.enable = adv7511_bridge_enable,
.disable = adv7511_bridge_disable,
.mode_set = adv7511_bridge_mode_set,
.attach = adv7511_bridge_attach,
+   .detach = adv7511_bridge_detach,
 };
 
 /* 
-
@@ -1202,7 +1212,7 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
IRQF_ONESHOT, dev_name(dev),
adv7511);
if (ret)
-   goto err_unregister_cec;
+   goto err_i2c_unregister_packet;
}
 
adv7511_power_off(adv7511);
@@ -1212,10 +1222,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
if (adv7511->type == ADV7511)
adv7511_set_link_config(adv7511, _config);
 
-   ret = adv7511_cec_init(dev, adv7511);
-   if (ret)
-   goto err_unregister_cec;
-
adv7511->bridge.funcs = _bridge_funcs;
adv7511->bridge.of_node = dev->of_node;
 
@@ -1224,10 +1230,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
adv7511_audio_init(dev, adv7511);
return 0;
 
-err_unregister_cec:
-   i2c_unregister_device(adv7511->i2c_cec);
-   if (adv7511->cec_clk)
-   clk_disable_unprepare(adv7511->cec_clk);
 err_i2c_unregister_packet:
i2c_unregister_device(adv7511->i2c_packet);
 err_i2c_unregister_edid:
@@ -1254,8 +1256,6 @@ static int adv7511_remove(struct i2c_client *i2c)
 
adv7511_audio_exit(adv7511);
 
-   cec_unregister_adapter(adv7511->cec_adap);
-
i2c_unregister_device(adv7511->i2c_packet);
i2c_unregister_device(adv7511->i2c_edid);
 
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH for v5.3] cec-notifier: clear cec_adap in cec_notifier_unregister

2019-08-25 Thread Hans Verkuil
If cec_notifier_cec_adap_unregister() is called before
cec_unregister_adapter() then everything is OK (and this is the
case today). But if it is the other way around, then
cec_notifier_unregister() is called first, and that doesn't
set n->cec_adap to NULL.

So if e.g. cec_notifier_set_phys_addr() is called after
cec_notifier_unregister() but before cec_unregister_adapter()
then n->cec_adap points to an unregistered and likely deleted
cec adapter. So just set n->cec_adap->notifier and n->cec_adap
to NULL for rubustness.

Eventually cec_notifier_unregister will disappear and this will
be simplified substantially.

Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-notifier.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 52a867bde15f..4d82a5522072 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -218,6 +218,8 @@ void cec_notifier_unregister(struct cec_notifier *n)

mutex_lock(>lock);
n->callback = NULL;
+   n->cec_adap->notifier = NULL;
+   n->cec_adap = NULL;
mutex_unlock(>lock);
cec_notifier_put(n);
 }
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 2/3] drm/sun4i/sun4i_hdmi_enc: call cec_s_conn_info()

2019-08-25 Thread Hans Verkuil
Set the connector info for the CEC adapter. This helps
userspace to associate the CEC device with the HDMI connector.

Tested on a Cubieboard.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 9c3f99339b82..22f082c32e1f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -489,6 +489,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
 {
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = data;
+   struct cec_connector_info conn_info;
struct sun4i_drv *drv = drm->dev_private;
struct sun4i_hdmi *hdmi;
struct resource *res;
@@ -628,8 +629,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
 
 #ifdef CONFIG_DRM_SUN4I_HDMI_CEC
hdmi->cec_adap = cec_pin_allocate_adapter(_hdmi_cec_pin_ops,
-   hdmi, "sun4i", CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS |
-   CEC_CAP_PASSTHROUGH | CEC_CAP_RC);
+   hdmi, "sun4i", CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO);
ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
if (ret < 0)
goto err_cleanup_connector;
@@ -647,6 +647,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
"Couldn't initialise the HDMI connector\n");
goto err_cleanup_connector;
}
+   cec_fill_conn_info_from_drm(_info, >connector);
+   cec_s_conn_info(hdmi->cec_adap, _info);
 
/* There is no HPD interrupt, so we need to poll the controller */
hdmi->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 0/3] drm: cec: call cec_s_conn_info()

2019-08-25 Thread Hans Verkuil
Three drivers were not updated in Dariusz' series:

https://patchwork.linuxtv.org/project/linux-media/list/?series=573

This series adds connector info support for those three.

Note that the sun4i patch has this patch as a prerequisite:

https://patchwork.linuxtv.org/project/linux-media/list/?series=573

This will be merged for v5.3, so this should be in before the
sun4i patch is merged.

Regards,

Hans

Dariusz Marcinkiewicz (1):
  drm/vc4/vc4_hdmi: fill in connector info

Hans Verkuil (2):
  drm/sun4i/sun4i_hdmi_enc: call cec_s_conn_info()
  drm/bridge/adv7511: enable CEC connector info

 drivers/gpu/drm/bridge/adv7511/adv7511_cec.c |  7 ++-
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++--
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c   |  6 --
 drivers/gpu/drm/vc4/vc4_hdmi.c   | 13 
 4 files changed, 30 insertions(+), 18 deletions(-)

-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCHv10 0/2] cec: add the connector info API

2019-08-25 Thread Hans Verkuil
These two patches add the CEC connector info API.

Note that connector info is currently for drm connectors only.
In the future support for v4l2 connectors will be added as well,
once we actually know how to uniquely identify a HDMI receiver
connector.

Regards,

Hans

Dariusz Marcinkiewicz (1):
  cec: expose the new connector info API

Hans Verkuil (1):
  cec: document CEC_ADAP_G_CONNECTOR_INFO and capability

 Documentation/media/uapi/cec/cec-funcs.rst|   1 +
 .../media/uapi/cec/cec-ioc-adap-g-caps.rst|   6 +-
 .../uapi/cec/cec-ioc-adap-g-conn-info.rst | 105 ++
 .../media/uapi/cec/cec-ioc-dqevent.rst|   8 ++
 drivers/media/cec/cec-adap.c  |   2 +
 drivers/media/cec/cec-api.c   |  20 
 drivers/media/cec/cec-core.c  |   5 -
 include/media/cec.h   |  31 --
 include/uapi/linux/cec.h  |  40 +++
 9 files changed, 181 insertions(+), 37 deletions(-)
 create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst

-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCHv10 2/2] cec: document CEC_ADAP_G_CONNECTOR_INFO and capability

2019-08-25 Thread Hans Verkuil
Document the new CEC_ADAP_G_CONNECTOR_INFO ioctl and the new
CEC_CAP_CONNECTOR_INFO capability.

Signed-off-by: Dariusz Marcinkiewicz 
Co-developed-by: Hans Verkuil 
[hverkuil-ci...@xs4all.nl: added CEC_CAP_CONNECTOR_INFO]
[hverkuil-ci...@xs4all.nl: added DQEVENT have_conn_info]
Signed-off-by: Hans Verkuil 
---
 Documentation/media/uapi/cec/cec-funcs.rst|   1 +
 .../media/uapi/cec/cec-ioc-adap-g-caps.rst|   6 +-
 .../uapi/cec/cec-ioc-adap-g-conn-info.rst | 105 ++
 .../media/uapi/cec/cec-ioc-dqevent.rst|   8 ++
 4 files changed, 119 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst

diff --git a/Documentation/media/uapi/cec/cec-funcs.rst 
b/Documentation/media/uapi/cec/cec-funcs.rst
index 620590b168c9..dc6da9c639a8 100644
--- a/Documentation/media/uapi/cec/cec-funcs.rst
+++ b/Documentation/media/uapi/cec/cec-funcs.rst
@@ -24,6 +24,7 @@ Function Reference
 cec-ioc-adap-g-caps
 cec-ioc-adap-g-log-addrs
 cec-ioc-adap-g-phys-addr
+cec-ioc-adap-g-conn-info
 cec-ioc-dqevent
 cec-ioc-g-mode
 cec-ioc-receive
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst 
b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
index 0c44f31a9b59..76761a98c312 100644
--- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
+++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
@@ -135,8 +135,12 @@ returns the information to the application. The ioctl 
never fails.
   - The CEC hardware can monitor CEC pin changes from low to high voltage
 and vice versa. When in pin monitoring mode the application will
receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events.
+* .. _`CEC-CAP-CONNECTOR-INFO`:
 
-
+  - ``CEC_CAP_CONNECTOR_INFO``
+  - 0x0100
+  - If this capability is set, then :ref:`CEC_ADAP_G_CONNECTOR_INFO` can
+be used.
 
 Return Value
 
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst 
b/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
new file mode 100644
index ..a21659d55c6b
--- /dev/null
+++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
@@ -0,0 +1,105 @@
+.. SPDX-License-Identifier: GPL-2.0
+..
+.. Copyright 2019 Google LLC
+..
+.. _CEC_ADAP_G_CONNECTOR_INFO:
+
+***
+ioctl CEC_ADAP_G_CONNECTOR_INFO
+***
+
+Name
+
+
+CEC_ADAP_G_CONNECTOR_INFO - Query HDMI connector information
+
+Synopsis
+
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_G_CONNECTOR_INFO, struct 
cec_connector_info *argp )
+:name: CEC_ADAP_G_CONNECTOR_INFO
+
+Arguments
+=
+
+``fd``
+File descriptor returned by :c:func:`open() `.
+
+``argp``
+
+
+Description
+===
+
+Using this ioctl an application can learn which HDMI connector this CEC
+device corresponds to. While calling this ioctl the application should
+provide a pointer to a cec_connector_info struct which will be populated
+by the kernel with the info provided by the adapter's driver. This ioctl
+is only available if the ``CEC_CAP_CONNECTOR_INFO`` capability is set.
+
+.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}|
+
+.. c:type:: cec_connector_info
+
+.. flat-table:: struct cec_connector_info
+:header-rows:  0
+:stub-columns: 0
+:widths:   1 1 1 8
+
+* - __u32
+  - ``type``
+  - The type of connector this adapter is associated with.
+* - union
+  - ``(anonymous)``
+  -
+* -
+  - ``struct cec_drm_connector_info``
+  - drm
+  - :ref:`cec-drm-connector-info`
+
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. _connector-type:
+
+.. flat-table:: Connector types
+:header-rows:  0
+:stub-columns: 0
+:widths:   3 1 8
+
+* .. _`CEC-CONNECTOR-TYPE-NO-CONNECTOR`:
+
+  - ``CEC_CONNECTOR_TYPE_NO_CONNECTOR``
+  - 0
+  - No connector is associated with the adapter/the information is not
+provided by the driver.
+* .. _`CEC-CONNECTOR-TYPE-DRM`:
+
+  - ``CEC_CONNECTOR_TYPE_DRM``
+  - 1
+  - Indicates that a DRM connector is associated with this adapter.
+Information about the connector can be found in
+   :ref:`cec-drm-connector-info`.
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. c:type:: cec_drm_connector_info
+
+.. _cec-drm-connector-info:
+
+.. flat-table:: struct cec_drm_connector_info
+:header-rows:  0
+:stub-columns: 0
+:widths:   3 1 8
+
+* .. _`CEC-DRM-CONNECTOR-TYPE-CARD-NO`:
+
+  - __u32
+  - ``card_no``
+  - DRM card number: the number from a card's path, e.g. 0 in case of
+/dev/card0.
+* .. _`CEC-DRM-CONNECTOR-TYPE-CONNECTOR_ID`:
+
+  - __u32
+  - ``connector_id``
+  - DRM connector ID.
diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst 
b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
index 46a1c99a595e..5e21b1fbfc01 100644

[PATCH for v5.3] cec-adap: return from cec_s_conn_info() if adap is invalid

2019-08-25 Thread Hans Verkuil
Check if cec_s_conn_info is called with a valid cec adapter,
do nothing if it is invalid.

This makes it possible to call this function even if CEC support is
disabled in the kernel config.

Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-adap.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 451c61bde4d4..5ef7daeb8cbd 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -1614,6 +1614,9 @@ EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
 void cec_s_conn_info(struct cec_adapter *adap,
 const struct cec_connector_info *conn_info)
 {
+   if (IS_ERR_OR_NULL(adap))
+   return;
+
if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
return;

-- 
2.20.1


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v7 5/9] drm: tda998x: use cec_notifier_conn_(un)register

2019-08-25 Thread Hans Verkuil
On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill
> in the cec_connector_info.
> 
> Changes since v6:
> - move cec_notifier_conn_unregister to tda998x_bridge_detach,
>   - add a mutex protecting accesses to a CEC notifier.
> Changes since v2:
>   - cec_notifier_phys_addr_invalidate where appropriate,
>   - don't check for NULL notifier before calling
>   cec_notifier_conn_unregister.
> Changes since v1:
>   Add memory barrier to make sure that the notifier
>   becomes visible to the irq thread once it is
>   fully constructed.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> ---
>  drivers/gpu/drm/i2c/tda998x_drv.c | 36 +--
>  1 file changed, 25 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
> b/drivers/gpu/drm/i2c/tda998x_drv.c
> index 61e042918a7fc..643480415473f 100644
> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> @@ -82,6 +82,8 @@ struct tda998x_priv {
>   u8 audio_port_enable[AUDIO_ROUTE_NUM];
>   struct tda9950_glue cec_glue;
>   struct gpio_desc *calib;
> +
> + struct mutex cec_notifiy_mutex;
>   struct cec_notifier *cec_notify;
>  };
>  
> @@ -805,8 +807,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void 
> *data)
>   tda998x_edid_delay_start(priv);
>   } else {
>   schedule_work(>detect_work);
> - cec_notifier_set_phys_addr(priv->cec_notify,
> -CEC_PHYS_ADDR_INVALID);
> +
> + mutex_lock(>cec_notifiy_mutex);
> + cec_notifier_phys_addr_invalidate(
> + priv->cec_notify);
> + mutex_unlock(>cec_notifiy_mutex);
>   }
>  
>   handled = true;
> @@ -1331,6 +1336,8 @@ static int tda998x_connector_init(struct tda998x_priv 
> *priv,
> struct drm_device *drm)
>  {
>   struct drm_connector *connector = >connector;
> + struct cec_connector_info conn_info;
> + struct cec_notifier *notifier;
>   int ret;
>  
>   connector->interlace_allowed = 1;
> @@ -1347,6 +1354,16 @@ static int tda998x_connector_init(struct tda998x_priv 
> *priv,
>   if (ret)
>   return ret;
>  
> + cec_fill_conn_info_from_drm(_info, connector);
> +
> + notifier = cec_notifier_conn_register(priv->cec_glue.parent,
> +   NULL, _info);
> + return -ENOMEM;

You dropped a 'if (!notifier)' before the return!

After adding back this 'if' it worked fine on my BeagleBone Black board,
so after fixing this you can add my:

Tested-by: Hans Verkuil 

tag.

Regards,

Hans

> +
> + mutex_lock(>cec_notifiy_mutex);
> + priv->cec_notify = notifier;
> + mutex_unlock(>cec_notifiy_mutex);
> +
>   drm_connector_attach_encoder(>connector,
>priv->bridge.encoder);
>  
> @@ -1366,6 +1383,11 @@ static void tda998x_bridge_detach(struct drm_bridge 
> *bridge)
>  {
>   struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
>  
> + mutex_lock(>cec_notifiy_mutex);
> + cec_notifier_conn_unregister(priv->cec_notify);
> + priv->cec_notify = NULL;
> + mutex_unlock(>cec_notifiy_mutex);
> +
>   drm_connector_cleanup(>connector);
>  }
>  
> @@ -1789,9 +1811,6 @@ static void tda998x_destroy(struct device *dev)
>   cancel_work_sync(>detect_work);
>  
>   i2c_unregister_device(priv->cec);
> -
> - if (priv->cec_notify)
> - cec_notifier_put(priv->cec_notify);
>  }
>  
>  static int tda998x_create(struct device *dev)
> @@ -1812,6 +1831,7 @@ static int tda998x_create(struct device *dev)
>   mutex_init(>mutex);   /* protect the page access */
>   mutex_init(>audio_mutex); /* protect access from audio thread */
>   mutex_init(>edid_mutex);
> + mutex_init(>cec_notifiy_mutex);
>   INIT_LIST_HEAD(>bridge.list);
>   init_waitqueue_head(>edid_delay_waitq);
>   timer_setup(>edid_delay_timer, tda998x_edid_delay_done, 0);
> @@ -1916,12 +1936,6 @@ static int tda998x_create(struct device *dev)
>   cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
>   }
>  
> - priv->cec_notify = cec_notifier_get(dev);
> - if (!priv->cec_notify) {
> - ret = -ENOMEM;
> - goto fail;
> - }
> -
>   priv->cec_glue.parent = dev;
>   priv->cec_glue.data = priv;
>   priv->cec_glue.init = tda998x_cec_hook_init;
> 



Re: [PATCH v7 1/9] drm_dp_cec: add connector info support.

2019-08-22 Thread Hans Verkuil
Alex, Ville/Rodrigo, Ben,

Can you (hopefully) Ack this patch so that I can merge it?

Thank you!

Hans

On 8/14/19 12:44 PM, Dariusz Marcinkiewicz wrote:
> Pass the connector info to the CEC adapter. This makes it possible
> to associate the CEC adapter with the corresponding drm connector.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> Signed-off-by: Hans Verkuil 
> Tested-by: Hans Verkuil 
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  2 +-
>  drivers/gpu/drm/drm_dp_cec.c  | 25 ---
>  drivers/gpu/drm/i915/display/intel_dp.c   |  4 +--
>  drivers/gpu/drm/nouveau/nouveau_connector.c   |  3 +--
>  include/drm/drm_dp_helper.h   | 17 ++---
>  5 files changed, 27 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 16218a202b591..5ec14efd4d8cb 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -416,7 +416,7 @@ void amdgpu_dm_initialize_dp_connector(struct 
> amdgpu_display_manager *dm,
>  
>   drm_dp_aux_register(>dm_dp_aux.aux);
>   drm_dp_cec_register_connector(>dm_dp_aux.aux,
> -   aconnector->base.name, dm->adev->dev);
> +   >base);
>   aconnector->mst_mgr.cbs = _mst_cbs;
>   drm_dp_mst_topology_mgr_init(
>   >mst_mgr,
> diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
> index b15cee85b702b..b457c16c3a8bb 100644
> --- a/drivers/gpu/drm/drm_dp_cec.c
> +++ b/drivers/gpu/drm/drm_dp_cec.c
> @@ -8,7 +8,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>  #include 
>  
>  /*
> @@ -295,7 +297,10 @@ static void drm_dp_cec_unregister_work(struct 
> work_struct *work)
>   */
>  void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
>  {
> - u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
> + struct drm_connector *connector = aux->cec.connector;
> + u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
> +CEC_CAP_CONNECTOR_INFO;
> + struct cec_connector_info conn_info;
>   unsigned int num_las = 1;
>   u8 cap;
>  
> @@ -344,13 +349,17 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
> struct edid *edid)
>  
>   /* Create a new adapter */
>   aux->cec.adap = cec_allocate_adapter(_dp_cec_adap_ops,
> -  aux, aux->cec.name, cec_caps,
> +  aux, connector->name, cec_caps,
>num_las);
>   if (IS_ERR(aux->cec.adap)) {
>   aux->cec.adap = NULL;
>   goto unlock;
>   }
> - if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
> +
> + cec_fill_conn_info_from_drm(_info, connector);
> + cec_s_conn_info(aux->cec.adap, _info);
> +
> + if (cec_register_adapter(aux->cec.adap, connector->dev->dev)) {
>   cec_delete_adapter(aux->cec.adap);
>   aux->cec.adap = NULL;
>   } else {
> @@ -406,22 +415,20 @@ EXPORT_SYMBOL(drm_dp_cec_unset_edid);
>  /**
>   * drm_dp_cec_register_connector() - register a new connector
>   * @aux: DisplayPort AUX channel
> - * @name: name of the CEC device
> - * @parent: parent device
> + * @connector: drm connector
>   *
>   * A new connector was registered with associated CEC adapter name and
>   * CEC adapter parent device. After registering the name and parent
>   * drm_dp_cec_set_edid() is called to check if the connector supports
>   * CEC and to register a CEC adapter if that is the case.
>   */
> -void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
> -struct device *parent)
> +void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
> +struct drm_connector *connector)
>  {
>   WARN_ON(aux->cec.adap);
>   if (WARN_ON(!aux->transfer))
>   return;
> - aux->cec.name = name;
> - aux->cec.parent = parent;
> + aux->cec.connector = connector;
>   INIT_DELAYED_WORK(>cec.unregister_work,
> drm_dp_cec_unregister_work);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 1092499115760..de2486fe7bf2d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/driver

Re: [PATCH v7 6/9] drm: sti: use cec_notifier_conn_(un)register

2019-08-22 Thread Hans Verkuil
Adding Benjamin Gaignard.

Benjamin, can you take a look at this and Ack it (or merge it if you prefer) and
ideally test it as well. This is the only patch in this series that I could not
test since I don't have any hardware.

Regards,

Hans

On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill
> in the cec_connector_info.
> 
> Changes since v2:
>   Don't invalidate physical address before unregistering the
>   notifier.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> ---
>  drivers/gpu/drm/sti/sti_hdmi.c | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 9862c322f0c4a..bd15902b825ad 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -1256,6 +1256,7 @@ static int sti_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
>   struct drm_device *drm_dev = data;
>   struct drm_encoder *encoder;
>   struct sti_hdmi_connector *connector;
> + struct cec_connector_info conn_info;
>   struct drm_connector *drm_connector;
>   struct drm_bridge *bridge;
>   int err;
> @@ -1318,6 +1319,14 @@ static int sti_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
>   goto err_sysfs;
>   }
>  
> + cec_fill_conn_info_from_drm(_info, drm_connector);
> + hdmi->notifier = cec_notifier_conn_register(>dev, NULL,
> + _info);
> + if (!hdmi->notifier) {
> + hdmi->drm_connector = NULL;
> + return -ENOMEM;
> + }
> +
>   /* Enable default interrupts */
>   hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN);
>  
> @@ -1331,6 +1340,9 @@ static int sti_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
>  static void sti_hdmi_unbind(struct device *dev,
>   struct device *master, void *data)
>  {
> + struct sti_hdmi *hdmi = dev_get_drvdata(dev);
> +
> + cec_notifier_conn_unregister(hdmi->notifier);
>  }
>  
>  static const struct component_ops sti_hdmi_ops = {
> @@ -1436,10 +1448,6 @@ static int sti_hdmi_probe(struct platform_device *pdev)
>   goto release_adapter;
>   }
>  
> - hdmi->notifier = cec_notifier_get(>dev);
> - if (!hdmi->notifier)
> - goto release_adapter;
> -
>   hdmi->reset = devm_reset_control_get(dev, "hdmi");
>   /* Take hdmi out of reset */
>   if (!IS_ERR(hdmi->reset))
> @@ -1459,14 +1467,11 @@ static int sti_hdmi_remove(struct platform_device 
> *pdev)
>  {
>   struct sti_hdmi *hdmi = dev_get_drvdata(>dev);
>  
> - cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
> -
>   i2c_put_adapter(hdmi->ddc_adapt);
>   if (hdmi->audio_pdev)
>   platform_device_unregister(hdmi->audio_pdev);
>   component_del(>dev, _hdmi_ops);
>  
> - cec_notifier_put(hdmi->notifier);
>   return 0;
>  }
>  
> 



Re: [PATCH v7 2/9] drm/i915/intel_hdmi: use cec_notifier_conn_(un)register

2019-08-22 Thread Hans Verkuil
Ville or Rodrigo,

Can one of you either merge this patch or Ack it so that I can merge this?

Thank you!

Regards,

Hans

On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill in
> the cec_connector_info.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> Signed-off-by: Hans Verkuil 
> Tested-by: Hans Verkuil 
> ---
>  drivers/gpu/drm/i915/display/intel_hdmi.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
> b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index b1ca8e5bdb56d..9fcf2c58c29c5 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -2752,8 +2752,9 @@ intel_hdmi_connector_register(struct drm_connector 
> *connector)
>  
>  static void intel_hdmi_destroy(struct drm_connector *connector)
>  {
> - if (intel_attached_hdmi(connector)->cec_notifier)
> - cec_notifier_put(intel_attached_hdmi(connector)->cec_notifier);
> + struct cec_notifier *n = intel_attached_hdmi(connector)->cec_notifier;
> +
> + cec_notifier_conn_unregister(n);
>  
>   intel_connector_destroy(connector);
>  }
> @@ -3068,6 +3069,7 @@ void intel_hdmi_init_connector(struct 
> intel_digital_port *intel_dig_port,
>   struct drm_device *dev = intel_encoder->base.dev;
>   struct drm_i915_private *dev_priv = to_i915(dev);
>   enum port port = intel_encoder->port;
> + struct cec_connector_info conn_info;
>  
>   DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
> port_name(port));
> @@ -3120,8 +3122,11 @@ void intel_hdmi_init_connector(struct 
> intel_digital_port *intel_dig_port,
>   I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
>   }
>  
> - intel_hdmi->cec_notifier = cec_notifier_get_conn(dev->dev,
> -  port_identifier(port));
> + cec_fill_conn_info_from_drm(_info, connector);
> +
> + intel_hdmi->cec_notifier =
> + cec_notifier_conn_register(dev->dev, port_identifier(port),
> +_info);
>   if (!intel_hdmi->cec_notifier)
>   DRM_DEBUG_KMS("CEC notifier get failed\n");
>  }
> 



Re: [PATCH v7 0/9] drm: cec: convert DRM drivers to the new notifier API

2019-08-20 Thread Hans Verkuil
On 8/19/19 1:28 PM, Dariusz Marcinkiewicz wrote:
> On Mon, Aug 19, 2019 at 11:38 AM Hans Verkuil  
> wrote:
>>
>> Hi all,
>>
> Hi Hans.
>> The patches in this series can be applied independently from each other.
>>
>> If you maintain one of these drivers and you want to merge it for v5.4
>> yourself, then please do so and let me know. If you prefer I commit it
>> to drm-misc, then please review and (hopefully) Ack the patch.
>>
>> I would really like to get this in for v5.4 so I can get the userspace
>> bits in for v5.4 as well through the media subsystem.
>>
>> Dariusz, can you post a v7.1 for patch 5/9 fixing the typo?
>>
> Done.
> 
> I think it would be good to test v7 changes to dw-hdmi and tda998x on
> a real hardware. Hans, do you think you would be able to test those?
> 
> Thank you.
> 

I'll try to do this for dw-hdmi today, but the tda998x testing will have to wait
until next week.

Regards,

Hans
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v7 0/9] drm: cec: convert DRM drivers to the new notifier API

2019-08-20 Thread Hans Verkuil
On 8/19/19 4:48 PM, Neil Armstrong wrote:
> Hi Dariusz, Hans,
> 
> I can apply the dw-hdmi patches if necessary.

I'd appreciate it if you can do that.

Thanks,

Hans

> 
> Neil
> 
> On 19/08/2019 11:38, Hans Verkuil wrote:
>> Hi all,
>>
>> The patches in this series can be applied independently from each other.
>>
>> If you maintain one of these drivers and you want to merge it for v5.4
>> yourself, then please do so and let me know. If you prefer I commit it
>> to drm-misc, then please review and (hopefully) Ack the patch.
>>
>> I would really like to get this in for v5.4 so I can get the userspace
>> bits in for v5.4 as well through the media subsystem.
>>
>> Dariusz, can you post a v7.1 for patch 5/9 fixing the typo?
>>
>> Thanks!
>>
>>  Hans
>>
>> On 8/14/19 12:44 PM, Dariusz Marcinkiewicz wrote:
>>> This series updates DRM drivers to use new CEC notifier API.
>>>
>>> Changes since v6:
>>> Made CEC notifiers' registration and de-registration symmetric
>>> in tda998x and dw-hdmi drivers. Also, accidentally dropped one
>>> patch in v6 (change to drm_dp_cec), brought it back now.
>>> Changes since v5:
>>> Fixed a warning about a missing comment for a new member of
>>> drm_dp_aux_cec struct. Sending to a wider audience,
>>> including maintainers of respective drivers.
>>> Changes since v4:
>>> Addressing review comments.
>>> Changes since v3:
>>> Updated adapter flags in dw-hdmi-cec.
>>> Changes since v2:
>>> Include all DRM patches from "cec: improve notifier support,
>>> add connector info connector info" series.
>>> Changes since v1:
>>> Those patches delay creation of notifiers until respective
>>> connectors are constructed. It seems that those patches, for a
>>> couple of drivers, by adding the delay, introduce a race between
>>> notifiers' creation and the IRQs handling threads - at least I
>>> don't see anything obvious in there that would explicitly forbid
>>> such races to occur. v2 adds a write barrier to make sure IRQ
>>> threads see the notifier once it is created (replacing the
>>> WRITE_ONCE I put in v1). The best thing to do here, I believe,
>>> would be not to have any synchronization and make sure that an IRQ
>>> only gets enabled after the notifier is created.
>>> Dariusz Marcinkiewicz (9):
>>>   drm_dp_cec: add connector info support.
>>>   drm/i915/intel_hdmi: use cec_notifier_conn_(un)register
>>>   dw-hdmi-cec: use cec_notifier_cec_adap_(un)register
>>>   tda9950: use cec_notifier_cec_adap_(un)register
>>>   drm: tda998x: use cec_notifier_conn_(un)register
>>>   drm: sti: use cec_notifier_conn_(un)register
>>>   drm: tegra: use cec_notifier_conn_(un)register
>>>   drm: dw-hdmi: use cec_notifier_conn_(un)register
>>>   drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register
>>>
>>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  2 +-
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 13 +++---
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 46 +--
>>>  drivers/gpu/drm/drm_dp_cec.c  | 25 ++
>>>  drivers/gpu/drm/exynos/exynos_hdmi.c  | 31 +++--
>>>  drivers/gpu/drm/i2c/tda9950.c | 12 ++---
>>>  drivers/gpu/drm/i2c/tda998x_drv.c | 36 ++-
>>>  drivers/gpu/drm/i915/display/intel_dp.c   |  4 +-
>>>  drivers/gpu/drm/i915/display/intel_hdmi.c | 13 --
>>>  drivers/gpu/drm/nouveau/nouveau_connector.c   |  3 +-
>>>  drivers/gpu/drm/sti/sti_hdmi.c| 19 +---
>>>  drivers/gpu/drm/tegra/output.c| 28 ---
>>>  include/drm/drm_dp_helper.h   | 17 ---
>>>  13 files changed, 155 insertions(+), 94 deletions(-)
>>>
>>
> 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

omap4: how to obtain drm_connector in hdmi4_cec.c for cec_s_conn_info()?

2019-08-19 Thread Hans Verkuil
Hi Tomi, Laurent,

For the CEC framework we (Dariusz and myself) are working on code to associate
a drm_connector with a CEC adapter, making it easier for userspace to link the
two.

In order to do that I need the drm_connector structure when creating the
CEC adapter in hdmi4_cec.c. That's easy enough in the GPU drivers, except for
the omap.

I need the drm_connector in hdmi4_cec_init(). Any idea how to obtain it
through the seemingly endless layers of data structures?

The code itself that needs to be added to hdmi4_cec_init() is easy enough:

struct cec_connector_info conn_info;

cec_fill_conn_info_from_drm(_info, connector);
cec_s_conn_info(core->adap, _info);

but getting the drm_connector is the hard bit.

As an aside: I finally found some time to finish my work on the omap5 CEC 
support.
Expect patches for this soon.

Regards,

Hans
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v7 8/9] drm: dw-hdmi: use cec_notifier_conn_(un)register

2019-08-19 Thread Hans Verkuil
On 8/19/19 4:38 PM, Neil Armstrong wrote:
> Hi Hans,
> 
> On 19/08/2019 16:05, Hans Verkuil wrote:
>> On 8/19/19 11:32 AM, Hans Verkuil wrote:
>>> On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
>>>> Use the new cec_notifier_conn_(un)register() functions to
>>>> (un)register the notifier for the HDMI connector, and fill in
>>>> the cec_connector_info.
>>>>
>>>> Changes since v6:
>>>> - move cec_notifier_conn_unregister to a bridge detach
>>>>  function,
>>>>- add a mutex protecting a CEC notifier.
>>>> Changes since v4:
>>>>- typo fix
>>>> Changes since v2:
>>>>- removed unnecessary NULL check before a call to
>>>>cec_notifier_conn_unregister,
>>>>- use cec_notifier_phys_addr_invalidate to invalidate physical
>>>>address.
>>>> Changes since v1:
>>>>    Add memory barrier to make sure that the notifier
>>>>becomes visible to the irq thread once it is fully
>>>>constructed.
>>>>
>>>> Signed-off-by: Dariusz Marcinkiewicz 
>>>
>>> Acked-by: Hans Verkuil 
>>
>> Tested-by: Hans Verkuil 
> 
> Did you test it on an Amlogic platform ? If yes, I don't have to !

Yes, tested on my khadas VIM2 (modified a bit to fix the issue where
the CEC physical address wasn't invalidated correctly as discussed here
earlier).

Regards,

Hans

> 
> Neil
> 
>>
>> Regards,
>>
>>  Hans
>>
>>>
>>> Regards,
>>>
>>> Hans
>>>
>>>> ---
>>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 45 +++
>>>>  1 file changed, 30 insertions(+), 15 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> index 83b94b66e464e..55162c9092f71 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> @@ -190,6 +190,7 @@ struct dw_hdmi {
>>>>void (*enable_audio)(struct dw_hdmi *hdmi);
>>>>void (*disable_audio)(struct dw_hdmi *hdmi);
>>>>  
>>>> +  struct mutex cec_notifier_mutex;
>>>>struct cec_notifier *cec_notifier;
>>>>  };
>>>>  
>>>> @@ -2194,6 +2195,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
>>>> *bridge)
>>>>struct dw_hdmi *hdmi = bridge->driver_private;
>>>>struct drm_encoder *encoder = bridge->encoder;
>>>>struct drm_connector *connector = >connector;
>>>> +  struct cec_connector_info conn_info;
>>>> +  struct cec_notifier *notifier;
>>>>  
>>>>connector->interlace_allowed = 1;
>>>>connector->polled = DRM_CONNECTOR_POLL_HPD;
>>>> @@ -2207,9 +2210,29 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
>>>> *bridge)
>>>>  
>>>>drm_connector_attach_encoder(connector, encoder);
>>>>  
>>>> +  cec_fill_conn_info_from_drm(_info, connector);
>>>> +
>>>> +  notifier = cec_notifier_conn_register(hdmi->dev, NULL, _info);
>>>> +  if (!notifier)
>>>> +  return -ENOMEM;
>>>> +
>>>> +  mutex_lock(>cec_notifier_mutex);
>>>> +  hdmi->cec_notifier = notifier;
>>>> +  mutex_unlock(>cec_notifier_mutex);
>>>> +
>>>>return 0;
>>>>  }
>>>>  
>>>> +static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
>>>> +{
>>>> +  struct dw_hdmi *hdmi = bridge->driver_private;
>>>> +
>>>> +  mutex_lock(>cec_notifier_mutex);
>>>> +  cec_notifier_conn_unregister(hdmi->cec_notifier);
>>>> +  hdmi->cec_notifier = NULL;
>>>> +  mutex_unlock(>cec_notifier_mutex);
>>>> +}
>>>> +
>>>>  static enum drm_mode_status
>>>>  dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
>>>>  const struct drm_display_mode *mode)
>>>> @@ -2266,6 +2289,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge 
>>>> *bridge)
>>>>  
>>>>  static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
>>>>.attach = dw_hdmi_bridge_attach,
>>>> +  .detach = dw_hdmi_bridge_detach,
>>>>.enable = dw_hdmi

Re: [PATCH v7 8/9] drm: dw-hdmi: use cec_notifier_conn_(un)register

2019-08-19 Thread Hans Verkuil
On 8/19/19 11:32 AM, Hans Verkuil wrote:
> On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
>> Use the new cec_notifier_conn_(un)register() functions to
>> (un)register the notifier for the HDMI connector, and fill in
>> the cec_connector_info.
>>
>> Changes since v6:
>> - move cec_notifier_conn_unregister to a bridge detach
>>function,
>>  - add a mutex protecting a CEC notifier.
>> Changes since v4:
>>  - typo fix
>> Changes since v2:
>>  - removed unnecessary NULL check before a call to
>>  cec_notifier_conn_unregister,
>>  - use cec_notifier_phys_addr_invalidate to invalidate physical
>>  address.
>> Changes since v1:
>>  Add memory barrier to make sure that the notifier
>>  becomes visible to the irq thread once it is fully
>>  constructed.
>>
>> Signed-off-by: Dariusz Marcinkiewicz 
> 
> Acked-by: Hans Verkuil 

Tested-by: Hans Verkuil 

Regards,

Hans

> 
> Regards,
> 
>   Hans
> 
>> ---
>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 45 +++
>>  1 file changed, 30 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 83b94b66e464e..55162c9092f71 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -190,6 +190,7 @@ struct dw_hdmi {
>>  void (*enable_audio)(struct dw_hdmi *hdmi);
>>  void (*disable_audio)(struct dw_hdmi *hdmi);
>>  
>> +struct mutex cec_notifier_mutex;
>>  struct cec_notifier *cec_notifier;
>>  };
>>  
>> @@ -2194,6 +2195,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
>> *bridge)
>>  struct dw_hdmi *hdmi = bridge->driver_private;
>>  struct drm_encoder *encoder = bridge->encoder;
>>  struct drm_connector *connector = >connector;
>> +struct cec_connector_info conn_info;
>> +struct cec_notifier *notifier;
>>  
>>  connector->interlace_allowed = 1;
>>  connector->polled = DRM_CONNECTOR_POLL_HPD;
>> @@ -2207,9 +2210,29 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
>> *bridge)
>>  
>>  drm_connector_attach_encoder(connector, encoder);
>>  
>> +cec_fill_conn_info_from_drm(_info, connector);
>> +
>> +notifier = cec_notifier_conn_register(hdmi->dev, NULL, _info);
>> +if (!notifier)
>> +return -ENOMEM;
>> +
>> +mutex_lock(>cec_notifier_mutex);
>> +hdmi->cec_notifier = notifier;
>> +mutex_unlock(>cec_notifier_mutex);
>> +
>>  return 0;
>>  }
>>  
>> +static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
>> +{
>> +struct dw_hdmi *hdmi = bridge->driver_private;
>> +
>> +mutex_lock(>cec_notifier_mutex);
>> +cec_notifier_conn_unregister(hdmi->cec_notifier);
>> +hdmi->cec_notifier = NULL;
>> +mutex_unlock(>cec_notifier_mutex);
>> +}
>> +
>>  static enum drm_mode_status
>>  dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
>>const struct drm_display_mode *mode)
>> @@ -2266,6 +2289,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge 
>> *bridge)
>>  
>>  static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
>>  .attach = dw_hdmi_bridge_attach,
>> +.detach = dw_hdmi_bridge_detach,
>>  .enable = dw_hdmi_bridge_enable,
>>  .disable = dw_hdmi_bridge_disable,
>>  .mode_set = dw_hdmi_bridge_mode_set,
>> @@ -2373,9 +2397,11 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>> phy_stat & HDMI_PHY_HPD,
>> phy_stat & HDMI_PHY_RX_SENSE);
>>  
>> -if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
>> -cec_notifier_set_phys_addr(hdmi->cec_notifier,
>> -   CEC_PHYS_ADDR_INVALID);
>> +if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
>> +mutex_lock(>cec_notifier_mutex);
>> +cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
>> +mutex_unlock(>cec_notifier_mutex);
>> +}
>>  }
>>  
>>  if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>> @@ -2561,6 +2587,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>  
>

Re: [PATCH v7 0/9] drm: cec: convert DRM drivers to the new notifier API

2019-08-19 Thread Hans Verkuil
Hi all,

The patches in this series can be applied independently from each other.

If you maintain one of these drivers and you want to merge it for v5.4
yourself, then please do so and let me know. If you prefer I commit it
to drm-misc, then please review and (hopefully) Ack the patch.

I would really like to get this in for v5.4 so I can get the userspace
bits in for v5.4 as well through the media subsystem.

Dariusz, can you post a v7.1 for patch 5/9 fixing the typo?

Thanks!

Hans

On 8/14/19 12:44 PM, Dariusz Marcinkiewicz wrote:
> This series updates DRM drivers to use new CEC notifier API.
> 
> Changes since v6:
>   Made CEC notifiers' registration and de-registration symmetric
>   in tda998x and dw-hdmi drivers. Also, accidentally dropped one
>   patch in v6 (change to drm_dp_cec), brought it back now.
> Changes since v5:
> Fixed a warning about a missing comment for a new member of
>   drm_dp_aux_cec struct. Sending to a wider audience,
>   including maintainers of respective drivers.
> Changes since v4:
>   Addressing review comments.
> Changes since v3:
> Updated adapter flags in dw-hdmi-cec.
> Changes since v2:
>   Include all DRM patches from "cec: improve notifier support,
>   add connector info connector info" series.
> Changes since v1:
>   Those patches delay creation of notifiers until respective
>   connectors are constructed. It seems that those patches, for a
>   couple of drivers, by adding the delay, introduce a race between
>   notifiers' creation and the IRQs handling threads - at least I
>   don't see anything obvious in there that would explicitly forbid
>   such races to occur. v2 adds a write barrier to make sure IRQ
>   threads see the notifier once it is created (replacing the
>   WRITE_ONCE I put in v1). The best thing to do here, I believe,
>   would be not to have any synchronization and make sure that an IRQ
>   only gets enabled after the notifier is created.
> Dariusz Marcinkiewicz (9):
>   drm_dp_cec: add connector info support.
>   drm/i915/intel_hdmi: use cec_notifier_conn_(un)register
>   dw-hdmi-cec: use cec_notifier_cec_adap_(un)register
>   tda9950: use cec_notifier_cec_adap_(un)register
>   drm: tda998x: use cec_notifier_conn_(un)register
>   drm: sti: use cec_notifier_conn_(un)register
>   drm: tegra: use cec_notifier_conn_(un)register
>   drm: dw-hdmi: use cec_notifier_conn_(un)register
>   drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register
> 
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  2 +-
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 13 +++---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 46 +--
>  drivers/gpu/drm/drm_dp_cec.c  | 25 ++
>  drivers/gpu/drm/exynos/exynos_hdmi.c  | 31 +++--
>  drivers/gpu/drm/i2c/tda9950.c | 12 ++---
>  drivers/gpu/drm/i2c/tda998x_drv.c | 36 ++-
>  drivers/gpu/drm/i915/display/intel_dp.c   |  4 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c | 13 --
>  drivers/gpu/drm/nouveau/nouveau_connector.c   |  3 +-
>  drivers/gpu/drm/sti/sti_hdmi.c| 19 +---
>  drivers/gpu/drm/tegra/output.c| 28 ---
>  include/drm/drm_dp_helper.h   | 17 ---
>  13 files changed, 155 insertions(+), 94 deletions(-)
> 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v7 6/9] drm: sti: use cec_notifier_conn_(un)register

2019-08-19 Thread Hans Verkuil
On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill
> in the cec_connector_info.
> 
> Changes since v2:
>   Don't invalidate physical address before unregistering the
>   notifier.
> 
> Signed-off-by: Dariusz Marcinkiewicz 

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/gpu/drm/sti/sti_hdmi.c | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 9862c322f0c4a..bd15902b825ad 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -1256,6 +1256,7 @@ static int sti_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
>   struct drm_device *drm_dev = data;
>   struct drm_encoder *encoder;
>   struct sti_hdmi_connector *connector;
> + struct cec_connector_info conn_info;
>   struct drm_connector *drm_connector;
>   struct drm_bridge *bridge;
>   int err;
> @@ -1318,6 +1319,14 @@ static int sti_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
>   goto err_sysfs;
>   }
>  
> + cec_fill_conn_info_from_drm(_info, drm_connector);
> + hdmi->notifier = cec_notifier_conn_register(>dev, NULL,
> + _info);
> + if (!hdmi->notifier) {
> + hdmi->drm_connector = NULL;
> + return -ENOMEM;
> + }
> +
>   /* Enable default interrupts */
>   hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN);
>  
> @@ -1331,6 +1340,9 @@ static int sti_hdmi_bind(struct device *dev, struct 
> device *master, void *data)
>  static void sti_hdmi_unbind(struct device *dev,
>   struct device *master, void *data)
>  {
> + struct sti_hdmi *hdmi = dev_get_drvdata(dev);
> +
> + cec_notifier_conn_unregister(hdmi->notifier);
>  }
>  
>  static const struct component_ops sti_hdmi_ops = {
> @@ -1436,10 +1448,6 @@ static int sti_hdmi_probe(struct platform_device *pdev)
>   goto release_adapter;
>   }
>  
> - hdmi->notifier = cec_notifier_get(>dev);
> - if (!hdmi->notifier)
> - goto release_adapter;
> -
>   hdmi->reset = devm_reset_control_get(dev, "hdmi");
>   /* Take hdmi out of reset */
>   if (!IS_ERR(hdmi->reset))
> @@ -1459,14 +1467,11 @@ static int sti_hdmi_remove(struct platform_device 
> *pdev)
>  {
>   struct sti_hdmi *hdmi = dev_get_drvdata(>dev);
>  
> - cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
> -
>   i2c_put_adapter(hdmi->ddc_adapt);
>   if (hdmi->audio_pdev)
>   platform_device_unregister(hdmi->audio_pdev);
>   component_del(>dev, _hdmi_ops);
>  
> - cec_notifier_put(hdmi->notifier);
>   return 0;
>  }
>  
> 



Re: [PATCH v7 7/9] drm: tegra: use cec_notifier_conn_(un)register

2019-08-19 Thread Hans Verkuil
On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill in
> the cec_connector_info.
> 
> Changes since v4:
>   - only create a CEC notifier for HDMI connectors
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> Tested-by: Hans Verkuil 

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/gpu/drm/tegra/output.c | 28 +---
>  1 file changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
> index bdcaa4c7168cf..34373734ff689 100644
> --- a/drivers/gpu/drm/tegra/output.c
> +++ b/drivers/gpu/drm/tegra/output.c
> @@ -70,6 +70,11 @@ tegra_output_connector_detect(struct drm_connector 
> *connector, bool force)
>  
>  void tegra_output_connector_destroy(struct drm_connector *connector)
>  {
> + struct tegra_output *output = connector_to_output(connector);
> +
> + if (output->cec)
> + cec_notifier_conn_unregister(output->cec);
> +
>   drm_connector_unregister(connector);
>   drm_connector_cleanup(connector);
>  }
> @@ -163,18 +168,11 @@ int tegra_output_probe(struct tegra_output *output)
>   disable_irq(output->hpd_irq);
>   }
>  
> - output->cec = cec_notifier_get(output->dev);
> - if (!output->cec)
> - return -ENOMEM;
> -
>   return 0;
>  }
>  
>  void tegra_output_remove(struct tegra_output *output)
>  {
> - if (output->cec)
> - cec_notifier_put(output->cec);
> -
>   if (output->hpd_gpio)
>   free_irq(output->hpd_irq, output);
>  
> @@ -184,6 +182,7 @@ void tegra_output_remove(struct tegra_output *output)
>  
>  int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
>  {
> + int connector_type;
>   int err;
>  
>   if (output->panel) {
> @@ -199,6 +198,21 @@ int tegra_output_init(struct drm_device *drm, struct 
> tegra_output *output)
>   if (output->hpd_gpio)
>   enable_irq(output->hpd_irq);
>  
> + connector_type = output->connector.connector_type;
> + /*
> +  * Create a CEC notifier for HDMI connector.
> +  */
> + if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
> + connector_type == DRM_MODE_CONNECTOR_HDMIB) {
> + struct cec_connector_info conn_info;
> +
> + cec_fill_conn_info_from_drm(_info, >connector);
> + output->cec = cec_notifier_conn_register(output->dev, NULL,
> +  _info);
> + if (!output->cec)
> + return -ENOMEM;
> + }
> +
>   return 0;
>  }
>  
> 



Re: [PATCH v7 8/9] drm: dw-hdmi: use cec_notifier_conn_(un)register

2019-08-19 Thread Hans Verkuil
On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill in
> the cec_connector_info.
> 
> Changes since v6:
> - move cec_notifier_conn_unregister to a bridge detach
> function,
>   - add a mutex protecting a CEC notifier.
> Changes since v4:
>   - typo fix
> Changes since v2:
>   - removed unnecessary NULL check before a call to
>   cec_notifier_conn_unregister,
>   - use cec_notifier_phys_addr_invalidate to invalidate physical
>   address.
> Changes since v1:
>   Add memory barrier to make sure that the notifier
>   becomes visible to the irq thread once it is fully
>   constructed.
> 
> Signed-off-by: Dariusz Marcinkiewicz 

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 45 +++
>  1 file changed, 30 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 83b94b66e464e..55162c9092f71 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -190,6 +190,7 @@ struct dw_hdmi {
>   void (*enable_audio)(struct dw_hdmi *hdmi);
>   void (*disable_audio)(struct dw_hdmi *hdmi);
>  
> + struct mutex cec_notifier_mutex;
>   struct cec_notifier *cec_notifier;
>  };
>  
> @@ -2194,6 +2195,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
> *bridge)
>   struct dw_hdmi *hdmi = bridge->driver_private;
>   struct drm_encoder *encoder = bridge->encoder;
>   struct drm_connector *connector = >connector;
> + struct cec_connector_info conn_info;
> + struct cec_notifier *notifier;
>  
>   connector->interlace_allowed = 1;
>   connector->polled = DRM_CONNECTOR_POLL_HPD;
> @@ -2207,9 +2210,29 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
> *bridge)
>  
>   drm_connector_attach_encoder(connector, encoder);
>  
> + cec_fill_conn_info_from_drm(_info, connector);
> +
> + notifier = cec_notifier_conn_register(hdmi->dev, NULL, _info);
> + if (!notifier)
> + return -ENOMEM;
> +
> + mutex_lock(>cec_notifier_mutex);
> + hdmi->cec_notifier = notifier;
> + mutex_unlock(>cec_notifier_mutex);
> +
>   return 0;
>  }
>  
> +static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
> +{
> + struct dw_hdmi *hdmi = bridge->driver_private;
> +
> + mutex_lock(>cec_notifier_mutex);
> + cec_notifier_conn_unregister(hdmi->cec_notifier);
> + hdmi->cec_notifier = NULL;
> + mutex_unlock(>cec_notifier_mutex);
> +}
> +
>  static enum drm_mode_status
>  dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> const struct drm_display_mode *mode)
> @@ -2266,6 +2289,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge 
> *bridge)
>  
>  static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
>   .attach = dw_hdmi_bridge_attach,
> + .detach = dw_hdmi_bridge_detach,
>   .enable = dw_hdmi_bridge_enable,
>   .disable = dw_hdmi_bridge_disable,
>   .mode_set = dw_hdmi_bridge_mode_set,
> @@ -2373,9 +2397,11 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  phy_stat & HDMI_PHY_HPD,
>  phy_stat & HDMI_PHY_RX_SENSE);
>  
> - if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> - cec_notifier_set_phys_addr(hdmi->cec_notifier,
> -CEC_PHYS_ADDR_INVALID);
> + if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
> + mutex_lock(>cec_notifier_mutex);
> + cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
> + mutex_unlock(>cec_notifier_mutex);
> + }
>   }
>  
>   if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> @@ -2561,6 +2587,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  
>   mutex_init(>mutex);
>   mutex_init(>audio_mutex);
> + mutex_init(>cec_notifier_mutex);
>   spin_lock_init(>audio_lock);
>  
>   ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
> @@ -2693,12 +2720,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
>   if (ret)
>   goto err_iahb;
>  
> - hdmi->cec_notifier = cec_notifier_get(dev);
> - if (!hdmi->cec_notifier) {
> - ret = -ENOM

Re: [PATCH v7 9/9] drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register

2019-08-19 Thread Hans Verkuil
On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill in
> the cec_connector_info.
> 
> Changes since v2:
>   - removed unnecessary call to invalidate phys address before
>   deregistering the notifier,
>   - use cec_notifier_phys_addr_invalidate instead of setting
>   invalid address on a notifier.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> Tested-by: Hans Verkuil 

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/gpu/drm/exynos/exynos_hdmi.c | 31 
>  1 file changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
> b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index bc1565f1822ab..d532b468d9af5 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -852,6 +852,10 @@ static enum drm_connector_status hdmi_detect(struct 
> drm_connector *connector,
>  
>  static void hdmi_connector_destroy(struct drm_connector *connector)
>  {
> + struct hdmi_context *hdata = connector_to_hdmi(connector);
> +
> + cec_notifier_conn_unregister(hdata->notifier);
> +
>   drm_connector_unregister(connector);
>   drm_connector_cleanup(connector);
>  }
> @@ -935,6 +939,7 @@ static int hdmi_create_connector(struct drm_encoder 
> *encoder)
>  {
>   struct hdmi_context *hdata = encoder_to_hdmi(encoder);
>   struct drm_connector *connector = >connector;
> + struct cec_connector_info conn_info;
>   int ret;
>  
>   connector->interlace_allowed = true;
> @@ -957,6 +962,15 @@ static int hdmi_create_connector(struct drm_encoder 
> *encoder)
>   DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n");
>   }
>  
> + cec_fill_conn_info_from_drm(_info, connector);
> +
> + hdata->notifier = cec_notifier_conn_register(hdata->dev, NULL,
> +  _info);
> + if (hdata->notifier == NULL) {
> + ret = -ENOMEM;
> + DRM_DEV_ERROR(hdata->dev, "Failed to allocate CEC notifier\n");
> + }
> +
>   return ret;
>  }
>  
> @@ -1528,8 +1542,8 @@ static void hdmi_disable(struct drm_encoder *encoder)
>*/
>   mutex_unlock(>mutex);
>   cancel_delayed_work(>hotplug_work);
> - cec_notifier_set_phys_addr(hdata->notifier,
> -CEC_PHYS_ADDR_INVALID);
> + if (hdata->notifier)
> + cec_notifier_phys_addr_invalidate(hdata->notifier);
>   return;
>   }
>  
> @@ -2006,12 +2020,6 @@ static int hdmi_probe(struct platform_device *pdev)
>   }
>   }
>  
> - hdata->notifier = cec_notifier_get(>dev);
> - if (hdata->notifier == NULL) {
> - ret = -ENOMEM;
> - goto err_hdmiphy;
> - }
> -
>   pm_runtime_enable(dev);
>  
>   audio_infoframe = >audio.infoframe;
> @@ -2023,7 +2031,7 @@ static int hdmi_probe(struct platform_device *pdev)
>  
>   ret = hdmi_register_audio_device(hdata);
>   if (ret)
> - goto err_notifier_put;
> + goto err_runtime_disable;
>  
>   ret = component_add(>dev, _component_ops);
>   if (ret)
> @@ -2034,8 +2042,7 @@ static int hdmi_probe(struct platform_device *pdev)
>  err_unregister_audio:
>   platform_device_unregister(hdata->audio.pdev);
>  
> -err_notifier_put:
> - cec_notifier_put(hdata->notifier);
> +err_runtime_disable:
>   pm_runtime_disable(dev);
>  
>  err_hdmiphy:
> @@ -2054,12 +2061,10 @@ static int hdmi_remove(struct platform_device *pdev)
>   struct hdmi_context *hdata = platform_get_drvdata(pdev);
>  
>   cancel_delayed_work_sync(>hotplug_work);
> - cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
>  
>   component_del(>dev, _component_ops);
>   platform_device_unregister(hdata->audio.pdev);
>  
> - cec_notifier_put(hdata->notifier);
>   pm_runtime_disable(>dev);
>  
>   if (!IS_ERR(hdata->reg_hdmi_en))
> 



Re: [PATCH v7 5/9] drm: tda998x: use cec_notifier_conn_(un)register

2019-08-19 Thread Hans Verkuil
On 8/14/19 12:45 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill
> in the cec_connector_info.
> 
> Changes since v6:
> - move cec_notifier_conn_unregister to tda998x_bridge_detach,
>   - add a mutex protecting accesses to a CEC notifier.
> Changes since v2:
>   - cec_notifier_phys_addr_invalidate where appropriate,
>   - don't check for NULL notifier before calling
>   cec_notifier_conn_unregister.
> Changes since v1:
>   Add memory barrier to make sure that the notifier
>   becomes visible to the irq thread once it is
>   fully constructed.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> ---
>  drivers/gpu/drm/i2c/tda998x_drv.c | 36 +--
>  1 file changed, 25 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
> b/drivers/gpu/drm/i2c/tda998x_drv.c
> index 61e042918a7fc..643480415473f 100644
> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> @@ -82,6 +82,8 @@ struct tda998x_priv {
>   u8 audio_port_enable[AUDIO_ROUTE_NUM];
>   struct tda9950_glue cec_glue;
>   struct gpio_desc *calib;
> +
> + struct mutex cec_notifiy_mutex;

Typo: notifiy -> notify

Regards,

Hans

>   struct cec_notifier *cec_notify;
>  };
>  
> @@ -805,8 +807,11 @@ static irqreturn_t tda998x_irq_thread(int irq, void 
> *data)
>   tda998x_edid_delay_start(priv);
>   } else {
>   schedule_work(>detect_work);
> - cec_notifier_set_phys_addr(priv->cec_notify,
> -CEC_PHYS_ADDR_INVALID);
> +
> + mutex_lock(>cec_notifiy_mutex);
> + cec_notifier_phys_addr_invalidate(
> + priv->cec_notify);
> + mutex_unlock(>cec_notifiy_mutex);
>   }
>  
>   handled = true;
> @@ -1331,6 +1336,8 @@ static int tda998x_connector_init(struct tda998x_priv 
> *priv,
> struct drm_device *drm)
>  {
>   struct drm_connector *connector = >connector;
> + struct cec_connector_info conn_info;
> + struct cec_notifier *notifier;
>   int ret;
>  
>   connector->interlace_allowed = 1;
> @@ -1347,6 +1354,16 @@ static int tda998x_connector_init(struct tda998x_priv 
> *priv,
>   if (ret)
>   return ret;
>  
> + cec_fill_conn_info_from_drm(_info, connector);
> +
> + notifier = cec_notifier_conn_register(priv->cec_glue.parent,
> +   NULL, _info);
> + return -ENOMEM;
> +
> + mutex_lock(>cec_notifiy_mutex);
> + priv->cec_notify = notifier;
> + mutex_unlock(>cec_notifiy_mutex);
> +
>   drm_connector_attach_encoder(>connector,
>priv->bridge.encoder);
>  
> @@ -1366,6 +1383,11 @@ static void tda998x_bridge_detach(struct drm_bridge 
> *bridge)
>  {
>   struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
>  
> + mutex_lock(>cec_notifiy_mutex);
> + cec_notifier_conn_unregister(priv->cec_notify);
> + priv->cec_notify = NULL;
> + mutex_unlock(>cec_notifiy_mutex);
> +
>   drm_connector_cleanup(>connector);
>  }
>  
> @@ -1789,9 +1811,6 @@ static void tda998x_destroy(struct device *dev)
>   cancel_work_sync(>detect_work);
>  
>   i2c_unregister_device(priv->cec);
> -
> - if (priv->cec_notify)
> - cec_notifier_put(priv->cec_notify);
>  }
>  
>  static int tda998x_create(struct device *dev)
> @@ -1812,6 +1831,7 @@ static int tda998x_create(struct device *dev)
>   mutex_init(>mutex);   /* protect the page access */
>   mutex_init(>audio_mutex); /* protect access from audio thread */
>   mutex_init(>edid_mutex);
> + mutex_init(>cec_notifiy_mutex);
>   INIT_LIST_HEAD(>bridge.list);
>   init_waitqueue_head(>edid_delay_waitq);
>   timer_setup(>edid_delay_timer, tda998x_edid_delay_done, 0);
> @@ -1916,12 +1936,6 @@ static int tda998x_create(struct device *dev)
>   cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
>   }
>  
> - priv->cec_notify = cec_notifier_get(dev);
> - if (!priv->cec_notify) {
> - ret = -ENOMEM;
> - goto fail;
> - }
> -
>   priv->cec_glue.parent = dev;
>   priv->cec_glue.data = priv;
>   priv->cec_glue.init = tda998x_cec_hook_init;
> 



Re: [PATCH v6 3/8] tda9950: use cec_notifier_cec_adap_(un)register

2019-08-13 Thread Hans Verkuil
On 8/13/19 1:32 PM, Russell King - ARM Linux admin wrote:
> On Tue, Aug 13, 2019 at 01:02:35PM +0200, Dariusz Marcinkiewicz wrote:
>> Use the new cec_notifier_cec_adap_(un)register() functions to
>> (un)register the notifier for the CEC adapter.
>>
>> Signed-off-by: Dariusz Marcinkiewicz 
>> Signed-off-by: Hans Verkuil 
>> Tested-by: Hans Verkuil 
>> ---
>>  drivers/gpu/drm/i2c/tda9950.c | 12 ++--
>>  1 file changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i2c/tda9950.c b/drivers/gpu/drm/i2c/tda9950.c
>> index 8039fc0d83db4..a5a75bdeb7a5f 100644
>> --- a/drivers/gpu/drm/i2c/tda9950.c
>> +++ b/drivers/gpu/drm/i2c/tda9950.c
>> @@ -420,7 +420,8 @@ static int tda9950_probe(struct i2c_client *client,
>>  priv->hdmi = glue->parent;
>>  
>>  priv->adap = cec_allocate_adapter(_cec_ops, priv, "tda9950",
>> -  CEC_CAP_DEFAULTS,
>> +  CEC_CAP_DEFAULTS |
>> +  CEC_CAP_CONNECTOR_INFO,
>>CEC_MAX_LOG_ADDRS);
>>  if (IS_ERR(priv->adap))
>>  return PTR_ERR(priv->adap);
>> @@ -457,13 +458,14 @@ static int tda9950_probe(struct i2c_client *client,
>>  if (ret < 0)
>>  return ret;
>>  
>> -priv->notify = cec_notifier_get(priv->hdmi);
>> +priv->notify = cec_notifier_cec_adap_register(priv->hdmi, NULL,
>> +  priv->adap);
>>  if (!priv->notify)
>>  return -ENOMEM;
>>  
>>  ret = cec_register_adapter(priv->adap, priv->hdmi);
>>  if (ret < 0) {
>> -cec_notifier_put(priv->notify);
>> +cec_notifier_cec_adap_unregister(priv->notify);
>>  return ret;
>>  }
>>  
>> @@ -473,8 +475,6 @@ static int tda9950_probe(struct i2c_client *client,
>>   */
>>  devm_remove_action(dev, tda9950_cec_del, priv);
>>  
>> -cec_register_cec_notifier(priv->adap, priv->notify);
>> -
>>  return 0;
>>  }
>>  
>> @@ -482,8 +482,8 @@ static int tda9950_remove(struct i2c_client *client)
>>  {
>>  struct tda9950_priv *priv = i2c_get_clientdata(client);
>>  
>> +cec_notifier_cec_adap_unregister(priv->notify);
>>  cec_unregister_adapter(priv->adap);
>> -cec_notifier_put(priv->notify);
> 
> It looks weird to have an unexpectedly different ordering of
> unregistration from the registration path - normally, unregistration
> is the reverse order of initialisation.
> 
> In the initialisation path, it seems that we register the notifier
> and _then_ the adapter.  Here, we unregister the notifier and then
> the adapter rather than what would normally be expected.  Why is
> this?  I suspect there will be drivers created that do this the
> "normal" way round, so if this is a requirement, it needs to be made
> plainly obvious.

It's not a requirement, it just feels better to do it in this order
since cec_unregister_adapter will in general also delete the adapter
(unless an application keeps the cec device open).

So the order is actually: allocate_adapter, then register notifier
and: unregister notifier, then unregister (and typically delete) adapter

Regards,

Hans

> 
>>  
>>  return 0;
>>  }
>> -- 
>> 2.23.0.rc1.153.gdeed80330f-goog
>>
>>
> 



Re: [PATCH] drm/bridge: dw-hdmi: move cec PA invalidation to dw_hdmi_setup_rx_sense()

2019-08-13 Thread Hans Verkuil
On 8/13/19 11:32 AM, Hans Verkuil wrote:
> When testing CEC on the AML-S905X-CC board I noticed that the CEC physical
> address was not invalidated when the HDMI cable was unplugged. Some more
> digging showed that meson uses meson_dw_hdmi.c to handle the HPD.
> 
> Both dw_hdmi_irq() and dw_hdmi_top_thread_irq() (in meson_dw_hdmi.c) call
> the dw_hdmi_setup_rx_sense() function. So move the code to invalidate the
> CEC physical address to that function, so that it is independent of where
> the HPD interrupt happens.
> 
> Tested with both a AML-S905X-CC and a Khadas VIM2 board.
> 
> Signed-off-by: Hans Verkuil 

Please disregard this patch, Jonas Karlman will post a different series
which will fix this in a different way.

Regards,

Hans

> ---
> Note: an alternative would be to make a new dw-hdmi function such as
> dw_hdmi_cec_phys_addr_invalidate() that is called from meson_dw_hdmi.c.
> I decided not to do that since this patch is minimally invasive, but
> that can obviously be changed if that approach is preferred.
> ---
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index c5a854af54f8..e899b31e1432 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2329,6 +2329,13 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool 
> hpd, bool rx_sense)
>   dw_hdmi_update_power(hdmi);
>   dw_hdmi_update_phy_mask(hdmi);
>   }
> + if (!hpd && !rx_sense) {
> + struct cec_notifier *notifier = READ_ONCE(hdmi->cec_notifier);
> +
> + if (notifier)
> + cec_notifier_phys_addr_invalidate(notifier);
> + }
> +
>   mutex_unlock(>mutex);
>  }
>  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
> @@ -2369,14 +2376,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>   dw_hdmi_setup_rx_sense(hdmi,
>  phy_stat & HDMI_PHY_HPD,
>  phy_stat & HDMI_PHY_RX_SENSE);
> -
> - if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
> - struct cec_notifier *notifier;
> -
> - notifier = READ_ONCE(hdmi->cec_notifier);
> - if (notifier)
> - cec_notifier_phys_addr_invalidate(notifier);
> - }
>   }
> 
>   if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> 



Re: [PATCH v6 7/8] drm: dw-hdmi: use cec_notifier_conn_(un)register

2019-08-13 Thread Hans Verkuil
On 8/13/19 1:02 PM, Dariusz Marcinkiewicz wrote:
> Use the new cec_notifier_conn_(un)register() functions to
> (un)register the notifier for the HDMI connector, and fill in
> the cec_connector_info.
> 
> Changes since v4:
>   - typo fix
> Changes since v2:
>   - removed unnecessary NULL check before a call to
>   cec_notifier_conn_unregister,
>   - use cec_notifier_phys_addr_invalidate to invalidate physical
>   address.
> Changes since v1:
>   Add memory barrier to make sure that the notifier
>   becomes visible to the irq thread once it is fully
>   constructed.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> Tested-by: Hans Verkuil 
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 36 ++-
>  1 file changed, 22 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 83b94b66e464e..c00184700bb9d 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2194,6 +2194,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
> *bridge)
>   struct dw_hdmi *hdmi = bridge->driver_private;
>   struct drm_encoder *encoder = bridge->encoder;
>   struct drm_connector *connector = >connector;
> + struct cec_connector_info conn_info;
> + struct cec_notifier *notifier;
>  
>   connector->interlace_allowed = 1;
>   connector->polled = DRM_CONNECTOR_POLL_HPD;
> @@ -2207,6 +2209,18 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
> *bridge)
>  
>   drm_connector_attach_encoder(connector, encoder);
>  
> + cec_fill_conn_info_from_drm(_info, connector);
> +
> + notifier = cec_notifier_conn_register(hdmi->dev, NULL, _info);
> + if (!notifier)
> + return -ENOMEM;
> + /*
> +  * Make sure that dw_hdmi_irq thread does see the notifier
> +  * when it fully constructed.
> +  */
> + smp_wmb();
> + hdmi->cec_notifier = notifier;
> +
>   return 0;
>  }
>  
> @@ -2373,9 +2387,13 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  phy_stat & HDMI_PHY_HPD,
>  phy_stat & HDMI_PHY_RX_SENSE);
>  
> - if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> - cec_notifier_set_phys_addr(hdmi->cec_notifier,
> -CEC_PHYS_ADDR_INVALID);
> + if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
> + struct cec_notifier *notifier;
> +
> + notifier = READ_ONCE(hdmi->cec_notifier);
> + if (notifier)
> + cec_notifier_phys_addr_invalidate(notifier);
> + }
>   }
>  
>   if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> @@ -2693,12 +2711,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
>   if (ret)
>   goto err_iahb;
>  
> - hdmi->cec_notifier = cec_notifier_get(dev);
> - if (!hdmi->cec_notifier) {
> - ret = -ENOMEM;
> - goto err_iahb;
> - }
> -
>   /*
>* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>* N and cts values before enabling phy
> @@ -2796,9 +2808,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
>   hdmi->ddc = NULL;
>   }
>  
> - if (hdmi->cec_notifier)
> - cec_notifier_put(hdmi->cec_notifier);
> -
>   clk_disable_unprepare(hdmi->iahb_clk);
>   if (hdmi->cec_clk)
>   clk_disable_unprepare(hdmi->cec_clk);
> @@ -2820,8 +2829,7 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>   /* Disable all interrupts */
>   hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
>  
> - if (hdmi->cec_notifier)
> - cec_notifier_put(hdmi->cec_notifier);
> + cec_notifier_conn_unregister(hdmi->cec_notifier);

Russell's review caused me to take another look at this series, and it made
wonder if cec_notifier_conn_unregister() shouldn't be called from bridge_detach?

Regards,

Hans

>  
>   clk_disable_unprepare(hdmi->iahb_clk);
>   clk_disable_unprepare(hdmi->isfr_clk);
> 



Re: [PATCH] drm/bridge: dw-hdmi: move cec PA invalidation to dw_hdmi_setup_rx_sense()

2019-08-13 Thread Hans Verkuil
On 8/13/19 12:18 PM, Jonas Karlman wrote:
> As an alternative I have a patch [1] to submit that moves 
> cec_notifier_phys_addr_invalidate() call
> from dw_hdmi_irq() to dw_hdmi_connector_detect() in order to address an issue 
> with
> stale CEC phys addr and stale EDID/ELD data after TV or AVR uses a 100ms HPD 
> pulse
> to signal EDID has changed, full patchset at [2].
> 
> At the moment CEC phys address is invalidated directly at HPD, leaving the 
> address as invalid
> after a 100ms HPD pulse, phys address may later be restored to a valid phys 
> address when
> get_modes() is called by drm core.
> 
> Should I wait on your and related patches to be merged before submitting my 
> series?

Your patch fixes this issue as well, so just ignore my patch and submit your 
series.
Please CC me when you post your series.

Regards,

Hans

> 
> [1] 
> https://github.com/Kwiboo/linux-rockchip/commit/2f4f99c82983e70952668c21f1c56a0241bd75f2
> [2] 
> https://github.com/Kwiboo/linux-rockchip/compare/next-20190813...next-20190813-cec-eld
> 
> Regards,
> Jonas
> 
> On 2019-08-13 11:34, Hans Verkuil wrote:
>> CC Dariusz as well, since this issue was discovered when testing his
>> CEC patches.
>>
>> Regards,
>>
>>  Hans
>>
>> On 8/13/19 11:32 AM, Hans Verkuil wrote:
>>> When testing CEC on the AML-S905X-CC board I noticed that the CEC physical
>>> address was not invalidated when the HDMI cable was unplugged. Some more
>>> digging showed that meson uses meson_dw_hdmi.c to handle the HPD.
>>>
>>> Both dw_hdmi_irq() and dw_hdmi_top_thread_irq() (in meson_dw_hdmi.c) call
>>> the dw_hdmi_setup_rx_sense() function. So move the code to invalidate the
>>> CEC physical address to that function, so that it is independent of where
>>> the HPD interrupt happens.
>>>
>>> Tested with both a AML-S905X-CC and a Khadas VIM2 board.
>>>
>>> Signed-off-by: Hans Verkuil 
>>> ---
>>> Note: an alternative would be to make a new dw-hdmi function such as
>>> dw_hdmi_cec_phys_addr_invalidate() that is called from meson_dw_hdmi.c.
>>> I decided not to do that since this patch is minimally invasive, but
>>> that can obviously be changed if that approach is preferred.
>>> ---
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> index c5a854af54f8..e899b31e1432 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -2329,6 +2329,13 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, 
>>> bool hpd, bool rx_sense)
>>> dw_hdmi_update_power(hdmi);
>>> dw_hdmi_update_phy_mask(hdmi);
>>> }
>>> +   if (!hpd && !rx_sense) {
>>> +   struct cec_notifier *notifier = READ_ONCE(hdmi->cec_notifier);
>>> +
>>> +   if (notifier)
>>> +   cec_notifier_phys_addr_invalidate(notifier);
>>> +   }
>>> +
>>> mutex_unlock(>mutex);
>>>  }
>>>  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
>>> @@ -2369,14 +2376,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>> dw_hdmi_setup_rx_sense(hdmi,
>>>phy_stat & HDMI_PHY_HPD,
>>>phy_stat & HDMI_PHY_RX_SENSE);
>>> -
>>> -   if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
>>> -   struct cec_notifier *notifier;
>>> -
>>> -   notifier = READ_ONCE(hdmi->cec_notifier);
>>> -   if (notifier)
>>> -   cec_notifier_phys_addr_invalidate(notifier);
>>> -   }
>>> }
>>>
>>> if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>
> 



Re: [PATCH v2] i2c: replace i2c_new_secondary_device with an ERR_PTR variant

2019-08-13 Thread Hans Verkuil
On 8/9/19 5:40 PM, Wolfram Sang wrote:
> In the general move to have i2c_new_*_device functions which return
> ERR_PTR instead of NULL, this patch converts i2c_new_secondary_device().
> 
> There are only few users, so this patch converts the I2C core and all
> users in one go. The function gets renamed to i2c_new_ancillary_device()
> so out-of-tree users will get a build failure to understand they need to
> adapt their error checking code.
> 
> Signed-off-by: Wolfram Sang 
> Reviewed-by: Kieran Bingham  # 
> adv748x
> Reviewed-by: Laurent Pinchart  # adv7511

For adv7604:

Reviewed-by: Hans Verkuil 

Thanks!

Hans

> ---
> 
> Changes since v1:
> 
> * adv7604: use a local variable for error handling
> * adv7604: simplify unregistering dummy clients because I2C core helper
>is NULL ptr aware
> * added tags for adv748x and adv7511
> 
> Thanks Kieran and Laurent!
> 
> 
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 18 
>  drivers/i2c/i2c-core-base.c  | 10 -
>  drivers/media/i2c/adv748x/adv748x-core.c |  6 +++---
>  drivers/media/i2c/adv7604.c  | 22 +++-
>  include/linux/i2c.h  |  2 +-
>  5 files changed, 30 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index f6d2681f6927..9e13e466e72c 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -981,10 +981,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
>  {
>   int ret;
>  
> - adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
> + adv->i2c_cec = i2c_new_ancillary_device(adv->i2c_main, "cec",
>   ADV7511_CEC_I2C_ADDR_DEFAULT);
> - if (!adv->i2c_cec)
> - return -EINVAL;
> + if (IS_ERR(adv->i2c_cec))
> + return PTR_ERR(adv->i2c_cec);
>   i2c_set_clientdata(adv->i2c_cec, adv);
>  
>   adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
> @@ -1165,20 +1165,20 @@ static int adv7511_probe(struct i2c_client *i2c, 
> const struct i2c_device_id *id)
>  
>   adv7511_packet_disable(adv7511, 0x);
>  
> - adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
> + adv7511->i2c_edid = i2c_new_ancillary_device(i2c, "edid",
>   ADV7511_EDID_I2C_ADDR_DEFAULT);
> - if (!adv7511->i2c_edid) {
> - ret = -EINVAL;
> + if (IS_ERR(adv7511->i2c_edid)) {
> + ret = PTR_ERR(adv7511->i2c_edid);
>   goto uninit_regulators;
>   }
>  
>   regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
>adv7511->i2c_edid->addr << 1);
>  
> - adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
> + adv7511->i2c_packet = i2c_new_ancillary_device(i2c, "packet",
>   ADV7511_PACKET_I2C_ADDR_DEFAULT);
> - if (!adv7511->i2c_packet) {
> - ret = -EINVAL;
> + if (IS_ERR(adv7511->i2c_packet)) {
> + ret = PTR_ERR(adv7511->i2c_packet);
>   goto err_i2c_unregister_edid;
>   }
>  
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index f26ed495d384..76cb91e064b8 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -966,7 +966,7 @@ struct i2c_client *devm_i2c_new_dummy_device(struct 
> device *dev,
>  EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device);
>  
>  /**
> - * i2c_new_secondary_device - Helper to get the instantiated secondary 
> address
> + * i2c_new_ancillary_device - Helper to get the instantiated secondary 
> address
>   * and create the associated device
>   * @client: Handle to the primary client
>   * @name: Handle to specify which secondary address to get
> @@ -985,9 +985,9 @@ EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device);
>   * cell whose "reg-names" value matches the slave name.
>   *
>   * This returns the new i2c client, which should be saved for later use with
> - * i2c_unregister_device(); or NULL to indicate an error.
> + * i2c_unregister_device(); or an ERR_PTR to describe the error.
>   */
> -struct i2c_client *i2c_new_secondary_device(struct i2c_client *client,
> +struct i2c_client *i2c_new_ancillary_device(struct i2c_client *client,
>   const char *name,
>

Re: [PATCH] drm/bridge: dw-hdmi: move cec PA invalidation to dw_hdmi_setup_rx_sense()

2019-08-13 Thread Hans Verkuil
Hi Jonas,

On 8/13/19 12:18 PM, Jonas Karlman wrote:
> As an alternative I have a patch [1] to submit that moves 
> cec_notifier_phys_addr_invalidate() call
> from dw_hdmi_irq() to dw_hdmi_connector_detect() in order to address an issue 
> with
> stale CEC phys addr and stale EDID/ELD data after TV or AVR uses a 100ms HPD 
> pulse
> to signal EDID has changed, full patchset at [2].
> 
> At the moment CEC phys address is invalidated directly at HPD, leaving the 
> address as invalid
> after a 100ms HPD pulse, phys address may later be restored to a valid phys 
> address when
> get_modes() is called by drm core.
> 
> Should I wait on your and related patches to be merged before submitting my 
> series?

Let me test your patch on my meson device and see if it solves this issue as 
well.

I'll get back to you later today.

Regards,

Hans

> 
> [1] 
> https://github.com/Kwiboo/linux-rockchip/commit/2f4f99c82983e70952668c21f1c56a0241bd75f2
> [2] 
> https://github.com/Kwiboo/linux-rockchip/compare/next-20190813...next-20190813-cec-eld
> 
> Regards,
> Jonas
> 
> On 2019-08-13 11:34, Hans Verkuil wrote:
>> CC Dariusz as well, since this issue was discovered when testing his
>> CEC patches.
>>
>> Regards,
>>
>>  Hans
>>
>> On 8/13/19 11:32 AM, Hans Verkuil wrote:
>>> When testing CEC on the AML-S905X-CC board I noticed that the CEC physical
>>> address was not invalidated when the HDMI cable was unplugged. Some more
>>> digging showed that meson uses meson_dw_hdmi.c to handle the HPD.
>>>
>>> Both dw_hdmi_irq() and dw_hdmi_top_thread_irq() (in meson_dw_hdmi.c) call
>>> the dw_hdmi_setup_rx_sense() function. So move the code to invalidate the
>>> CEC physical address to that function, so that it is independent of where
>>> the HPD interrupt happens.
>>>
>>> Tested with both a AML-S905X-CC and a Khadas VIM2 board.
>>>
>>> Signed-off-by: Hans Verkuil 
>>> ---
>>> Note: an alternative would be to make a new dw-hdmi function such as
>>> dw_hdmi_cec_phys_addr_invalidate() that is called from meson_dw_hdmi.c.
>>> I decided not to do that since this patch is minimally invasive, but
>>> that can obviously be changed if that approach is preferred.
>>> ---
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> index c5a854af54f8..e899b31e1432 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -2329,6 +2329,13 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, 
>>> bool hpd, bool rx_sense)
>>> dw_hdmi_update_power(hdmi);
>>> dw_hdmi_update_phy_mask(hdmi);
>>> }
>>> +   if (!hpd && !rx_sense) {
>>> +   struct cec_notifier *notifier = READ_ONCE(hdmi->cec_notifier);
>>> +
>>> +   if (notifier)
>>> +   cec_notifier_phys_addr_invalidate(notifier);
>>> +   }
>>> +
>>> mutex_unlock(>mutex);
>>>  }
>>>  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
>>> @@ -2369,14 +2376,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>> dw_hdmi_setup_rx_sense(hdmi,
>>>phy_stat & HDMI_PHY_HPD,
>>>phy_stat & HDMI_PHY_RX_SENSE);
>>> -
>>> -   if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
>>> -   struct cec_notifier *notifier;
>>> -
>>> -   notifier = READ_ONCE(hdmi->cec_notifier);
>>> -   if (notifier)
>>> -   cec_notifier_phys_addr_invalidate(notifier);
>>> -   }
>>> }
>>>
>>> if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



Re: [PATCH] drm/bridge: dw-hdmi: move cec PA invalidation to dw_hdmi_setup_rx_sense()

2019-08-13 Thread Hans Verkuil
CC Dariusz as well, since this issue was discovered when testing his
CEC patches.

Regards,

Hans

On 8/13/19 11:32 AM, Hans Verkuil wrote:
> When testing CEC on the AML-S905X-CC board I noticed that the CEC physical
> address was not invalidated when the HDMI cable was unplugged. Some more
> digging showed that meson uses meson_dw_hdmi.c to handle the HPD.
> 
> Both dw_hdmi_irq() and dw_hdmi_top_thread_irq() (in meson_dw_hdmi.c) call
> the dw_hdmi_setup_rx_sense() function. So move the code to invalidate the
> CEC physical address to that function, so that it is independent of where
> the HPD interrupt happens.
> 
> Tested with both a AML-S905X-CC and a Khadas VIM2 board.
> 
> Signed-off-by: Hans Verkuil 
> ---
> Note: an alternative would be to make a new dw-hdmi function such as
> dw_hdmi_cec_phys_addr_invalidate() that is called from meson_dw_hdmi.c.
> I decided not to do that since this patch is minimally invasive, but
> that can obviously be changed if that approach is preferred.
> ---
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index c5a854af54f8..e899b31e1432 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2329,6 +2329,13 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool 
> hpd, bool rx_sense)
>   dw_hdmi_update_power(hdmi);
>   dw_hdmi_update_phy_mask(hdmi);
>   }
> + if (!hpd && !rx_sense) {
> + struct cec_notifier *notifier = READ_ONCE(hdmi->cec_notifier);
> +
> + if (notifier)
> + cec_notifier_phys_addr_invalidate(notifier);
> + }
> +
>   mutex_unlock(>mutex);
>  }
>  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
> @@ -2369,14 +2376,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>   dw_hdmi_setup_rx_sense(hdmi,
>  phy_stat & HDMI_PHY_HPD,
>  phy_stat & HDMI_PHY_RX_SENSE);
> -
> - if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
> - struct cec_notifier *notifier;
> -
> - notifier = READ_ONCE(hdmi->cec_notifier);
> - if (notifier)
> - cec_notifier_phys_addr_invalidate(notifier);
> - }
>   }
> 
>   if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> 



[PATCH] drm/bridge: dw-hdmi: move cec PA invalidation to dw_hdmi_setup_rx_sense()

2019-08-13 Thread Hans Verkuil
When testing CEC on the AML-S905X-CC board I noticed that the CEC physical
address was not invalidated when the HDMI cable was unplugged. Some more
digging showed that meson uses meson_dw_hdmi.c to handle the HPD.

Both dw_hdmi_irq() and dw_hdmi_top_thread_irq() (in meson_dw_hdmi.c) call
the dw_hdmi_setup_rx_sense() function. So move the code to invalidate the
CEC physical address to that function, so that it is independent of where
the HPD interrupt happens.

Tested with both a AML-S905X-CC and a Khadas VIM2 board.

Signed-off-by: Hans Verkuil 
---
Note: an alternative would be to make a new dw-hdmi function such as
dw_hdmi_cec_phys_addr_invalidate() that is called from meson_dw_hdmi.c.
I decided not to do that since this patch is minimally invasive, but
that can obviously be changed if that approach is preferred.
---
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index c5a854af54f8..e899b31e1432 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2329,6 +2329,13 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool 
hpd, bool rx_sense)
dw_hdmi_update_power(hdmi);
dw_hdmi_update_phy_mask(hdmi);
}
+   if (!hpd && !rx_sense) {
+   struct cec_notifier *notifier = READ_ONCE(hdmi->cec_notifier);
+
+   if (notifier)
+   cec_notifier_phys_addr_invalidate(notifier);
+   }
+
mutex_unlock(>mutex);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
@@ -2369,14 +2376,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
dw_hdmi_setup_rx_sense(hdmi,
   phy_stat & HDMI_PHY_HPD,
   phy_stat & HDMI_PHY_RX_SENSE);
-
-   if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
-   struct cec_notifier *notifier;
-
-   notifier = READ_ONCE(hdmi->cec_notifier);
-   if (notifier)
-   cec_notifier_phys_addr_invalidate(notifier);
-   }
}

if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {


Re: [PATCH v3 11/41] media/v4l2-core/mm: convert put_page() to put_user_page*()

2019-08-08 Thread Hans Verkuil
On 8/7/19 3:33 AM, john.hubb...@gmail.com wrote:
> From: John Hubbard 
> 
> For pages that were retained via get_user_pages*(), release those pages
> via the new put_user_page*() routines, instead of via put_page() or
> release_pages().
> 
> This is part a tree-wide conversion, as described in commit fc1d8e7cca2d
> ("mm: introduce put_user_page*(), placeholder versions").
> 
> Cc: Mauro Carvalho Chehab 
> Cc: Kees Cook 
> Cc: Hans Verkuil 
> Cc: Sakari Ailus 
> Cc: Jan Kara 
> Cc: Robin Murphy 
> Cc: Souptick Joarder 
> Cc: Dan Williams 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: John Hubbard 

Acked-by: Hans Verkuil 

> ---
>  drivers/media/v4l2-core/videobuf-dma-sg.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c 
> b/drivers/media/v4l2-core/videobuf-dma-sg.c
> index 66a6c6c236a7..d6eeb437ec19 100644
> --- a/drivers/media/v4l2-core/videobuf-dma-sg.c
> +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
> @@ -349,8 +349,7 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
>   BUG_ON(dma->sglen);
>  
>   if (dma->pages) {
> - for (i = 0; i < dma->nr_pages; i++)
> - put_page(dma->pages[i]);
> + put_user_pages(dma->pages, dma->nr_pages);
>   kfree(dma->pages);
>   dma->pages = NULL;
>   }
> 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 10/41] media/ivtv: convert put_page() to put_user_page*()

2019-08-08 Thread Hans Verkuil
On 8/7/19 3:33 AM, john.hubb...@gmail.com wrote:
> From: John Hubbard 
> 
> For pages that were retained via get_user_pages*(), release those pages
> via the new put_user_page*() routines, instead of via put_page() or
> release_pages().
> 
> This is part a tree-wide conversion, as described in commit fc1d8e7cca2d
> ("mm: introduce put_user_page*(), placeholder versions").
> 
> Cc: Andy Walls 
> Cc: Mauro Carvalho Chehab 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: John Hubbard 

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/media/pci/ivtv/ivtv-udma.c | 14 --
>  drivers/media/pci/ivtv/ivtv-yuv.c  | 11 +++
>  2 files changed, 7 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/media/pci/ivtv/ivtv-udma.c 
> b/drivers/media/pci/ivtv/ivtv-udma.c
> index 5f8883031c9c..7c7f33c2412b 100644
> --- a/drivers/media/pci/ivtv/ivtv-udma.c
> +++ b/drivers/media/pci/ivtv/ivtv-udma.c
> @@ -92,7 +92,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long 
> ivtv_dest_addr,
>  {
>   struct ivtv_dma_page_info user_dma;
>   struct ivtv_user_dma *dma = >udma;
> - int i, err;
> + int err;
>  
>   IVTV_DEBUG_DMA("ivtv_udma_setup, dst: 0x%08x\n", (unsigned 
> int)ivtv_dest_addr);
>  
> @@ -119,8 +119,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long 
> ivtv_dest_addr,
>   IVTV_DEBUG_WARN("failed to map user pages, returned %d instead 
> of %d\n",
>  err, user_dma.page_count);
>   if (err >= 0) {
> - for (i = 0; i < err; i++)
> - put_page(dma->map[i]);
> + put_user_pages(dma->map, err);
>   return -EINVAL;
>   }
>   return err;
> @@ -130,9 +129,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long 
> ivtv_dest_addr,
>  
>   /* Fill SG List with new values */
>   if (ivtv_udma_fill_sg_list(dma, _dma, 0) < 0) {
> - for (i = 0; i < dma->page_count; i++) {
> - put_page(dma->map[i]);
> - }
> + put_user_pages(dma->map, dma->page_count);
>   dma->page_count = 0;
>   return -ENOMEM;
>   }
> @@ -153,7 +150,6 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long 
> ivtv_dest_addr,
>  void ivtv_udma_unmap(struct ivtv *itv)
>  {
>   struct ivtv_user_dma *dma = >udma;
> - int i;
>  
>   IVTV_DEBUG_INFO("ivtv_unmap_user_dma\n");
>  
> @@ -170,9 +166,7 @@ void ivtv_udma_unmap(struct ivtv *itv)
>   ivtv_udma_sync_for_cpu(itv);
>  
>   /* Release User Pages */
> - for (i = 0; i < dma->page_count; i++) {
> - put_page(dma->map[i]);
> - }
> + put_user_pages(dma->map, dma->page_count);
>   dma->page_count = 0;
>  }
>  
> diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c 
> b/drivers/media/pci/ivtv/ivtv-yuv.c
> index cd2fe2d444c0..2c61a11d391d 100644
> --- a/drivers/media/pci/ivtv/ivtv-yuv.c
> +++ b/drivers/media/pci/ivtv/ivtv-yuv.c
> @@ -30,7 +30,6 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct 
> ivtv_user_dma *dma,
>   struct yuv_playback_info *yi = >yuv_info;
>   u8 frame = yi->draw_frame;
>   struct yuv_frame_info *f = >new_frame_info[frame];
> - int i;
>   int y_pages, uv_pages;
>   unsigned long y_buffer_offset, uv_buffer_offset;
>   int y_decode_height, uv_decode_height, y_size;
> @@ -81,8 +80,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct 
> ivtv_user_dma *dma,
>uv_pages, uv_dma.page_count);
>  
>   if (uv_pages >= 0) {
> - for (i = 0; i < uv_pages; i++)
> - put_page(dma->map[y_pages + i]);
> + put_user_pages(>map[y_pages], uv_pages);
>   rc = -EFAULT;
>   } else {
>   rc = uv_pages;
> @@ -93,8 +91,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct 
> ivtv_user_dma *dma,
>y_pages, y_dma.page_count);
>   }
>   if (y_pages >= 0) {
> - for (i = 0; i < y_pages; i++)
> - put_page(dma->map[i]);
> + put_user_pages(dma->map, y_pages);
>   /*
>* Inherit the -EFAULT from rc's
>* initialization, but allow it to be
> @@ -112,9 +109,7 @@ s

Re: next-20190806: arm64: adv7511 3-0039: failed to find dsi host

2019-08-07 Thread Hans Verkuil
Adding dri-devel since this appears to be drm specific and not media
related.

Regards,

Hans

On 8/7/19 10:17 AM, Naresh Kamboju wrote:
> arm64 devices dragonboard 410c (QC410E) and hi6220-hikey running Linux
> next-20190806 loading modules causing floods of kernel messages.
> 
> We have enabled few extra kernel configs for testing.
> CONFIG_DRM_I2C_ADV7511=m
> CONFIG_DRM_I2C_ADV7511_CEC=y
> ...
> 
> Please find below boot log and config file link.
> 
> [0.00] Linux version 5.3.0-rc3-next-20190806 (oe-user@oe-host)
> (gcc version 7.3.0 (GCC)) #1 SMP PREEMPT Tue Aug 6 05:49:36 UTC 2019
> [0.00] Machine model: Qualcomm Technologies, Inc. APQ 8016 SBC
> 
> [   10.051193] adv7511 3-0039: 3-0039 supply dvdd not found, using
> dummy regulator
> [   10.051633] adv7511 3-0039: 3-0039 supply pvdd not found, using
> dummy regulator
> [   10.076257] adreno 1c0.gpu: Adding to iommu group 0
> [   10.090929] adv7511 3-0039: 3-0039 supply a2vdd not found, using
> dummy regulator
> [   10.101703] msm_mdp 1a01000.mdp: Adding to iommu group 1
> [   10.102563] msm_mdp 1a01000.mdp: No interconnect support may cause
> display underflows!
> [   10.139492] adv7511 3-0039: failed to find dsi host
> ...
> [   33.065744] adv7511 3-0039: failed to find dsi host
> [   33.076721] msm 1a0.mdss: 1a0.mdss supply vdd not found,
> using dummy regulator
> [   33.078344] msm_mdp 1a01000.mdp: [drm:mdp5_bind [msm]] MDP5 version v1.6
> [   33.083862] msm 1a0.mdss: bound 1a01000.mdp (ops mdp5_ops [msm])
> [   33.090892] msm_dsi 1a98000.dsi: 1a98000.dsi supply gdsc not found,
> using dummy regulator
> [   33.097756] msm_dsi 1a98000.dsi: 1a98000.dsi supply gdsc not found,
> using dummy regulator
> [   33.106606] msm_dsi_manager_register: failed to register mipi dsi
> host for DSI 0
> [   33.114579] msm 1a0.mdss: failed to bind 1a98000.dsi (ops
> dsi_ops [msm]): -517
> [   33.121263] msm 1a0.mdss: master bind failed: -517
> [   33.135547] adv7511 3-0039: 3-0039 supply dvdd not found, using
> dummy regulator
> [   33.139360] adv7511 3-0039: 3-0039 supply pvdd not found, using
> dummy regulator
> [   33.143646] adv7511 3-0039: 3-0039 supply a2vdd not found, using
> dummy regulator
> 
> Full test log
> https://lkft.validation.linaro.org/scheduler/job/860208#L956
> 
> metadata:
>   git branch: master
>   git repo: 
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
>   git commit: 958eb4327c1761c609bde8e9f7c04e9d1c6fbb96
>   git describe: next-20190806
>   make_kernelversion: 5.3.0-rc3
>   kernel-config:
> http://snapshots.linaro.org/openembedded/lkft/lkft/sumo/dragonboard-410c/lkft/linux-next/579/config
>   kernel-defconfig:
> http://snapshots.linaro.org/openembedded/lkft/lkft/sumo/dragonboard-410c/lkft/linux-next/579/defconfig
>   build-location:
> http://snapshots.linaro.org/openembedded/lkft/lkft/sumo/dragonboard-410c/lkft/linux-next/579
> 
> Best regards
> Naresh Kamboju
> 



Re: [PATCH 2/9] v4l: Add definitions for missing 16-bit RGB4444 formats

2019-07-09 Thread Hans Verkuil
Hi Laurent,

On 3/28/19 8:07 AM, Laurent Pinchart wrote:
> The V4L2 API is missing the 16-bit RGB formats for the RGBA, RGBX,
> ABGR, XBGR, BGRA and BGRX component orders. Add them, using the same
> 4CCs as DRM.
> 
> Signed-off-by: Laurent Pinchart 
> ---
>  .../media/uapi/v4l/pixfmt-packed-rgb.rst  | 138 ++
>  include/uapi/linux/videodev2.h|   6 +
>  2 files changed, 144 insertions(+)
> 



> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 4e5222726719..df9fa78a6ab7 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -514,6 +514,12 @@ struct v4l2_pix_format {
>  #define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R', '4', '4', '4') /* 16   
>  */
>  #define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') /* 16   
>  */
>  #define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') /* 16   
>  */
> +#define V4L2_PIX_FMT_RGBA444 v4l2_fourcc('R', 'A', '1', '2') /* 16   
>  */
> +#define V4L2_PIX_FMT_RGBX444 v4l2_fourcc('R', 'X', '1', '2') /* 16   
>  */
> +#define V4L2_PIX_FMT_ABGR444 v4l2_fourcc('A', 'B', '1', '2') /* 16   
>  */
> +#define V4L2_PIX_FMT_XBGR444 v4l2_fourcc('X', 'B', '1', '2') /* 16   
>  */
> +#define V4L2_PIX_FMT_BGRA444 v4l2_fourcc('B', 'A', '1', '2') /* 16   
>  */

Hmm, 'BA12' clashes with V4L2_PIX_FMT_SGRBG12 which has the same fourcc.
That fourcc makes no sense for V4L2_PIX_FMT_SGRBG12 and I suspect it was
a mistake, but it's been in use since 2014.

I think V4L2_PIX_FMT_BGRA444 should get a different fourcc and be backported to 
5.2.

Can you address this issue?

Regards,

Hans

> +#define V4L2_PIX_FMT_BGRX444 v4l2_fourcc('B', 'X', '1', '2') /* 16   
>  */
>  #define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R', 'G', 'B', 'O') /* 16  
> RGB-5-5-5 */
>  #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') /* 16  
> ARGB-1-5-5-5  */
>  #define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5') /* 16  
> XRGB-1-5-5-5  */
> 



Re: [PATCHv9 04/13] cec: expose the new connector info API

2019-06-25 Thread Hans Verkuil
On 6/25/19 4:58 PM, Dariusz Marcinkiewicz wrote:
> Hi again.
> On Tue, Jun 25, 2019 at 4:45 PM Hans Verkuil  wrote:
>>
>> +   mutex_lock(>lock);
>> +   if (copy_to_user(parg, >conn_info, sizeof(adap->conn_info)))
>> +   ret = -EFAULT;
>> +   mutex_unlock(>lock);
>> +   return ret;
>> +}
> Shouldn't the lock be released before calling copy_to_user? I guess
> you need to make an extra copy of the conn_info, like it is done for
> other ioctls.

There is no reason for doing that, it would just use additional stack
space.

Regards,

Hans


[PATCHv9 05/13] cec: document CEC_ADAP_G_CONNECTOR_INFO and capability

2019-06-25 Thread Hans Verkuil
Document the new CEC_ADAP_G_CONNECTOR_INFO ioctl and the new
CEC_CAP_CONNECTOR_INFO capability.

Signed-off-by: Dariusz Marcinkiewicz 
Co-developed-by: Hans Verkuil 
[hverkuil-ci...@xs4all.nl: added CEC_CAP_CONNECTOR_INFO]
[hverkuil-ci...@xs4all.nl: added DQEVENT have_conn_info]
Signed-off-by: Hans Verkuil 
---
 Documentation/media/uapi/cec/cec-funcs.rst|   1 +
 .../media/uapi/cec/cec-ioc-adap-g-caps.rst|   6 +-
 .../uapi/cec/cec-ioc-adap-g-conn-info.rst | 102 ++
 .../media/uapi/cec/cec-ioc-dqevent.rst|   8 ++
 4 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst

diff --git a/Documentation/media/uapi/cec/cec-funcs.rst 
b/Documentation/media/uapi/cec/cec-funcs.rst
index 620590b168c9..dc6da9c639a8 100644
--- a/Documentation/media/uapi/cec/cec-funcs.rst
+++ b/Documentation/media/uapi/cec/cec-funcs.rst
@@ -24,6 +24,7 @@ Function Reference
 cec-ioc-adap-g-caps
 cec-ioc-adap-g-log-addrs
 cec-ioc-adap-g-phys-addr
+cec-ioc-adap-g-conn-info
 cec-ioc-dqevent
 cec-ioc-g-mode
 cec-ioc-receive
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst 
b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
index 0c44f31a9b59..76761a98c312 100644
--- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
+++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
@@ -135,8 +135,12 @@ returns the information to the application. The ioctl 
never fails.
   - The CEC hardware can monitor CEC pin changes from low to high voltage
 and vice versa. When in pin monitoring mode the application will
receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events.
+* .. _`CEC-CAP-CONNECTOR-INFO`:
 
-
+  - ``CEC_CAP_CONNECTOR_INFO``
+  - 0x0100
+  - If this capability is set, then :ref:`CEC_ADAP_G_CONNECTOR_INFO` can
+be used.
 
 Return Value
 
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst 
b/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
new file mode 100644
index ..74500cc896a9
--- /dev/null
+++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
@@ -0,0 +1,102 @@
+.. SPDX-License-Identifier: GPL-2.0
+..
+.. Copyright 2019 Google LLC
+..
+.. _CEC_ADAP_G_CONNECTOR_INFO:
+
+***
+ioctl CEC_ADAP_G_CONNECTOR_INFO
+***
+
+Name
+
+
+CEC_ADAP_G_CONNECTOR_INFO - Query HDMI connector information
+
+Synopsis
+
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_G_CONNECTOR_INFO, struct 
cec_connector_info *argp )
+:name: CEC_ADAP_G_CONNECTOR_INFO
+
+Arguments
+=
+
+``fd``
+File descriptor returned by :c:func:`open() `.
+
+``argp``
+
+
+Description
+===
+
+Using this ioctl an application can learn which HDMI connector this CEC
+device corresponds to. While calling this ioctl the application should
+provide pointer to a cec_connector_info struct which will be populated
+by the kernel with the info provided by the adapter's driver. This ioctl
+is only available if the ``CEC_CAP_CONNECTOR_INFO`` capability is set.
+
+.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}|
+
+.. c:type:: cec_connector_info
+
+.. flat-table:: struct cec_connector_info
+:header-rows:  0
+:stub-columns: 0
+:widths:   1 1 1 8
+
+* - __u32
+  - ``type``
+  - The type of connector this adapter is associated with.
+* - union
+  - ``(anonymous)``
+  -
+* -
+  - ``struct cec_drm_connector_info``
+  - drm
+  - :ref:`cec-drm-connector-info`
+
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. _connector-type:
+
+.. flat-table:: Connector types
+:header-rows:  0
+:stub-columns: 0
+:widths:   3 1 8
+
+* .. _`CEC-CONNECTOR-TYPE-NO-CONNECTOR`:
+
+  - ``CEC_CONNECTOR_TYPE_NO_CONNECTOR``
+  - 0
+  - No connector is associated with the adapter/the information is not 
provided by the driver.
+* .. _`CEC-CONNECTOR-TYPE-DRM`:
+
+  - ``CEC_CONNECTOR_TYPE_DRM``
+  - 1
+  - Indicates that a DRM connector is associated with this adapter. Info 
about the
+connector can be found in :ref:`cec-drm-connector-info`.
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. c:type:: cec_drm_connector_info
+
+.. _cec-drm-connector-info:
+
+.. flat-table:: struct cec_drm_connector_info
+:header-rows:  0
+:stub-columns: 0
+:widths:   3 1 8
+
+* .. _`CEC-DRM-CONNECTOR-TYPE-CARD-NO`:
+
+  - __u32
+  - ``card_no``
+  - DRM card number: the digit from a card's path, e.g. 0 in case of 
/dev/card0.
+* .. _`CEC-DRM-CONNECTOR-TYPE-CONNECTOR_ID`:
+
+  - __u32
+  - ``connector_id``
+  - DRM connector ID.
diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst 
b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
index 46a1c99a595e..5e21b1fbfc01 100644
--- a/Documentation/media/uapi

[PATCHv9 08/13] dw-hdmi-cec: use cec_notifier_cec_adap_(un)register

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_cec_adap_(un)register() functions to
(un)register the notifier for the CEC adapter.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
index 6c323510f128..6f7ecacb7d1f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -281,13 +281,14 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
 
-   cec->notify = cec_notifier_get(pdev->dev.parent);
+   cec->notify = cec_notifier_cec_adap_register(pdev->dev.parent,
+NULL, cec->adap);
if (!cec->notify)
return -ENOMEM;
 
ret = cec_register_adapter(cec->adap, pdev->dev.parent);
if (ret < 0) {
-   cec_notifier_put(cec->notify);
+   cec_notifier_cec_adap_unregister(cec->notify);
return ret;
}
 
@@ -297,8 +298,6 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)
 */
devm_remove_action(>dev, dw_hdmi_cec_del, cec);
 
-   cec_register_cec_notifier(cec->adap, cec->notify);
-
return 0;
 }
 
@@ -306,8 +305,8 @@ static int dw_hdmi_cec_remove(struct platform_device *pdev)
 {
struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
 
+   cec_notifier_cec_adap_unregister(cec->notify);
cec_unregister_adapter(cec->adap);
-   cec_notifier_put(cec->notify);
 
return 0;
 }
-- 
2.20.1



[PATCHv9 13/13] drm/vc4/vc4_hdmi: fill in connector info

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Fill in the connector info, allowing userspace to associate
the CEC device with the drm connector.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 99fc8569e0f5..a998bb35b375 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1279,6 +1279,9 @@ static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
 
 static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 {
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+   struct cec_connector_info conn_info;
+#endif
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = drm->dev_private;
@@ -1397,13 +1400,15 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 #ifdef CONFIG_DRM_VC4_HDMI_CEC
hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
  vc4, "vc4",
- CEC_CAP_TRANSMIT |
- CEC_CAP_LOG_ADDRS |
- CEC_CAP_PASSTHROUGH |
- CEC_CAP_RC, 1);
+ CEC_CAP_DEFAULTS |
+ CEC_CAP_CONNECTOR_INFO, 1);
ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
if (ret < 0)
goto err_destroy_conn;
+
+   cec_fill_conn_info_from_drm(_info, hdmi->connector);
+   cec_s_conn_info(hdmi->cec_adap, _info);
+
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0x);
value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
-- 
2.20.1



[PATCHv9 09/13] dw-hdmi: use cec_notifier_conn_(un)register

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector, and fill in
the cec_connector_info.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 --
 1 file changed, 58 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 045b1b13fd0e..fc4d3b5f71d0 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -133,6 +133,8 @@ struct dw_hdmi {
struct drm_connector connector;
struct drm_bridge bridge;
 
+   int irq;
+
unsigned int version;
 
struct platform_device *audio;
@@ -184,6 +186,7 @@ struct dw_hdmi {
void (*enable_audio)(struct dw_hdmi *hdmi);
void (*disable_audio)(struct dw_hdmi *hdmi);
 
+   bool cec_configured;
struct cec_notifier *cec_notifier;
 };
 
@@ -2108,11 +2111,35 @@ static const struct drm_connector_helper_funcs 
dw_hdmi_connector_helper_funcs =
.get_modes = dw_hdmi_connector_get_modes,
 };
 
+static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
+{
+   mutex_lock(>mutex);
+   hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
+   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+   mutex_unlock(>mutex);
+}
+
+static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
+{
+   mutex_lock(>mutex);
+   hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
+   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+   mutex_unlock(>mutex);
+}
+
+static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
+   .write = hdmi_writeb,
+   .read = hdmi_readb,
+   .enable = dw_hdmi_cec_enable,
+   .disable = dw_hdmi_cec_disable,
+};
+
 static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
 {
struct dw_hdmi *hdmi = bridge->driver_private;
struct drm_encoder *encoder = bridge->encoder;
struct drm_connector *connector = >connector;
+   struct cec_connector_info conn_info;
 
connector->interlace_allowed = 1;
connector->polled = DRM_CONNECTOR_POLL_HPD;
@@ -2124,6 +2151,33 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
*bridge)
 
drm_connector_attach_encoder(connector, encoder);
 
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   hdmi->cec_notifier = cec_notifier_conn_register(hdmi->dev, NULL,
+   _info);
+   if (!hdmi->cec_notifier)
+   return -ENOMEM;
+
+   if (hdmi->cec_configured) {
+   struct platform_device_info pdevinfo;
+   struct dw_hdmi_cec_data cec;
+
+   memset(, 0, sizeof(pdevinfo));
+   pdevinfo.parent = hdmi->dev;
+   pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+   cec.hdmi = hdmi;
+   cec.ops = _hdmi_cec_ops;
+   cec.irq = hdmi->irq;
+
+   pdevinfo.name = "dw-hdmi-cec";
+   pdevinfo.data = 
+   pdevinfo.size_data = sizeof(cec);
+   pdevinfo.dma_mask = 0;
+
+   hdmi->cec = platform_device_register_full();
+   }
+
return 0;
 }
 
@@ -2393,29 +2447,6 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
return -ENODEV;
 }
 
-static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
-{
-   mutex_lock(>mutex);
-   hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
-   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
-   mutex_unlock(>mutex);
-}
-
-static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
-{
-   mutex_lock(>mutex);
-   hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
-   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
-   mutex_unlock(>mutex);
-}
-
-static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
-   .write = hdmi_writeb,
-   .read = hdmi_readb,
-   .enable = dw_hdmi_cec_enable,
-   .disable = dw_hdmi_cec_disable,
-};
-
 static const struct regmap_config hdmi_regmap_8bit_config = {
.reg_bits   = 32,
.val_bits   = 8,
@@ -2438,7 +2469,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
struct device_node *np = dev->of_node;
struct platform_device_info pdevinfo;
struct device_node *ddc_node;
-   struct dw_hdmi_cec_data cec;
struct dw_hdmi *hdmi;
struct resource *iores = NULL;
int irq;
@@ -2588,6 +2618,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
ret = irq;
goto err_iahb;
}
+   hdmi->irq = irq;
 
ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
dw_hdmi_irq, IRQF_SHARED,
@@ -2595,12 +2626,6 @@ __dw_hdmi_probe(struct platform_devic

[PATCHv9 04/13] cec: expose the new connector info API

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Until now the connector info API was a kernel-internal API only.
This moves it to the public API and adds the new ioctl to retrieve
this information.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-adap.c |  2 ++
 drivers/media/cec/cec-api.c  | 20 ++
 drivers/media/cec/cec-core.c |  5 -
 include/media/cec.h  | 31 
 include/uapi/linux/cec.h | 40 
 5 files changed, 62 insertions(+), 36 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 451c61bde4d4..059c83525024 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -319,6 +319,8 @@ static void cec_post_state_event(struct cec_adapter *adap)
 
ev.state_change.phys_addr = adap->phys_addr;
ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+   ev.state_change.have_conn_info =
+   adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
cec_queue_event(adap, );
 }
 
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 12d676484472..17d1cb2e5f97 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -187,6 +187,21 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, 
struct cec_fh *fh,
return 0;
 }
 
+static long cec_adap_g_connector_info(struct cec_adapter *adap,
+ struct cec_log_addrs __user *parg)
+{
+   int ret = 0;
+
+   if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
+   return -ENOTTY;
+
+   mutex_lock(>lock);
+   if (copy_to_user(parg, >conn_info, sizeof(adap->conn_info)))
+   ret = -EFAULT;
+   mutex_unlock(>lock);
+   return ret;
+}
+
 static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
 bool block, struct cec_msg __user *parg)
 {
@@ -506,6 +521,9 @@ static long cec_ioctl(struct file *filp, unsigned int cmd, 
unsigned long arg)
case CEC_ADAP_S_LOG_ADDRS:
return cec_adap_s_log_addrs(adap, fh, block, parg);
 
+   case CEC_ADAP_G_CONNECTOR_INFO:
+   return cec_adap_g_connector_info(adap, parg);
+
case CEC_TRANSMIT:
return cec_transmit(adap, fh, block, parg);
 
@@ -578,6 +596,8 @@ static int cec_open(struct inode *inode, struct file *filp)
/* Queue up initial state events */
ev.state_change.phys_addr = adap->phys_addr;
ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+   ev.state_change.have_conn_info =
+   adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
cec_queue_event_fh(fh, , 0);
 #ifdef CONFIG_CEC_PIN
if (adap->pin && adap->pin->ops->read_hpd) {
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index 9c610e1e99b8..db7adffcdc76 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -257,11 +257,6 @@ struct cec_adapter *cec_allocate_adapter(const struct 
cec_adap_ops *ops,
struct cec_adapter *adap;
int res;
 
-   /*
-* Disable this capability until the connector info public API
-* is ready.
-*/
-   caps &= ~CEC_CAP_CONNECTOR_INFO;
 #ifndef CONFIG_MEDIA_CEC_RC
caps &= ~CEC_CAP_RC;
 #endif
diff --git a/include/media/cec.h b/include/media/cec.h
index 4d59387bc61b..0a4f69cc9dd4 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -18,9 +18,6 @@
 #include 
 #include 
 
-/* CEC_ADAP_G_CONNECTOR_INFO is available */
-#define CEC_CAP_CONNECTOR_INFO (1 << 8)
-
 #define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
  CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
 
@@ -147,34 +144,6 @@ struct cec_adap_ops {
  */
 #define CEC_MAX_MSG_TX_QUEUE_SZ(18 * 1)
 
-/**
- * struct cec_drm_connector_info - tells which drm connector is
- * associated with the CEC adapter.
- * @card_no: drm card number
- * @connector_id: drm connector ID
- */
-struct cec_drm_connector_info {
-   __u32 card_no;
-   __u32 connector_id;
-};
-
-#define CEC_CONNECTOR_TYPE_NO_CONNECTOR0
-#define CEC_CONNECTOR_TYPE_DRM 1
-
-/**
- * struct cec_connector_info - tells if and which connector is
- * associated with the CEC adapter.
- * @type: connector type (if any)
- * @drm: drm connector info
- */
-struct cec_connector_info {
-   __u32 type;
-   union {
-   struct cec_drm_connector_info drm;
-   __u32 raw[16];
-   };
-};
-
 struct cec_adapter {
struct module *owner;
char name[32];
diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
index 5704fa0292b5..0115c5aa0d36 100644
--- a/include/uapi/linux/cec.h
+++ b/include/uapi/linux/cec.h
@@ -317,6 +317,8 @@ static inline int cec_is_un

[PATCHv9 03/13] cec-notifier: add new notifier functions

2019-06-25 Thread Hans Verkuil
In order to support multiple CEC devices for an HDMI connector,
and to support cec_connector_info, drivers should use either a
cec_notifier_conn_(un)register pair of functions (HDMI drivers)
or a cec_notifier_cec_adap_(un)register pair (CEC adapter drivers).

This replaces cec_notifier_get_conn/cec_notifier_put.

For CEC adapters it is also no longer needed to call cec_notifier_register,
cec_register_cec_notifier and cec_notifier_unregister. This is now
all handled internally by the new functions.

The 'called_cec_notifier_register' bool is needed to handle the case where
a CEC adapter driver calls the old cec_notifier_register() function
instead of cec_notifier_cec_adap_unregister().

Once those old functions are removed in the future, that bool can also
be removed.

Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-notifier.c | 85 
 include/media/cec-notifier.h | 78 +
 2 files changed, 163 insertions(+)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index f72b19c351dd..52a867bde15f 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -22,6 +22,7 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *hdmi_dev;
+   struct cec_connector_info conn_info;
const char *conn_name;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
@@ -88,6 +89,84 @@ void cec_notifier_put(struct cec_notifier *n)
 }
 EXPORT_SYMBOL_GPL(cec_notifier_put);
 
+struct cec_notifier *
+cec_notifier_conn_register(struct device *hdmi_dev, const char *conn_name,
+  const struct cec_connector_info *conn_info)
+{
+   struct cec_notifier *n = cec_notifier_get_conn(hdmi_dev, conn_name);
+
+   if (!n)
+   return n;
+
+   mutex_lock(>lock);
+   n->phys_addr = CEC_PHYS_ADDR_INVALID;
+   if (conn_info)
+   n->conn_info = *conn_info;
+   else
+   memset(>conn_info, 0, sizeof(n->conn_info));
+   if (n->cec_adap) {
+   cec_phys_addr_invalidate(n->cec_adap);
+   cec_s_conn_info(n->cec_adap, conn_info);
+   }
+   mutex_unlock(>lock);
+   return n;
+}
+EXPORT_SYMBOL_GPL(cec_notifier_conn_register);
+
+void cec_notifier_conn_unregister(struct cec_notifier *n)
+{
+   if (!n)
+   return;
+
+   mutex_lock(>lock);
+   memset(>conn_info, 0, sizeof(n->conn_info));
+   n->phys_addr = CEC_PHYS_ADDR_INVALID;
+   if (n->cec_adap) {
+   cec_phys_addr_invalidate(n->cec_adap);
+   cec_s_conn_info(n->cec_adap, NULL);
+   }
+   mutex_unlock(>lock);
+   cec_notifier_put(n);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_conn_unregister);
+
+struct cec_notifier *
+cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *conn_name,
+  struct cec_adapter *adap)
+{
+   struct cec_notifier *n;
+
+   if (WARN_ON(!adap))
+   return NULL;
+
+   n = cec_notifier_get_conn(hdmi_dev, conn_name);
+   if (!n)
+   return n;
+
+   mutex_lock(>lock);
+   n->cec_adap = adap;
+   adap->conn_info = n->conn_info;
+   adap->notifier = n;
+   cec_s_phys_addr(adap, n->phys_addr, false);
+   mutex_unlock(>lock);
+   return n;
+}
+EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_register);
+
+void cec_notifier_cec_adap_unregister(struct cec_notifier *n)
+{
+   if (!n)
+   return;
+
+   mutex_lock(>lock);
+   n->cec_adap->notifier = NULL;
+   n->cec_adap = NULL;
+   n->callback = NULL;
+   mutex_unlock(>lock);
+   cec_notifier_put(n);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_unregister);
+
 void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
 {
if (n == NULL)
@@ -97,6 +176,8 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 
pa)
n->phys_addr = pa;
if (n->callback)
n->callback(n->cec_adap, n->phys_addr);
+   else if (n->cec_adap)
+   cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
mutex_unlock(>lock);
 }
 EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
@@ -131,6 +212,10 @@ EXPORT_SYMBOL_GPL(cec_notifier_register);
 
 void cec_notifier_unregister(struct cec_notifier *n)
 {
+   /* Do nothing unless cec_notifier_register was called first */
+   if (!n->callback)
+   return;
+
mutex_lock(>lock);
n->callback = NULL;
mutex_unlock(>lock);
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index 0e3bd3415724..e8a677c90f6f 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -42,6 +42,60 @@ struct cec_notifier *cec_notifier_get_conn(struc

[PATCHv9 02/13] cec: add struct cec_connector_info support

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Define struct cec_connector_info in media/cec.h and define
CEC_CAP_CONNECTOR_INFO. In a later patch this will be moved to
uapi/linux/cec.h.

Due to these changes the seco-cec driver was changed as well: it
should include cec-notifier.h, not cec.h.

The CEC_CAP_CONNECTOR_INFO capability can be set by drivers, but
cec_allocate_adapter() will remove it again until the public API
for this can be enabled once all drm drivers wire this up correctly.

Also add the cec_fill_conn_info_from_drm and cec_s_conn_info functions,
which are needed by drm drivers to fill in the cec_connector info
based on a drm_connector.

Signed-off-by: Dariusz Marcinkiewicz 
Co-developed-by: Hans Verkuil 
Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-adap.c   | 29 +++
 drivers/media/cec/cec-core.c   |  5 ++
 drivers/media/platform/seco-cec/seco-cec.c |  2 +-
 include/media/cec-notifier.h   | 39 -
 include/media/cec.h| 98 +-
 5 files changed, 132 insertions(+), 41 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index ac3683a7b2ab..451c61bde4d4 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -16,7 +16,10 @@
 #include 
 #include 
 
+#include 
+#include 
 #include 
+#include 
 
 #include "cec-priv.h"
 
@@ -75,6 +78,16 @@ u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
 }
 EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
 
+void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
+const struct drm_connector *connector)
+{
+   memset(conn_info, 0, sizeof(*conn_info));
+   conn_info->type = CEC_CONNECTOR_TYPE_DRM;
+   conn_info->drm.card_no = connector->dev->primary->index;
+   conn_info->drm.connector_id = connector->base.id;
+}
+EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm);
+
 /*
  * Queue a new event for this filehandle. If ts == 0, then set it
  * to the current time.
@@ -1598,6 +1611,22 @@ void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
 }
 EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
 
+void cec_s_conn_info(struct cec_adapter *adap,
+const struct cec_connector_info *conn_info)
+{
+   if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
+   return;
+
+   mutex_lock(>lock);
+   if (conn_info)
+   adap->conn_info = *conn_info;
+   else
+   memset(>conn_info, 0, sizeof(adap->conn_info));
+   cec_post_state_event(adap);
+   mutex_unlock(>lock);
+}
+EXPORT_SYMBOL_GPL(cec_s_conn_info);
+
 /*
  * Called from either the ioctl or a driver to set the logical addresses.
  *
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index db7adffcdc76..9c610e1e99b8 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -257,6 +257,11 @@ struct cec_adapter *cec_allocate_adapter(const struct 
cec_adap_ops *ops,
struct cec_adapter *adap;
int res;
 
+   /*
+* Disable this capability until the connector info public API
+* is ready.
+*/
+   caps &= ~CEC_CAP_CONNECTOR_INFO;
 #ifndef CONFIG_MEDIA_CEC_RC
caps &= ~CEC_CAP_RC;
 #endif
diff --git a/drivers/media/platform/seco-cec/seco-cec.c 
b/drivers/media/platform/seco-cec/seco-cec.c
index e5080d6f5b2d..1d0133f01e00 100644
--- a/drivers/media/platform/seco-cec/seco-cec.c
+++ b/drivers/media/platform/seco-cec/seco-cec.c
@@ -18,7 +18,7 @@
 #include 
 
 /* CEC Framework */
-#include 
+#include 
 
 #include "seco-cec.h"
 
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index 57b3a9f6ea1d..0e3bd3415724 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -63,30 +63,6 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 
pa);
 void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
  const struct edid *edid);
 
-/**
- * cec_notifier_register - register a callback with the notifier
- * @n: the CEC notifier
- * @adap: the CEC adapter, passed as argument to the callback function
- * @callback: the callback function
- */
-void cec_notifier_register(struct cec_notifier *n,
-  struct cec_adapter *adap,
-  void (*callback)(struct cec_adapter *adap, u16 pa));
-
-/**
- * cec_notifier_unregister - unregister the callback from the notifier.
- * @n: the CEC notifier
- */
-void cec_notifier_unregister(struct cec_notifier *n);
-
-/**
- * cec_register_cec_notifier - register the notifier with the cec adapter.
- * @adap: the CEC adapter
- * @notifier: the CEC notifier
- */
-void cec_register_cec_notifier(struct cec_adapter *adap,
-  struct cec_notifier *notifier);
-
 /**
  * cec_notifier_parse_hdmi_phandle - find the hdmi

[PATCHv9 07/13] drm/i915/intel_hdmi: use cec_notifier_conn_(un)register

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector, and fill in
the cec_connector_info.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i915/intel_hdmi.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 34be2cfd0ec8..05a5ccc1517e 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2670,8 +2670,9 @@ intel_hdmi_connector_register(struct drm_connector 
*connector)
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
-   if (intel_attached_hdmi(connector)->cec_notifier)
-   cec_notifier_put(intel_attached_hdmi(connector)->cec_notifier);
+   struct cec_notifier *n = intel_attached_hdmi(connector)->cec_notifier;
+
+   cec_notifier_conn_unregister(n);
 
intel_connector_destroy(connector);
 }
@@ -2968,6 +2969,7 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
enum port port = intel_encoder->port;
+   struct cec_connector_info conn_info;
 
DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
  port_name(port));
@@ -3020,8 +3022,11 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
 
-   intel_hdmi->cec_notifier = cec_notifier_get_conn(dev->dev,
-port_identifier(port));
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   intel_hdmi->cec_notifier =
+   cec_notifier_conn_register(dev->dev, port_identifier(port),
+  _info);
if (!intel_hdmi->cec_notifier)
DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
-- 
2.20.1



[PATCHv9 06/13] drm_dp_cec: add connector info support.

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Pass the connector info to the CEC adapter. This makes it possible
to associate the CEC adapter with the corresponding drm connector.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  2 +-
 drivers/gpu/drm/drm_dp_cec.c  | 25 ---
 drivers/gpu/drm/i915/intel_dp.c   |  4 +--
 drivers/gpu/drm/nouveau/nouveau_connector.c   |  3 +--
 include/drm/drm_dp_helper.h   | 14 +--
 5 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 6e205ee36ac3..7f2eb4eb1035 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -394,7 +394,7 @@ void amdgpu_dm_initialize_dp_connector(struct 
amdgpu_display_manager *dm,
 
drm_dp_aux_register(>dm_dp_aux.aux);
drm_dp_cec_register_connector(>dm_dp_aux.aux,
- aconnector->base.name, dm->adev->dev);
+ >base);
aconnector->mst_mgr.cbs = _mst_cbs;
drm_dp_mst_topology_mgr_init(
>mst_mgr,
diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
index b15cee85b702..b457c16c3a8b 100644
--- a/drivers/gpu/drm/drm_dp_cec.c
+++ b/drivers/gpu/drm/drm_dp_cec.c
@@ -8,7 +8,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 /*
@@ -295,7 +297,10 @@ static void drm_dp_cec_unregister_work(struct work_struct 
*work)
  */
 void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
 {
-   u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
+   struct drm_connector *connector = aux->cec.connector;
+   u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
+  CEC_CAP_CONNECTOR_INFO;
+   struct cec_connector_info conn_info;
unsigned int num_las = 1;
u8 cap;
 
@@ -344,13 +349,17 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
struct edid *edid)
 
/* Create a new adapter */
aux->cec.adap = cec_allocate_adapter(_dp_cec_adap_ops,
-aux, aux->cec.name, cec_caps,
+aux, connector->name, cec_caps,
 num_las);
if (IS_ERR(aux->cec.adap)) {
aux->cec.adap = NULL;
goto unlock;
}
-   if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
+
+   cec_fill_conn_info_from_drm(_info, connector);
+   cec_s_conn_info(aux->cec.adap, _info);
+
+   if (cec_register_adapter(aux->cec.adap, connector->dev->dev)) {
cec_delete_adapter(aux->cec.adap);
aux->cec.adap = NULL;
} else {
@@ -406,22 +415,20 @@ EXPORT_SYMBOL(drm_dp_cec_unset_edid);
 /**
  * drm_dp_cec_register_connector() - register a new connector
  * @aux: DisplayPort AUX channel
- * @name: name of the CEC device
- * @parent: parent device
+ * @connector: drm connector
  *
  * A new connector was registered with associated CEC adapter name and
  * CEC adapter parent device. After registering the name and parent
  * drm_dp_cec_set_edid() is called to check if the connector supports
  * CEC and to register a CEC adapter if that is the case.
  */
-void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
-  struct device *parent)
+void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
+  struct drm_connector *connector)
 {
WARN_ON(aux->cec.adap);
if (WARN_ON(!aux->transfer))
return;
-   aux->cec.name = name;
-   aux->cec.parent = parent;
+   aux->cec.connector = connector;
INIT_DELAYED_WORK(>cec.unregister_work,
  drm_dp_cec_unregister_work);
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 560274d1c50b..1dfd16848e03 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5518,7 +5518,6 @@ static int
 intel_dp_connector_register(struct drm_connector *connector)
 {
struct intel_dp *intel_dp = intel_attached_dp(connector);
-   struct drm_device *dev = connector->dev;
int ret;
 
ret = intel_connector_register(connector);
@@ -5533,8 +5532,7 @@ intel_dp_connector_register(struct drm_connector 
*connector)
intel_dp->aux.dev = connector->kdev;
ret = drm_dp_aux_register(_dp->aux);
if (!ret)
-   drm_dp_cec_register_connector(_dp->aux,
- connector->name, dev->dev);
+   

[PATCHv9 11/13] tda9950: use cec_notifier_cec_adap_(un)register

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_cec_adap_(un)register() functions to
(un)register the notifier for the CEC adapter.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda9950.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda9950.c b/drivers/gpu/drm/i2c/tda9950.c
index 250b5e02a314..2f3381f0b2bf 100644
--- a/drivers/gpu/drm/i2c/tda9950.c
+++ b/drivers/gpu/drm/i2c/tda9950.c
@@ -423,7 +423,7 @@ static int tda9950_probe(struct i2c_client *client,
priv->hdmi = glue->parent;
 
priv->adap = cec_allocate_adapter(_cec_ops, priv, "tda9950",
- CEC_CAP_DEFAULTS,
+ CEC_CAP_DEFAULTS | 
CEC_CAP_CONNECTOR_INFO,
  CEC_MAX_LOG_ADDRS);
if (IS_ERR(priv->adap))
return PTR_ERR(priv->adap);
@@ -460,13 +460,14 @@ static int tda9950_probe(struct i2c_client *client,
if (ret < 0)
return ret;
 
-   priv->notify = cec_notifier_get(priv->hdmi);
+   priv->notify = cec_notifier_cec_adap_register(priv->hdmi, NULL,
+ priv->adap);
if (!priv->notify)
return -ENOMEM;
 
ret = cec_register_adapter(priv->adap, priv->hdmi);
if (ret < 0) {
-   cec_notifier_put(priv->notify);
+   cec_notifier_cec_adap_unregister(priv->notify);
return ret;
}
 
@@ -476,8 +477,6 @@ static int tda9950_probe(struct i2c_client *client,
 */
devm_remove_action(dev, tda9950_cec_del, priv);
 
-   cec_register_cec_notifier(priv->adap, priv->notify);
-
return 0;
 }
 
@@ -485,8 +484,8 @@ static int tda9950_remove(struct i2c_client *client)
 {
struct tda9950_priv *priv = i2c_get_clientdata(client);
 
+   cec_notifier_cec_adap_unregister(priv->notify);
cec_unregister_adapter(priv->adap);
-   cec_notifier_put(priv->notify);
 
return 0;
 }
-- 
2.20.1



[PATCHv9 10/13] meson/ao-cec: use cec_notifier_cec_adap_(un)register

2019-06-25 Thread Hans Verkuil
Use the new cec_notifier_cec_adap_(un)register() functions to
(un)register the notifier for the CEC adapter.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/meson/ao-cec.c | 37 +--
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/meson/ao-cec.c 
b/drivers/media/platform/meson/ao-cec.c
index facf9b029e79..b80eb8f9b422 100644
--- a/drivers/media/platform/meson/ao-cec.c
+++ b/drivers/media/platform/meson/ao-cec.c
@@ -616,20 +616,22 @@ static int meson_ao_cec_probe(struct platform_device 
*pdev)
 
spin_lock_init(_cec->cec_reg_lock);
 
-   ao_cec->notify = cec_notifier_get(hdmi_dev);
-   if (!ao_cec->notify)
-   return -ENOMEM;
-
ao_cec->adap = cec_allocate_adapter(_ao_cec_ops, ao_cec,
"meson_ao_cec",
CEC_CAP_LOG_ADDRS |
CEC_CAP_TRANSMIT |
CEC_CAP_RC |
-   CEC_CAP_PASSTHROUGH,
+   CEC_CAP_PASSTHROUGH |
+   CEC_CAP_CONNECTOR_INFO,
1); /* Use 1 for now */
-   if (IS_ERR(ao_cec->adap)) {
-   ret = PTR_ERR(ao_cec->adap);
-   goto out_probe_notify;
+   if (IS_ERR(ao_cec->adap))
+   return PTR_ERR(ao_cec->adap);
+
+   ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+   ao_cec->adap);
+   if (!ao_cec->notify) {
+   ret = -ENOMEM;
+   goto out_probe_adapter;
}
 
ao_cec->adap->owner = THIS_MODULE;
@@ -638,7 +640,7 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
ao_cec->base = devm_ioremap_resource(>dev, res);
if (IS_ERR(ao_cec->base)) {
ret = PTR_ERR(ao_cec->base);
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
irq = platform_get_irq(pdev, 0);
@@ -648,20 +650,20 @@ static int meson_ao_cec_probe(struct platform_device 
*pdev)
0, NULL, ao_cec);
if (ret) {
dev_err(>dev, "irq request failed\n");
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
ao_cec->core = devm_clk_get(>dev, "core");
if (IS_ERR(ao_cec->core)) {
dev_err(>dev, "core clock request failed\n");
ret = PTR_ERR(ao_cec->core);
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
ret = clk_prepare_enable(ao_cec->core);
if (ret) {
dev_err(>dev, "core clock enable failed\n");
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE);
@@ -685,19 +687,17 @@ static int meson_ao_cec_probe(struct platform_device 
*pdev)
writel_relaxed(CEC_GEN_CNTL_RESET,
   ao_cec->base + CEC_GEN_CNTL_REG);
 
-   cec_register_cec_notifier(ao_cec->adap, ao_cec->notify);
-
return 0;
 
 out_probe_clk:
clk_disable_unprepare(ao_cec->core);
 
+out_probe_notify:
+   cec_notifier_cec_adap_unregister(ao_cec->notify);
+
 out_probe_adapter:
cec_delete_adapter(ao_cec->adap);
 
-out_probe_notify:
-   cec_notifier_put(ao_cec->notify);
-
dev_err(>dev, "CEC controller registration failed\n");
 
return ret;
@@ -709,10 +709,9 @@ static int meson_ao_cec_remove(struct platform_device 
*pdev)
 
clk_disable_unprepare(ao_cec->core);
 
+   cec_notifier_cec_adap_unregister(ao_cec->notify);
cec_unregister_adapter(ao_cec->adap);
 
-   cec_notifier_put(ao_cec->notify);
-
return 0;
 }
 
-- 
2.20.1



[PATCHv9 12/13] tda998x: use cec_notifier_conn_(un)register

2019-06-25 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector, and fill in
the cec_connector_info.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 56 +++
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 7f34601bb515..019e1f2f008c 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1253,6 +1253,8 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
  struct drm_device *drm)
 {
struct drm_connector *connector = >connector;
+   struct cec_connector_info conn_info;
+   struct i2c_board_info cec_info;
int ret;
 
connector->interlace_allowed = 1;
@@ -1269,6 +1271,31 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
if (ret)
return ret;
 
+   /*
+* Some TDA998x are actually two I2C devices merged onto one piece
+* of silicon: TDA9989 and TDA19989 combine the HDMI transmitter
+* with a slightly modified TDA9950 CEC device.  The CEC device
+* is at the TDA9950 address, with the address pins strapped across
+* to the TDA998x address pins.  Hence, it always has the same
+* offset.
+*/
+   memset(_info, 0, sizeof(cec_info));
+   strlcpy(cec_info.type, "tda9950", sizeof(cec_info.type));
+   cec_info.addr = priv->cec_addr;
+   cec_info.platform_data = >cec_glue;
+   cec_info.irq = priv->hdmi->irq;
+
+   priv->cec = i2c_new_device(priv->hdmi->adapter, _info);
+   if (!priv->cec)
+   return -ENODEV;
+
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   priv->cec_notify = cec_notifier_conn_register(priv->cec_glue.parent,
+ NULL, _info);
+   if (!priv->cec_notify)
+   return -ENOMEM;
+
drm_connector_attach_encoder(>connector,
 priv->bridge.encoder);
 
@@ -1651,14 +1678,13 @@ static void tda998x_destroy(struct device *dev)
i2c_unregister_device(priv->cec);
 
if (priv->cec_notify)
-   cec_notifier_put(priv->cec_notify);
+   cec_notifier_conn_unregister(priv->cec_notify);
 }
 
 static int tda998x_create(struct device *dev)
 {
struct i2c_client *client = to_i2c_client(dev);
struct device_node *np = client->dev.of_node;
-   struct i2c_board_info cec_info;
struct tda998x_priv *priv;
u32 video;
int rev_lo, rev_hi, ret;
@@ -1776,12 +1802,6 @@ static int tda998x_create(struct device *dev)
cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
}
 
-   priv->cec_notify = cec_notifier_get(dev);
-   if (!priv->cec_notify) {
-   ret = -ENOMEM;
-   goto fail;
-   }
-
priv->cec_glue.parent = dev;
priv->cec_glue.data = priv;
priv->cec_glue.init = tda998x_cec_hook_init;
@@ -1789,26 +1809,6 @@ static int tda998x_create(struct device *dev)
priv->cec_glue.open = tda998x_cec_hook_open;
priv->cec_glue.release = tda998x_cec_hook_release;
 
-   /*
-* Some TDA998x are actually two I2C devices merged onto one piece
-* of silicon: TDA9989 and TDA19989 combine the HDMI transmitter
-* with a slightly modified TDA9950 CEC device.  The CEC device
-* is at the TDA9950 address, with the address pins strapped across
-* to the TDA998x address pins.  Hence, it always has the same
-* offset.
-*/
-   memset(_info, 0, sizeof(cec_info));
-   strlcpy(cec_info.type, "tda9950", sizeof(cec_info.type));
-   cec_info.addr = priv->cec_addr;
-   cec_info.platform_data = >cec_glue;
-   cec_info.irq = client->irq;
-
-   priv->cec = i2c_new_device(client->adapter, _info);
-   if (!priv->cec) {
-   ret = -ENODEV;
-   goto fail;
-   }
-
/* enable EDID read irq: */
reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
 
-- 
2.20.1



[PATCHv9 01/13] cec-notifier: rename variables, check kstrdup and n->conn_name

2019-06-25 Thread Hans Verkuil
dev -> hdmi_dev
conn -> conn_name

Check if n->conn_name is not NULL before calling strcmp.
Check the result of kstrdup, and clean up on error.

Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-notifier.c | 27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 9598c7778871..f72b19c351dd 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,8 +21,8 @@ struct cec_notifier {
struct mutex lock;
struct list_head head;
struct kref kref;
-   struct device *dev;
-   const char *conn;
+   struct device *hdmi_dev;
+   const char *conn_name;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -32,14 +32,16 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
+struct cec_notifier *
+cec_notifier_get_conn(struct device *hdmi_dev, const char *conn_name)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev &&
-   (!conn || !strcmp(n->conn, conn))) {
+   if (n->hdmi_dev == hdmi_dev &&
+   (!conn_name ||
+(n->conn_name && !strcmp(n->conn_name, conn_name {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -48,10 +50,17 @@ struct cec_notifier *cec_notifier_get_conn(struct device 
*dev, const char *conn)
n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n)
goto unlock;
-   n->dev = dev;
-   if (conn)
-   n->conn = kstrdup(conn, GFP_KERNEL);
+   n->hdmi_dev = hdmi_dev;
+   if (conn_name) {
+   n->conn_name = kstrdup(conn_name, GFP_KERNEL);
+   if (!n->conn_name) {
+   kfree(n);
+   n = NULL;
+   goto unlock;
+   }
+   }
n->phys_addr = CEC_PHYS_ADDR_INVALID;
+
mutex_init(>lock);
kref_init(>kref);
list_add_tail(>head, _notifiers);
@@ -67,7 +76,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
-   kfree(n->conn);
+   kfree(n->conn_name);
kfree(n);
 }
 
-- 
2.20.1



[PATCHv9 00/13] cec: improve notifier support, add connector info

2019-06-25 Thread Hans Verkuil
This is a rework of Dariusz' v7 series:

https://www.spinics.net/lists/linux-media/msg151117.html

Rather than changing the existing CEC kAPI to allocate and
register CEC adapters I left it as-is. Instead new notifiers
functions are added to (un)register HDMI connector and CEC adapter
notifiers. These replace the current cec_notifier_get_conn and _put
functions.

For drivers that don't use notifiers the cec_s_conn_info function
was created so the connector info can be set directly as well.

This split in separate connector and CEC adapter functions is needed
since the notifier information is different between the two and this
makes it future proof since we will need to eventually support more
than one CEC adapter per HDMI connector.

By carefully designing these functions it is possible to convert
drivers to these new functions one-by-one, rather than as a painful
big-bang patch.

The plan is to merge the first three patches for kernel 5.3: these
patches provide the infrastructure needed by drm and cec drivers
to do the conversion during the 5.4 cycle, without requiring
patches that touch on multiple subsystems.

Once the conversion is done the new connector API can be exposed.

Various drivers have been converted as well as an example. These
are based on Dariusz' original series, but using the new notifier
functions.

Regards,

Hans

Changes since v8:

- Complete the documentation patch (now documents the new capability
  and the new field in the state changed event)
- Take a lock in cec_adap_g_connector_info
- cec-notifier: dropped 'called_cec_notifier_register', use 'callback'
  instead.
- cec_notifier_cec_adap_unregister: don't memset adap->conn_info, it's
  not necessary.
- seco-cec: include cec-notifier instead of relying on cec.h to include
  it, since that's no longer the case.
- Move cec_notifier_register, cec_notifier_unregister and
  cec_register_cec_notifier to cec.h. This avoids sparse/smatch warnings.
- Improve cec_(drm_)connector_info docbook comments.
- CEC_CAP_CONNECTOR_INFO is now defined as (1 << 8) instead of 0, but is
  removed from the cap set in cec_adapter_allocate while this API remains
  internal.

Dariusz Marcinkiewicz (9):
  cec: add struct cec_connector_info support
  cec: expose the new connector info API
  drm_dp_cec: add connector info support.
  drm/i915/intel_hdmi: use cec_notifier_conn_(un)register
  dw-hdmi-cec: use cec_notifier_cec_adap_(un)register
  dw-hdmi: use cec_notifier_conn_(un)register
  tda9950: use cec_notifier_cec_adap_(un)register
  tda998x: use cec_notifier_conn_(un)register
  drm/vc4/vc4_hdmi: fill in connector info

Hans Verkuil (4):
  cec-notifier: rename variables, check kstrdup and n->conn_name
  cec-notifier: add new notifier functions
  cec: document CEC_ADAP_G_CONNECTOR_INFO and capability
  meson/ao-cec: use cec_notifier_cec_adap_(un)register

 Documentation/media/uapi/cec/cec-funcs.rst|   1 +
 .../media/uapi/cec/cec-ioc-adap-g-caps.rst|   6 +-
 .../uapi/cec/cec-ioc-adap-g-conn-info.rst | 102 
 .../media/uapi/cec/cec-ioc-dqevent.rst|   8 ++
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   2 +-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c |   9 +-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 +---
 drivers/gpu/drm/drm_dp_cec.c  |  25 ++--
 drivers/gpu/drm/i2c/tda9950.c |  11 +-
 drivers/gpu/drm/i2c/tda998x_drv.c |  56 -
 drivers/gpu/drm/i915/intel_dp.c   |   4 +-
 drivers/gpu/drm/i915/intel_hdmi.c |  13 +-
 drivers/gpu/drm/nouveau/nouveau_connector.c   |   3 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c|  13 +-
 drivers/media/cec/cec-adap.c  |  31 +
 drivers/media/cec/cec-api.c   |  20 
 drivers/media/cec/cec-notifier.c  | 112 --
 drivers/media/platform/meson/ao-cec.c |  37 +++---
 drivers/media/platform/seco-cec/seco-cec.c|   2 +-
 include/drm/drm_dp_helper.h   |  14 +--
 include/media/cec-notifier.h  | 105 ++--
 include/media/cec.h   |  67 ++-
 include/uapi/linux/cec.h  |  40 +++
 23 files changed, 606 insertions(+), 179 deletions(-)
 create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst

-- 
2.20.1



Re: [PATCHv8 04/13] cec: expose the new connector info API

2019-06-25 Thread Hans Verkuil
On 6/25/19 3:59 PM, Dariusz Marcinkiewicz wrote:
> Hi.
> 
> This looks good except one comment about the ioctl.
> 
> On Mon, Jun 24, 2019 at 6:03 PM Hans Verkuil  wrote:
>>
> ...
>> +static long cec_adap_g_connector_info(struct cec_adapter *adap,
>> + struct cec_log_addrs __user *parg)
>> +{
>> +   if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
>> +   return -ENOTTY;
> I guess access to adap->conn_info needs to be guarded by the lock now.

Good catch! Yes, this needs a lock.

Regards,

Hans

> 
>> +   if (copy_to_user(parg, >conn_info,
>> +sizeof(adap->conn_info)))
>> +   return -EFAULT;
>> +   return 0;
>> +}
> 
> Best regards.
> 



Re: [PATCHv8 03/13] cec: add new notifier functions

2019-06-25 Thread Hans Verkuil
On 6/25/19 3:48 PM, Dariusz Marcinkiewicz wrote:
> Hello.
> 
> Some small comments/questions.
> 
> On Mon, Jun 24, 2019 at 6:03 PM Hans Verkuil  wrote:
>>
> ...
>> @@ -22,9 +22,11 @@ struct cec_notifier {
>> struct list_head head;
>> struct kref kref;
>> struct device *hdmi_dev;
>> +   struct cec_connector_info conn_info;
>> const char *conn_name;
>> struct cec_adapter *cec_adap;
>> void (*callback)(struct cec_adapter *adap, u16 pa);
>> +   bool called_cec_notifier_register;
> If I read his correctly callback is set only by cec_notifier_register
> (and not by the cec_notifier_cec_adap_register) so maybe that boolean
> is not needed and just checking if the callback is set is enough to
> tell those 2 cases apart?

True. I'll change this.

> 
> ...
>> +struct cec_notifier *
>> +cec_notifier_cec_adap_register(struct device *hdmi_dev, const char 
>> *conn_name,
>> +  struct cec_adapter *adap)
>> +{
>> +   struct cec_notifier *n;
>> +
>> +   if (WARN_ON(!adap))
>> +   return NULL;
>> +
>> +   n = cec_notifier_get_conn(hdmi_dev, conn_name);
>> +   if (!n)
>> +   return n;
>> +
>> +   mutex_lock(>lock);
>> +   n->cec_adap = adap;
>> +   adap->conn_info = n->conn_info;
> Would it make sense to use cec_s_conn_info? There is a certain
> asymmetry here  - cec_s_phys_addr is used to configure physical
> address, which also takes the adapter's lock while setting the
> physical address. That lock is not taken while the connector info is
> being set (not sure if that really matters for the code paths that
> would call into this function).

I thought about that, but there is a side-effect if I do that:
both cec_s_conn_info and cec_s_phys_addr send a state_changed
event, and I want to avoid that. Doing it this way ensures that
there will be only one event.

But there is definitely room for improvement here and I want to
work on that for the next kernel.

> 
>> +   adap->notifier = n;
>> +   cec_s_phys_addr(adap, n->phys_addr, false);
>> +   mutex_unlock(>lock);
>> +   return n;
>> +}
>> +EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_register);
>> +
>> +void cec_notifier_cec_adap_unregister(struct cec_notifier *n)
>> +{
>> +   if (!n)
>> +   return;
>> +
>> +   mutex_lock(>lock);
>> +   memset(>cec_adap->conn_info, 0, sizeof(n->cec_adap->conn_info));
> Could cec_s_conn_info be used to reset the connector info?
> Also, we explicitly clear connector info here. Since the notifier
> provides both connector info and physical address, maybe it would make
> sense to clear physical address as well?

Actually, this memset should be removed altogether. The connector info
doesn't change at all, it's just that right after this function is called
the whole CEC adapter will be unregistered. I thought that it might make
sense to zero the connector info, but really I should just leave it alone.

> 
> 
> ...
>>  void cec_notifier_unregister(struct cec_notifier *n)
>>  {
>> +   /* Do nothing unless cec_notifier_register was called first */
>> +   if (!n->called_cec_notifier_register)
> Could this check be made with n->lock held? cec_notifier_register sets
> this value while holding that lock.

It's not needed: you can never have a race here.

BTW, I'll be glad when I can remove these cec_notifier_(un)register
functions, they are pretty ugly and confusing.

Regards,

Hans

> ...
> 
> 
> Thank you.
> 



[PATCHv8.1 01/13] cec-notifier: rename variables, check kstrdup and n->conn_name

2019-06-25 Thread Hans Verkuil
dev -> hdmi_dev
conn -> conn_name

Check if n->conn_name is not NULL before calling strcmp.
Check the result of kstrdup, and clean up on error.

Signed-off-by: Hans Verkuil 
---
Changes since v8:

- check n->conn_name before calling strcmp to make the code more robust
---
 drivers/media/cec/cec-notifier.c | 27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 9598c7778871..f72b19c351dd 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,8 +21,8 @@ struct cec_notifier {
struct mutex lock;
struct list_head head;
struct kref kref;
-   struct device *dev;
-   const char *conn;
+   struct device *hdmi_dev;
+   const char *conn_name;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);

@@ -32,14 +32,16 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);

-struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
+struct cec_notifier *
+cec_notifier_get_conn(struct device *hdmi_dev, const char *conn_name)
 {
struct cec_notifier *n;

mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev &&
-   (!conn || !strcmp(n->conn, conn))) {
+   if (n->hdmi_dev == hdmi_dev &&
+   (!conn_name ||
+(n->conn_name && !strcmp(n->conn_name, conn_name {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -48,10 +50,17 @@ struct cec_notifier *cec_notifier_get_conn(struct device 
*dev, const char *conn)
n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n)
goto unlock;
-   n->dev = dev;
-   if (conn)
-   n->conn = kstrdup(conn, GFP_KERNEL);
+   n->hdmi_dev = hdmi_dev;
+   if (conn_name) {
+   n->conn_name = kstrdup(conn_name, GFP_KERNEL);
+   if (!n->conn_name) {
+   kfree(n);
+   n = NULL;
+   goto unlock;
+   }
+   }
n->phys_addr = CEC_PHYS_ADDR_INVALID;
+
mutex_init(>lock);
kref_init(>kref);
list_add_tail(>head, _notifiers);
@@ -67,7 +76,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);

list_del(>head);
-   kfree(n->conn);
+   kfree(n->conn_name);
kfree(n);
 }

-- 
2.20.1




Re: [PATCHv8 02/13] cec: add struct cec_connector_info support

2019-06-25 Thread Hans Verkuil
On 6/24/19 6:03 PM, Hans Verkuil wrote:
> From: Dariusz Marcinkiewicz 
> 
> Define struct cec_connector_info in media/cec.h and define
> CEC_CAP_CONNECTOR_INFO. In a later patch this will be moved to
> uapi/linux/cec.h.
> 
> For now just define this together with the cec_fill_conn_info_from_drm
> and cec_s_conn_info functions: this allows both drm and media to make
> use of this without requiring cross-subsystem changes.
> 
> Signed-off-by: Dariusz Marcinkiewicz 
> Co-developed-by: Hans Verkuil 
> Signed-off-by: Hans Verkuil 
> ---
>  drivers/media/cec/cec-adap.c | 29 +++
>  drivers/media/cec/cec-core.c |  5 
>  include/media/cec.h  | 45 +++-
>  3 files changed, 78 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
> index ac3683a7b2ab..451c61bde4d4 100644
> --- a/drivers/media/cec/cec-adap.c
> +++ b/drivers/media/cec/cec-adap.c
> @@ -16,7 +16,10 @@
>  #include 
>  #include 
>  
> +#include 
> +#include 
>  #include 
> +#include 
>  
>  #include "cec-priv.h"
>  
> @@ -75,6 +78,16 @@ u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int 
> size,
>  }
>  EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
>  
> +void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
> +  const struct drm_connector *connector)
> +{
> + memset(conn_info, 0, sizeof(*conn_info));
> + conn_info->type = CEC_CONNECTOR_TYPE_DRM;
> + conn_info->drm.card_no = connector->dev->primary->index;
> + conn_info->drm.connector_id = connector->base.id;
> +}
> +EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm);
> +
>  /*
>   * Queue a new event for this filehandle. If ts == 0, then set it
>   * to the current time.
> @@ -1598,6 +1611,22 @@ void cec_s_phys_addr_from_edid(struct cec_adapter 
> *adap,
>  }
>  EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
>  
> +void cec_s_conn_info(struct cec_adapter *adap,
> +  const struct cec_connector_info *conn_info)
> +{
> + if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
> + return;
> +
> + mutex_lock(>lock);
> + if (conn_info)
> + adap->conn_info = *conn_info;
> + else
> + memset(>conn_info, 0, sizeof(adap->conn_info));
> + cec_post_state_event(adap);
> + mutex_unlock(>lock);
> +}
> +EXPORT_SYMBOL_GPL(cec_s_conn_info);
> +
>  /*
>   * Called from either the ioctl or a driver to set the logical addresses.
>   *
> diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
> index db7adffcdc76..e45b792d26fb 100644
> --- a/drivers/media/cec/cec-core.c
> +++ b/drivers/media/cec/cec-core.c
> @@ -189,6 +189,11 @@ static void cec_cec_notify(struct cec_adapter *adap, u16 
> pa)
>   cec_s_phys_addr(adap, pa, false);
>  }
>  
> +void cec_notifier_register(struct cec_notifier *n,
> +struct cec_adapter *adap,
> +void (*callback)(struct cec_adapter *adap, u16 pa));
> +void cec_notifier_unregister(struct cec_notifier *n);
> +
>  void cec_register_cec_notifier(struct cec_adapter *adap,
>  struct cec_notifier *notifier)
>  {
> diff --git a/include/media/cec.h b/include/media/cec.h
> index 707411ef8ba2..45f2c98ed75b 100644
> --- a/include/media/cec.h
> +++ b/include/media/cec.h
> @@ -17,7 +17,9 @@
>  #include 
>  #include 
>  #include 
> -#include 
> +
> +/* CEC_ADAP_G_CONNECTOR_INFO is available */
> +#define CEC_CAP_CONNECTOR_INFO   0
>  
>  #define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
> CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
> @@ -53,6 +55,7 @@ struct cec_devnode {
>  struct cec_adapter;
>  struct cec_data;
>  struct cec_pin;
> +struct cec_notifier;
>  
>  struct cec_data {
>   struct list_head list;
> @@ -144,6 +147,27 @@ struct cec_adap_ops {
>   */
>  #define CEC_MAX_MSG_TX_QUEUE_SZ  (18 * 1)
>  
> +/**
> + * struct cec_event_connector - tells if and which connector is associated
> + * with the CEC adapter.
> + * @card_no: drm card number
> + * @connector_id: drm connector ID
> + */
> +struct cec_drm_connector_info {
> + __u32 card_no;
> + __u32 connector_id;
> +};
> +
> +#define CEC_CONNECTOR_TYPE_NO_CONNECTOR  0
> +#define CEC_CONNECTOR_TYPE_DRM   1
> +struct cec_connector_info {
> + __u32 type;
> + union {
> + struct cec_drm_connector_info drm;
> + __u32 raw[16];
> + };
> +};
> +
>  str

[PATCHv8 11/13] tda9950: use cec_notifier_cec_adap_(un)register

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_cec_adap_(un)register() functions to
(un)register the notifier for the CEC adapter.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda9950.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda9950.c b/drivers/gpu/drm/i2c/tda9950.c
index 250b5e02a314..2f3381f0b2bf 100644
--- a/drivers/gpu/drm/i2c/tda9950.c
+++ b/drivers/gpu/drm/i2c/tda9950.c
@@ -423,7 +423,7 @@ static int tda9950_probe(struct i2c_client *client,
priv->hdmi = glue->parent;
 
priv->adap = cec_allocate_adapter(_cec_ops, priv, "tda9950",
- CEC_CAP_DEFAULTS,
+ CEC_CAP_DEFAULTS | 
CEC_CAP_CONNECTOR_INFO,
  CEC_MAX_LOG_ADDRS);
if (IS_ERR(priv->adap))
return PTR_ERR(priv->adap);
@@ -460,13 +460,14 @@ static int tda9950_probe(struct i2c_client *client,
if (ret < 0)
return ret;
 
-   priv->notify = cec_notifier_get(priv->hdmi);
+   priv->notify = cec_notifier_cec_adap_register(priv->hdmi, NULL,
+ priv->adap);
if (!priv->notify)
return -ENOMEM;
 
ret = cec_register_adapter(priv->adap, priv->hdmi);
if (ret < 0) {
-   cec_notifier_put(priv->notify);
+   cec_notifier_cec_adap_unregister(priv->notify);
return ret;
}
 
@@ -476,8 +477,6 @@ static int tda9950_probe(struct i2c_client *client,
 */
devm_remove_action(dev, tda9950_cec_del, priv);
 
-   cec_register_cec_notifier(priv->adap, priv->notify);
-
return 0;
 }
 
@@ -485,8 +484,8 @@ static int tda9950_remove(struct i2c_client *client)
 {
struct tda9950_priv *priv = i2c_get_clientdata(client);
 
+   cec_notifier_cec_adap_unregister(priv->notify);
cec_unregister_adapter(priv->adap);
-   cec_notifier_put(priv->notify);
 
return 0;
 }
-- 
2.20.1



[PATCHv8 12/13] tda998x: use cec_notifier_conn_(un)register

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector, and fill in
the cec_connector_info.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 56 +++
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 7f34601bb515..019e1f2f008c 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1253,6 +1253,8 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
  struct drm_device *drm)
 {
struct drm_connector *connector = >connector;
+   struct cec_connector_info conn_info;
+   struct i2c_board_info cec_info;
int ret;
 
connector->interlace_allowed = 1;
@@ -1269,6 +1271,31 @@ static int tda998x_connector_init(struct tda998x_priv 
*priv,
if (ret)
return ret;
 
+   /*
+* Some TDA998x are actually two I2C devices merged onto one piece
+* of silicon: TDA9989 and TDA19989 combine the HDMI transmitter
+* with a slightly modified TDA9950 CEC device.  The CEC device
+* is at the TDA9950 address, with the address pins strapped across
+* to the TDA998x address pins.  Hence, it always has the same
+* offset.
+*/
+   memset(_info, 0, sizeof(cec_info));
+   strlcpy(cec_info.type, "tda9950", sizeof(cec_info.type));
+   cec_info.addr = priv->cec_addr;
+   cec_info.platform_data = >cec_glue;
+   cec_info.irq = priv->hdmi->irq;
+
+   priv->cec = i2c_new_device(priv->hdmi->adapter, _info);
+   if (!priv->cec)
+   return -ENODEV;
+
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   priv->cec_notify = cec_notifier_conn_register(priv->cec_glue.parent,
+ NULL, _info);
+   if (!priv->cec_notify)
+   return -ENOMEM;
+
drm_connector_attach_encoder(>connector,
 priv->bridge.encoder);
 
@@ -1651,14 +1678,13 @@ static void tda998x_destroy(struct device *dev)
i2c_unregister_device(priv->cec);
 
if (priv->cec_notify)
-   cec_notifier_put(priv->cec_notify);
+   cec_notifier_conn_unregister(priv->cec_notify);
 }
 
 static int tda998x_create(struct device *dev)
 {
struct i2c_client *client = to_i2c_client(dev);
struct device_node *np = client->dev.of_node;
-   struct i2c_board_info cec_info;
struct tda998x_priv *priv;
u32 video;
int rev_lo, rev_hi, ret;
@@ -1776,12 +1802,6 @@ static int tda998x_create(struct device *dev)
cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
}
 
-   priv->cec_notify = cec_notifier_get(dev);
-   if (!priv->cec_notify) {
-   ret = -ENOMEM;
-   goto fail;
-   }
-
priv->cec_glue.parent = dev;
priv->cec_glue.data = priv;
priv->cec_glue.init = tda998x_cec_hook_init;
@@ -1789,26 +1809,6 @@ static int tda998x_create(struct device *dev)
priv->cec_glue.open = tda998x_cec_hook_open;
priv->cec_glue.release = tda998x_cec_hook_release;
 
-   /*
-* Some TDA998x are actually two I2C devices merged onto one piece
-* of silicon: TDA9989 and TDA19989 combine the HDMI transmitter
-* with a slightly modified TDA9950 CEC device.  The CEC device
-* is at the TDA9950 address, with the address pins strapped across
-* to the TDA998x address pins.  Hence, it always has the same
-* offset.
-*/
-   memset(_info, 0, sizeof(cec_info));
-   strlcpy(cec_info.type, "tda9950", sizeof(cec_info.type));
-   cec_info.addr = priv->cec_addr;
-   cec_info.platform_data = >cec_glue;
-   cec_info.irq = client->irq;
-
-   priv->cec = i2c_new_device(client->adapter, _info);
-   if (!priv->cec) {
-   ret = -ENODEV;
-   goto fail;
-   }
-
/* enable EDID read irq: */
reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
 
-- 
2.20.1



[PATCHv8 09/13] dw-hdmi: use cec_notifier_conn_(un)register

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector, and fill in
the cec_connector_info.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 --
 1 file changed, 58 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 045b1b13fd0e..fc4d3b5f71d0 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -133,6 +133,8 @@ struct dw_hdmi {
struct drm_connector connector;
struct drm_bridge bridge;
 
+   int irq;
+
unsigned int version;
 
struct platform_device *audio;
@@ -184,6 +186,7 @@ struct dw_hdmi {
void (*enable_audio)(struct dw_hdmi *hdmi);
void (*disable_audio)(struct dw_hdmi *hdmi);
 
+   bool cec_configured;
struct cec_notifier *cec_notifier;
 };
 
@@ -2108,11 +2111,35 @@ static const struct drm_connector_helper_funcs 
dw_hdmi_connector_helper_funcs =
.get_modes = dw_hdmi_connector_get_modes,
 };
 
+static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
+{
+   mutex_lock(>mutex);
+   hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
+   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+   mutex_unlock(>mutex);
+}
+
+static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
+{
+   mutex_lock(>mutex);
+   hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
+   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+   mutex_unlock(>mutex);
+}
+
+static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
+   .write = hdmi_writeb,
+   .read = hdmi_readb,
+   .enable = dw_hdmi_cec_enable,
+   .disable = dw_hdmi_cec_disable,
+};
+
 static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
 {
struct dw_hdmi *hdmi = bridge->driver_private;
struct drm_encoder *encoder = bridge->encoder;
struct drm_connector *connector = >connector;
+   struct cec_connector_info conn_info;
 
connector->interlace_allowed = 1;
connector->polled = DRM_CONNECTOR_POLL_HPD;
@@ -2124,6 +2151,33 @@ static int dw_hdmi_bridge_attach(struct drm_bridge 
*bridge)
 
drm_connector_attach_encoder(connector, encoder);
 
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   hdmi->cec_notifier = cec_notifier_conn_register(hdmi->dev, NULL,
+   _info);
+   if (!hdmi->cec_notifier)
+   return -ENOMEM;
+
+   if (hdmi->cec_configured) {
+   struct platform_device_info pdevinfo;
+   struct dw_hdmi_cec_data cec;
+
+   memset(, 0, sizeof(pdevinfo));
+   pdevinfo.parent = hdmi->dev;
+   pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+   cec.hdmi = hdmi;
+   cec.ops = _hdmi_cec_ops;
+   cec.irq = hdmi->irq;
+
+   pdevinfo.name = "dw-hdmi-cec";
+   pdevinfo.data = 
+   pdevinfo.size_data = sizeof(cec);
+   pdevinfo.dma_mask = 0;
+
+   hdmi->cec = platform_device_register_full();
+   }
+
return 0;
 }
 
@@ -2393,29 +2447,6 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
return -ENODEV;
 }
 
-static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
-{
-   mutex_lock(>mutex);
-   hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
-   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
-   mutex_unlock(>mutex);
-}
-
-static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
-{
-   mutex_lock(>mutex);
-   hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
-   hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
-   mutex_unlock(>mutex);
-}
-
-static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
-   .write = hdmi_writeb,
-   .read = hdmi_readb,
-   .enable = dw_hdmi_cec_enable,
-   .disable = dw_hdmi_cec_disable,
-};
-
 static const struct regmap_config hdmi_regmap_8bit_config = {
.reg_bits   = 32,
.val_bits   = 8,
@@ -2438,7 +2469,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
struct device_node *np = dev->of_node;
struct platform_device_info pdevinfo;
struct device_node *ddc_node;
-   struct dw_hdmi_cec_data cec;
struct dw_hdmi *hdmi;
struct resource *iores = NULL;
int irq;
@@ -2588,6 +2618,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
ret = irq;
goto err_iahb;
}
+   hdmi->irq = irq;
 
ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
dw_hdmi_irq, IRQF_SHARED,
@@ -2595,12 +2626,6 @@ __dw_hdmi_probe(struct platform_devic

[PATCHv8 04/13] cec: expose the new connector info API

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Until now the connector info API was a kernel-internal API only.
This moves it to the public API and adds the new ioctl to retrieve
this information.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-adap.c |  2 ++
 drivers/media/cec/cec-api.c  | 16 
 drivers/media/cec/cec-core.c |  5 -
 include/media/cec.h  | 26 +-
 include/uapi/linux/cec.h | 33 +
 5 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 451c61bde4d4..059c83525024 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -319,6 +319,8 @@ static void cec_post_state_event(struct cec_adapter *adap)
 
ev.state_change.phys_addr = adap->phys_addr;
ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+   ev.state_change.have_conn_info =
+   adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
cec_queue_event(adap, );
 }
 
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 12d676484472..cba0099beab2 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -187,6 +187,17 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, 
struct cec_fh *fh,
return 0;
 }
 
+static long cec_adap_g_connector_info(struct cec_adapter *adap,
+ struct cec_log_addrs __user *parg)
+{
+   if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
+   return -ENOTTY;
+   if (copy_to_user(parg, >conn_info,
+sizeof(adap->conn_info)))
+   return -EFAULT;
+   return 0;
+}
+
 static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
 bool block, struct cec_msg __user *parg)
 {
@@ -506,6 +517,9 @@ static long cec_ioctl(struct file *filp, unsigned int cmd, 
unsigned long arg)
case CEC_ADAP_S_LOG_ADDRS:
return cec_adap_s_log_addrs(adap, fh, block, parg);
 
+   case CEC_ADAP_G_CONNECTOR_INFO:
+   return cec_adap_g_connector_info(adap, parg);
+
case CEC_TRANSMIT:
return cec_transmit(adap, fh, block, parg);
 
@@ -578,6 +592,8 @@ static int cec_open(struct inode *inode, struct file *filp)
/* Queue up initial state events */
ev.state_change.phys_addr = adap->phys_addr;
ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+   ev.state_change.have_conn_info =
+   adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
cec_queue_event_fh(fh, , 0);
 #ifdef CONFIG_CEC_PIN
if (adap->pin && adap->pin->ops->read_hpd) {
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index e45b792d26fb..db7adffcdc76 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -189,11 +189,6 @@ static void cec_cec_notify(struct cec_adapter *adap, u16 
pa)
cec_s_phys_addr(adap, pa, false);
 }
 
-void cec_notifier_register(struct cec_notifier *n,
-  struct cec_adapter *adap,
-  void (*callback)(struct cec_adapter *adap, u16 pa));
-void cec_notifier_unregister(struct cec_notifier *n);
-
 void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier)
 {
diff --git a/include/media/cec.h b/include/media/cec.h
index 45f2c98ed75b..2c30df40e2ce 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -17,9 +17,7 @@
 #include 
 #include 
 #include 
-
-/* CEC_ADAP_G_CONNECTOR_INFO is available */
-#define CEC_CAP_CONNECTOR_INFO 0
+#include 
 
 #define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
  CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
@@ -55,7 +53,6 @@ struct cec_devnode {
 struct cec_adapter;
 struct cec_data;
 struct cec_pin;
-struct cec_notifier;
 
 struct cec_data {
struct list_head list;
@@ -147,27 +144,6 @@ struct cec_adap_ops {
  */
 #define CEC_MAX_MSG_TX_QUEUE_SZ(18 * 1)
 
-/**
- * struct cec_event_connector - tells if and which connector is associated
- * with the CEC adapter.
- * @card_no: drm card number
- * @connector_id: drm connector ID
- */
-struct cec_drm_connector_info {
-   __u32 card_no;
-   __u32 connector_id;
-};
-
-#define CEC_CONNECTOR_TYPE_NO_CONNECTOR0
-#define CEC_CONNECTOR_TYPE_DRM 1
-struct cec_connector_info {
-   __u32 type;
-   union {
-   struct cec_drm_connector_info drm;
-   __u32 raw[16];
-   };
-};
-
 struct cec_adapter {
struct module *owner;
char name[32];
diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
index 5704fa0292b5..414df75c0ab8 100644
--- a/include/uapi/linux/cec.h
+++ b/include/uap

[PATCHv8 03/13] cec: add new notifier functions

2019-06-24 Thread Hans Verkuil
In order to support multiple CEC devices for an HDMI connector,
and to support cec_connector_info, drivers should use either a
cec_notifier_conn_(un)register pair of functions (HDMI drivers)
or a cec_notifier_cec_adap_(un)register pair (CEC adapter drivers).

This replaces cec_notifier_get_conn/cec_notifier_put.

For CEC adapters it is also no longer needed to call cec_notifier_register,
cec_register_cec_notifier and cec_notifier_unregister. This is now
all handled internally by the new functions.

The called_cec_notifier_register bool is needed to handle the case where
a CEC adapter driver called the old cec_notifier_register() function
instead of cec_notifier_cec_adap_unregister().

Once those old functions are removed in the future, that bool can also
be removed.

Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-notifier.c | 89 
 include/media/cec-notifier.h | 78 
 2 files changed, 167 insertions(+)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index ce10dfd400bb..49d6ec198d38 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -22,9 +22,11 @@ struct cec_notifier {
struct list_head head;
struct kref kref;
struct device *hdmi_dev;
+   struct cec_connector_info conn_info;
const char *conn_name;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
+   bool called_cec_notifier_register;
 
u16 phys_addr;
 };
@@ -87,6 +89,85 @@ void cec_notifier_put(struct cec_notifier *n)
 }
 EXPORT_SYMBOL_GPL(cec_notifier_put);
 
+struct cec_notifier *
+cec_notifier_conn_register(struct device *hdmi_dev, const char *conn_name,
+  const struct cec_connector_info *conn_info)
+{
+   struct cec_notifier *n = cec_notifier_get_conn(hdmi_dev, conn_name);
+
+   if (!n)
+   return n;
+
+   mutex_lock(>lock);
+   n->phys_addr = CEC_PHYS_ADDR_INVALID;
+   if (conn_info)
+   n->conn_info = *conn_info;
+   else
+   memset(>conn_info, 0, sizeof(n->conn_info));
+   if (n->cec_adap) {
+   cec_phys_addr_invalidate(n->cec_adap);
+   cec_s_conn_info(n->cec_adap, conn_info);
+   }
+   mutex_unlock(>lock);
+   return n;
+}
+EXPORT_SYMBOL_GPL(cec_notifier_conn_register);
+
+void cec_notifier_conn_unregister(struct cec_notifier *n)
+{
+   if (!n)
+   return;
+
+   mutex_lock(>lock);
+   memset(>conn_info, 0, sizeof(n->conn_info));
+   n->phys_addr = CEC_PHYS_ADDR_INVALID;
+   if (n->cec_adap) {
+   cec_phys_addr_invalidate(n->cec_adap);
+   cec_s_conn_info(n->cec_adap, NULL);
+   }
+   mutex_unlock(>lock);
+   cec_notifier_put(n);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_conn_unregister);
+
+struct cec_notifier *
+cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *conn_name,
+  struct cec_adapter *adap)
+{
+   struct cec_notifier *n;
+
+   if (WARN_ON(!adap))
+   return NULL;
+
+   n = cec_notifier_get_conn(hdmi_dev, conn_name);
+   if (!n)
+   return n;
+
+   mutex_lock(>lock);
+   n->cec_adap = adap;
+   adap->conn_info = n->conn_info;
+   adap->notifier = n;
+   cec_s_phys_addr(adap, n->phys_addr, false);
+   mutex_unlock(>lock);
+   return n;
+}
+EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_register);
+
+void cec_notifier_cec_adap_unregister(struct cec_notifier *n)
+{
+   if (!n)
+   return;
+
+   mutex_lock(>lock);
+   memset(>cec_adap->conn_info, 0, sizeof(n->cec_adap->conn_info));
+   n->cec_adap->notifier = NULL;
+   n->cec_adap = NULL;
+   n->callback = NULL;
+   mutex_unlock(>lock);
+   cec_notifier_put(n);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_unregister);
+
 void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
 {
if (n == NULL)
@@ -96,6 +177,8 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 
pa)
n->phys_addr = pa;
if (n->callback)
n->callback(n->cec_adap, n->phys_addr);
+   else if (n->cec_adap)
+   cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
mutex_unlock(>lock);
 }
 EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
@@ -121,6 +204,7 @@ void cec_notifier_register(struct cec_notifier *n,
 {
kref_get(>kref);
mutex_lock(>lock);
+   n->called_cec_notifier_register = true;
n->cec_adap = adap;
n->callback = callback;
n->callback(adap, n->phys_addr);
@@ -130,8 +214,13 @@ EXPORT_SYMBOL_GPL(cec_notifier_register);
 
 void cec_notifier_unregister(struct cec_notifier *n)
 {
+   /* Do not

[PATCHv8 07/13] drm/i915/intel_hdmi: use cec_notifier_conn_(un)register

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector, and fill in
the cec_connector_info.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/i915/intel_hdmi.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 34be2cfd0ec8..05a5ccc1517e 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2670,8 +2670,9 @@ intel_hdmi_connector_register(struct drm_connector 
*connector)
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
-   if (intel_attached_hdmi(connector)->cec_notifier)
-   cec_notifier_put(intel_attached_hdmi(connector)->cec_notifier);
+   struct cec_notifier *n = intel_attached_hdmi(connector)->cec_notifier;
+
+   cec_notifier_conn_unregister(n);
 
intel_connector_destroy(connector);
 }
@@ -2968,6 +2969,7 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
enum port port = intel_encoder->port;
+   struct cec_connector_info conn_info;
 
DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
  port_name(port));
@@ -3020,8 +3022,11 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
}
 
-   intel_hdmi->cec_notifier = cec_notifier_get_conn(dev->dev,
-port_identifier(port));
+   cec_fill_conn_info_from_drm(_info, connector);
+
+   intel_hdmi->cec_notifier =
+   cec_notifier_conn_register(dev->dev, port_identifier(port),
+  _info);
if (!intel_hdmi->cec_notifier)
DRM_DEBUG_KMS("CEC notifier get failed\n");
 }
-- 
2.20.1



[PATCHv8 13/13] drm/vc4/vc4_hdmi: fill in connector info

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Fill in the connector info, allowing userspace to associate
the CEC device with the drm connector.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 99fc8569e0f5..a998bb35b375 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1279,6 +1279,9 @@ static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
 
 static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 {
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+   struct cec_connector_info conn_info;
+#endif
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = drm->dev_private;
@@ -1397,13 +1400,15 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 #ifdef CONFIG_DRM_VC4_HDMI_CEC
hdmi->cec_adap = cec_allocate_adapter(_hdmi_cec_adap_ops,
  vc4, "vc4",
- CEC_CAP_TRANSMIT |
- CEC_CAP_LOG_ADDRS |
- CEC_CAP_PASSTHROUGH |
- CEC_CAP_RC, 1);
+ CEC_CAP_DEFAULTS |
+ CEC_CAP_CONNECTOR_INFO, 1);
ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
if (ret < 0)
goto err_destroy_conn;
+
+   cec_fill_conn_info_from_drm(_info, hdmi->connector);
+   cec_s_conn_info(hdmi->cec_adap, _info);
+
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0x);
value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
-- 
2.20.1



[PATCHv8 08/13] dw-hdmi-cec: use cec_notifier_cec_adap_(un)register

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Use the new cec_notifier_cec_adap_(un)register() functions to
(un)register the notifier for the CEC adapter.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
index 6c323510f128..6f7ecacb7d1f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -281,13 +281,14 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
 
-   cec->notify = cec_notifier_get(pdev->dev.parent);
+   cec->notify = cec_notifier_cec_adap_register(pdev->dev.parent,
+NULL, cec->adap);
if (!cec->notify)
return -ENOMEM;
 
ret = cec_register_adapter(cec->adap, pdev->dev.parent);
if (ret < 0) {
-   cec_notifier_put(cec->notify);
+   cec_notifier_cec_adap_unregister(cec->notify);
return ret;
}
 
@@ -297,8 +298,6 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)
 */
devm_remove_action(>dev, dw_hdmi_cec_del, cec);
 
-   cec_register_cec_notifier(cec->adap, cec->notify);
-
return 0;
 }
 
@@ -306,8 +305,8 @@ static int dw_hdmi_cec_remove(struct platform_device *pdev)
 {
struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
 
+   cec_notifier_cec_adap_unregister(cec->notify);
cec_unregister_adapter(cec->adap);
-   cec_notifier_put(cec->notify);
 
return 0;
 }
-- 
2.20.1



[PATCHv8 10/13] meson/ao-cec: use cec_notifier_cec_adap_(un)register

2019-06-24 Thread Hans Verkuil
Use the new cec_notifier_cec_adap_(un)register() functions to
(un)register the notifier for the CEC adapter.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/meson/ao-cec.c | 37 +--
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/meson/ao-cec.c 
b/drivers/media/platform/meson/ao-cec.c
index facf9b029e79..b80eb8f9b422 100644
--- a/drivers/media/platform/meson/ao-cec.c
+++ b/drivers/media/platform/meson/ao-cec.c
@@ -616,20 +616,22 @@ static int meson_ao_cec_probe(struct platform_device 
*pdev)
 
spin_lock_init(_cec->cec_reg_lock);
 
-   ao_cec->notify = cec_notifier_get(hdmi_dev);
-   if (!ao_cec->notify)
-   return -ENOMEM;
-
ao_cec->adap = cec_allocate_adapter(_ao_cec_ops, ao_cec,
"meson_ao_cec",
CEC_CAP_LOG_ADDRS |
CEC_CAP_TRANSMIT |
CEC_CAP_RC |
-   CEC_CAP_PASSTHROUGH,
+   CEC_CAP_PASSTHROUGH |
+   CEC_CAP_CONNECTOR_INFO,
1); /* Use 1 for now */
-   if (IS_ERR(ao_cec->adap)) {
-   ret = PTR_ERR(ao_cec->adap);
-   goto out_probe_notify;
+   if (IS_ERR(ao_cec->adap))
+   return PTR_ERR(ao_cec->adap);
+
+   ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+   ao_cec->adap);
+   if (!ao_cec->notify) {
+   ret = -ENOMEM;
+   goto out_probe_adapter;
}
 
ao_cec->adap->owner = THIS_MODULE;
@@ -638,7 +640,7 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
ao_cec->base = devm_ioremap_resource(>dev, res);
if (IS_ERR(ao_cec->base)) {
ret = PTR_ERR(ao_cec->base);
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
irq = platform_get_irq(pdev, 0);
@@ -648,20 +650,20 @@ static int meson_ao_cec_probe(struct platform_device 
*pdev)
0, NULL, ao_cec);
if (ret) {
dev_err(>dev, "irq request failed\n");
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
ao_cec->core = devm_clk_get(>dev, "core");
if (IS_ERR(ao_cec->core)) {
dev_err(>dev, "core clock request failed\n");
ret = PTR_ERR(ao_cec->core);
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
ret = clk_prepare_enable(ao_cec->core);
if (ret) {
dev_err(>dev, "core clock enable failed\n");
-   goto out_probe_adapter;
+   goto out_probe_notify;
}
 
ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE);
@@ -685,19 +687,17 @@ static int meson_ao_cec_probe(struct platform_device 
*pdev)
writel_relaxed(CEC_GEN_CNTL_RESET,
   ao_cec->base + CEC_GEN_CNTL_REG);
 
-   cec_register_cec_notifier(ao_cec->adap, ao_cec->notify);
-
return 0;
 
 out_probe_clk:
clk_disable_unprepare(ao_cec->core);
 
+out_probe_notify:
+   cec_notifier_cec_adap_unregister(ao_cec->notify);
+
 out_probe_adapter:
cec_delete_adapter(ao_cec->adap);
 
-out_probe_notify:
-   cec_notifier_put(ao_cec->notify);
-
dev_err(>dev, "CEC controller registration failed\n");
 
return ret;
@@ -709,10 +709,9 @@ static int meson_ao_cec_remove(struct platform_device 
*pdev)
 
clk_disable_unprepare(ao_cec->core);
 
+   cec_notifier_cec_adap_unregister(ao_cec->notify);
cec_unregister_adapter(ao_cec->adap);
 
-   cec_notifier_put(ao_cec->notify);
-
return 0;
 }
 
-- 
2.20.1



[PATCHv8 02/13] cec: add struct cec_connector_info support

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Define struct cec_connector_info in media/cec.h and define
CEC_CAP_CONNECTOR_INFO. In a later patch this will be moved to
uapi/linux/cec.h.

For now just define this together with the cec_fill_conn_info_from_drm
and cec_s_conn_info functions: this allows both drm and media to make
use of this without requiring cross-subsystem changes.

Signed-off-by: Dariusz Marcinkiewicz 
Co-developed-by: Hans Verkuil 
Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-adap.c | 29 +++
 drivers/media/cec/cec-core.c |  5 
 include/media/cec.h  | 45 +++-
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index ac3683a7b2ab..451c61bde4d4 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -16,7 +16,10 @@
 #include 
 #include 
 
+#include 
+#include 
 #include 
+#include 
 
 #include "cec-priv.h"
 
@@ -75,6 +78,16 @@ u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
 }
 EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
 
+void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
+const struct drm_connector *connector)
+{
+   memset(conn_info, 0, sizeof(*conn_info));
+   conn_info->type = CEC_CONNECTOR_TYPE_DRM;
+   conn_info->drm.card_no = connector->dev->primary->index;
+   conn_info->drm.connector_id = connector->base.id;
+}
+EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm);
+
 /*
  * Queue a new event for this filehandle. If ts == 0, then set it
  * to the current time.
@@ -1598,6 +1611,22 @@ void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
 }
 EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
 
+void cec_s_conn_info(struct cec_adapter *adap,
+const struct cec_connector_info *conn_info)
+{
+   if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
+   return;
+
+   mutex_lock(>lock);
+   if (conn_info)
+   adap->conn_info = *conn_info;
+   else
+   memset(>conn_info, 0, sizeof(adap->conn_info));
+   cec_post_state_event(adap);
+   mutex_unlock(>lock);
+}
+EXPORT_SYMBOL_GPL(cec_s_conn_info);
+
 /*
  * Called from either the ioctl or a driver to set the logical addresses.
  *
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index db7adffcdc76..e45b792d26fb 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -189,6 +189,11 @@ static void cec_cec_notify(struct cec_adapter *adap, u16 
pa)
cec_s_phys_addr(adap, pa, false);
 }
 
+void cec_notifier_register(struct cec_notifier *n,
+  struct cec_adapter *adap,
+  void (*callback)(struct cec_adapter *adap, u16 pa));
+void cec_notifier_unregister(struct cec_notifier *n);
+
 void cec_register_cec_notifier(struct cec_adapter *adap,
   struct cec_notifier *notifier)
 {
diff --git a/include/media/cec.h b/include/media/cec.h
index 707411ef8ba2..45f2c98ed75b 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -17,7 +17,9 @@
 #include 
 #include 
 #include 
-#include 
+
+/* CEC_ADAP_G_CONNECTOR_INFO is available */
+#define CEC_CAP_CONNECTOR_INFO 0
 
 #define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
  CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
@@ -53,6 +55,7 @@ struct cec_devnode {
 struct cec_adapter;
 struct cec_data;
 struct cec_pin;
+struct cec_notifier;
 
 struct cec_data {
struct list_head list;
@@ -144,6 +147,27 @@ struct cec_adap_ops {
  */
 #define CEC_MAX_MSG_TX_QUEUE_SZ(18 * 1)
 
+/**
+ * struct cec_event_connector - tells if and which connector is associated
+ * with the CEC adapter.
+ * @card_no: drm card number
+ * @connector_id: drm connector ID
+ */
+struct cec_drm_connector_info {
+   __u32 card_no;
+   __u32 connector_id;
+};
+
+#define CEC_CONNECTOR_TYPE_NO_CONNECTOR0
+#define CEC_CONNECTOR_TYPE_DRM 1
+struct cec_connector_info {
+   __u32 type;
+   union {
+   struct cec_drm_connector_info drm;
+   __u32 raw[16];
+   };
+};
+
 struct cec_adapter {
struct module *owner;
char name[32];
@@ -182,6 +206,7 @@ struct cec_adapter {
struct cec_fh *cec_initiator;
bool passthrough;
struct cec_log_addrs log_addrs;
+   struct cec_connector_info conn_info;
 
u32 tx_timeouts;
 
@@ -233,6 +258,7 @@ static inline bool cec_is_registered(const struct 
cec_adapter *adap)
((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
 
 struct edid;
+struct drm_connector;
 
 #if IS_REACHABLE(CONFIG_CEC_CORE)
 struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
@@ -247,6 +273,8 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 

[PATCHv8 06/13] drm_dp_cec: add connector info support.

2019-06-24 Thread Hans Verkuil
From: Dariusz Marcinkiewicz 

Pass the connector info to the CEC adapter. This makes it possible
to associate the CEC adapter with the corresponding drm connector.

Signed-off-by: Dariusz Marcinkiewicz 
Signed-off-by: Hans Verkuil 
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  2 +-
 drivers/gpu/drm/drm_dp_cec.c  | 25 ---
 drivers/gpu/drm/i915/intel_dp.c   |  4 +--
 drivers/gpu/drm/nouveau/nouveau_connector.c   |  3 +--
 include/drm/drm_dp_helper.h   | 14 +--
 5 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 6e205ee36ac3..7f2eb4eb1035 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -394,7 +394,7 @@ void amdgpu_dm_initialize_dp_connector(struct 
amdgpu_display_manager *dm,
 
drm_dp_aux_register(>dm_dp_aux.aux);
drm_dp_cec_register_connector(>dm_dp_aux.aux,
- aconnector->base.name, dm->adev->dev);
+ >base);
aconnector->mst_mgr.cbs = _mst_cbs;
drm_dp_mst_topology_mgr_init(
>mst_mgr,
diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
index b15cee85b702..b457c16c3a8b 100644
--- a/drivers/gpu/drm/drm_dp_cec.c
+++ b/drivers/gpu/drm/drm_dp_cec.c
@@ -8,7 +8,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 /*
@@ -295,7 +297,10 @@ static void drm_dp_cec_unregister_work(struct work_struct 
*work)
  */
 void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
 {
-   u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
+   struct drm_connector *connector = aux->cec.connector;
+   u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
+  CEC_CAP_CONNECTOR_INFO;
+   struct cec_connector_info conn_info;
unsigned int num_las = 1;
u8 cap;
 
@@ -344,13 +349,17 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
struct edid *edid)
 
/* Create a new adapter */
aux->cec.adap = cec_allocate_adapter(_dp_cec_adap_ops,
-aux, aux->cec.name, cec_caps,
+aux, connector->name, cec_caps,
 num_las);
if (IS_ERR(aux->cec.adap)) {
aux->cec.adap = NULL;
goto unlock;
}
-   if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
+
+   cec_fill_conn_info_from_drm(_info, connector);
+   cec_s_conn_info(aux->cec.adap, _info);
+
+   if (cec_register_adapter(aux->cec.adap, connector->dev->dev)) {
cec_delete_adapter(aux->cec.adap);
aux->cec.adap = NULL;
} else {
@@ -406,22 +415,20 @@ EXPORT_SYMBOL(drm_dp_cec_unset_edid);
 /**
  * drm_dp_cec_register_connector() - register a new connector
  * @aux: DisplayPort AUX channel
- * @name: name of the CEC device
- * @parent: parent device
+ * @connector: drm connector
  *
  * A new connector was registered with associated CEC adapter name and
  * CEC adapter parent device. After registering the name and parent
  * drm_dp_cec_set_edid() is called to check if the connector supports
  * CEC and to register a CEC adapter if that is the case.
  */
-void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
-  struct device *parent)
+void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
+  struct drm_connector *connector)
 {
WARN_ON(aux->cec.adap);
if (WARN_ON(!aux->transfer))
return;
-   aux->cec.name = name;
-   aux->cec.parent = parent;
+   aux->cec.connector = connector;
INIT_DELAYED_WORK(>cec.unregister_work,
  drm_dp_cec_unregister_work);
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 560274d1c50b..1dfd16848e03 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5518,7 +5518,6 @@ static int
 intel_dp_connector_register(struct drm_connector *connector)
 {
struct intel_dp *intel_dp = intel_attached_dp(connector);
-   struct drm_device *dev = connector->dev;
int ret;
 
ret = intel_connector_register(connector);
@@ -5533,8 +5532,7 @@ intel_dp_connector_register(struct drm_connector 
*connector)
intel_dp->aux.dev = connector->kdev;
ret = drm_dp_aux_register(_dp->aux);
if (!ret)
-   drm_dp_cec_register_connector(_dp->aux,
- connector->name, dev->dev);
+   

[PATCHv8 05/13] cec: document CEC_ADAP_G_CONNECTOR_INFO

2019-06-24 Thread Hans Verkuil
Document the new CEC_ADAP_G_CONNECTOR_INFO ioctl.

Signed-off-by: Hans Verkuil 
---
 Documentation/media/uapi/cec/cec-funcs.rst|   1 +
 .../uapi/cec/cec-ioc-adap-g-conn-info.rst | 109 ++
 2 files changed, 110 insertions(+)
 create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst

diff --git a/Documentation/media/uapi/cec/cec-funcs.rst 
b/Documentation/media/uapi/cec/cec-funcs.rst
index 620590b168c9..dc6da9c639a8 100644
--- a/Documentation/media/uapi/cec/cec-funcs.rst
+++ b/Documentation/media/uapi/cec/cec-funcs.rst
@@ -24,6 +24,7 @@ Function Reference
 cec-ioc-adap-g-caps
 cec-ioc-adap-g-log-addrs
 cec-ioc-adap-g-phys-addr
+cec-ioc-adap-g-conn-info
 cec-ioc-dqevent
 cec-ioc-g-mode
 cec-ioc-receive
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst 
b/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
new file mode 100644
index ..87f475d7dfed
--- /dev/null
+++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
@@ -0,0 +1,109 @@
+.. SPDX-License-Identifier: GPL-2.0
+..
+.. Copyright 2019 Google LLC
+..
+.. This documentation is free software; you can redistribute it and/or
+.. modify it under the terms of the GNU General Public License
+.. version 2 as published by the Free Software Foundation.
+..
+.. This documentation is distributed in the hope that it will be useful,
+.. but WITHOUT ANY WARRANTY; without even the implied warranty of
+.. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.. GNU General Public License for more details.
+..
+.. _CEC_ADAP_G_CONNECTOR_INFO:
+
+***
+ioctl CEC_ADAP_G_CONNECTOR_INFO
+***
+
+Name
+
+
+CEC_ADAP_G_CONNECTOR_INFO - Query HDMI connector information
+
+Synopsis
+
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_G_CONNECTOR_INFO, struct 
cec_connector_info *argp )
+:name: CEC_ADAP_G_CONNECTOR_INFO
+
+Arguments
+=
+
+``fd``
+File descriptor returned by :c:func:`open() `.
+
+``argp``
+
+
+Description
+===
+
+Using this ioctl an application can learn which HDMI connector this CEC
+device corresponds to. While calling this ioctl the application should
+provide pointer to a cec_connector_info struct which will be populated
+by the kernel with the info provided by the adapter's driver. Not all
+drivers supply this information.
+
+.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}|
+
+.. c:type:: cec_connector_info
+
+.. flat-table:: struct cec_connector_info
+:header-rows:  0
+:stub-columns: 0
+:widths:   1 1 1 8
+
+* - __u32
+  - ``type``
+  - The type of connector this adapter is associated with.
+* - union
+  - ``(anonymous)``
+  -
+* -
+  - ``struct cec_drm_connector_info``
+  - drm
+  - :ref:`cec-drm-connector-info`.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. _connector-type:
+
+.. flat-table:: Connector types
+:header-rows:  0
+:stub-columns: 0
+:widths:   3 1 8
+
+* .. _`CEC-CONNECTOR-TYPE-NO-CONNECTOR`:
+
+  - ``CEC_CONNECTOR_TYPE_NO_CONNECTOR``
+  - 0
+  - No connector is associated with the adapter/the information is not 
provided by the driver.
+* .. _`CEC-CONNECTOR-TYPE-DRM`:
+
+  - ``CEC_CONNECTOR_TYPE_DRM``
+  - 1
+  - Indicates that a DRM connector is associated with this adapter. Info 
about the
+connector can be found in :ref:`cec-drm-connector-info`.
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. c:type:: cec_drm_connector_info
+
+.. _cec-drm-connector-info:
+
+.. flat-table:: struct cec_drm_connector_info
+:header-rows:  0
+:stub-columns: 0
+:widths:   3 1 8
+
+* .. _`CEC-DRM-CONNECTOR-TYPE-CARD-NO`:
+
+  - __u32
+  - ``card_no``
+  - DRM card number - the digit from a card's path, e.g. 0 in case of 
/dev/card0.
+* .. _`CEC-DRM-CONNECTOR-TYPE-CONNECTOR_ID`:
+
+  - __u32
-- 
2.20.1



[PATCHv8 01/13] cec-notifier: rename variable, check kstrdup

2019-06-24 Thread Hans Verkuil
dev -> hdmi_dev
conn -> conn_name

Also check the result of kstrdup, and clean up on error.

Signed-off-by: Hans Verkuil 
---
 drivers/media/cec/cec-notifier.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 9598c7778871..ce10dfd400bb 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -21,8 +21,8 @@ struct cec_notifier {
struct mutex lock;
struct list_head head;
struct kref kref;
-   struct device *dev;
-   const char *conn;
+   struct device *hdmi_dev;
+   const char *conn_name;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
 
@@ -32,14 +32,15 @@ struct cec_notifier {
 static LIST_HEAD(cec_notifiers);
 static DEFINE_MUTEX(cec_notifiers_lock);
 
-struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char 
*conn)
+struct cec_notifier *
+cec_notifier_get_conn(struct device *hdmi_dev, const char *conn_name)
 {
struct cec_notifier *n;
 
mutex_lock(_notifiers_lock);
list_for_each_entry(n, _notifiers, head) {
-   if (n->dev == dev &&
-   (!conn || !strcmp(n->conn, conn))) {
+   if (n->hdmi_dev == hdmi_dev &&
+   (!conn_name || !strcmp(n->conn_name, conn_name))) {
kref_get(>kref);
mutex_unlock(_notifiers_lock);
return n;
@@ -48,10 +49,17 @@ struct cec_notifier *cec_notifier_get_conn(struct device 
*dev, const char *conn)
n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n)
goto unlock;
-   n->dev = dev;
-   if (conn)
-   n->conn = kstrdup(conn, GFP_KERNEL);
+   n->hdmi_dev = hdmi_dev;
+   if (conn_name) {
+   n->conn_name = kstrdup(conn_name, GFP_KERNEL);
+   if (!n->conn_name) {
+   kfree(n);
+   n = NULL;
+   goto unlock;
+   }
+   }
n->phys_addr = CEC_PHYS_ADDR_INVALID;
+
mutex_init(>lock);
kref_init(>kref);
list_add_tail(>head, _notifiers);
@@ -67,7 +75,7 @@ static void cec_notifier_release(struct kref *kref)
container_of(kref, struct cec_notifier, kref);
 
list_del(>head);
-   kfree(n->conn);
+   kfree(n->conn_name);
kfree(n);
 }
 
-- 
2.20.1



[PATCHv8 00/13] cec: improve notifier support, add connector info

2019-06-24 Thread Hans Verkuil
This is a rework of Dariusz' v7 series:

https://www.spinics.net/lists/linux-media/msg151117.html

Rather than changing the existing CEC kAPI to allocate and
register CEC adapters I left it as-is. Instead new notifiers
functions are added to (un)register HDMI connector and CEC adapter
notifiers. These replace the current cec_notifier_get_conn and _put
functions.

For drivers that don't use notifiers the cec_s_conn_info function
was created so the connector info can be set directly as well.

This split in separate connector and CEC adapter functions is needed
since the notifier information is different between the two and this
makes it future proof since we will need to eventually support more
than one CEC adapter per HDMI connector.

By carefully designing these functions it is possible to convert
drivers to these new functions one-by-one, rather than as a painful
big-bang patch.

The plan is to merge the first three patches for kernel 5.3: these
patches provide the infrastructure needed by drm and cec drivers
to do the conversion during the 5.4 cycle, without requiring
patches that touch on multiple subsystems.

Once the conversion is done the new connector API can be exposed.
A patch documenting the new API is included as well, but it is
old and needs updating (the new CEC_CAP_CONNECTOR_INFO capability
isn't documented, and neither is the new 'have_connector_info'
field of the state changed event).

Various drivers have been converted as well as an example. These
are based on Dariusz' original series, but using the new notifier
functions.

Regards,

Hans

Dariusz Marcinkiewicz (9):
  cec: add struct cec_connector_info support
  cec: expose the new connector info API
  drm_dp_cec: add connector info support.
  drm/i915/intel_hdmi: use cec_notifier_conn_(un)register
  dw-hdmi-cec: use cec_notifier_cec_adap_(un)register
  dw-hdmi: use cec_notifier_conn_(un)register
  tda9950: use cec_notifier_cec_adap_(un)register
  tda998x: use cec_notifier_conn_(un)register
  drm/vc4/vc4_hdmi: fill in connector info

Hans Verkuil (4):
  cec-notifier: rename variable, check kstrdup
  cec: add new notifier functions
  cec: document CEC_ADAP_G_CONNECTOR_INFO
  meson/ao-cec: use cec_notifier_cec_adap_(un)register

 Documentation/media/uapi/cec/cec-funcs.rst|   1 +
 .../uapi/cec/cec-ioc-adap-g-conn-info.rst | 109 +
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   2 +-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c |   9 +-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 +---
 drivers/gpu/drm/drm_dp_cec.c  |  25 ++--
 drivers/gpu/drm/i2c/tda9950.c |  11 +-
 drivers/gpu/drm/i2c/tda998x_drv.c |  56 -
 drivers/gpu/drm/i915/intel_dp.c   |   4 +-
 drivers/gpu/drm/i915/intel_hdmi.c |  13 +-
 drivers/gpu/drm/nouveau/nouveau_connector.c   |   3 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c|  13 +-
 drivers/media/cec/cec-adap.c  |  31 +
 drivers/media/cec/cec-api.c   |  16 +++
 drivers/media/cec/cec-notifier.c  | 115 --
 drivers/media/platform/meson/ao-cec.c |  37 +++---
 include/drm/drm_dp_helper.h   |  14 +--
 include/media/cec-notifier.h  |  78 
 include/media/cec.h   |  19 +++
 include/uapi/linux/cec.h  |  33 +
 20 files changed, 550 insertions(+), 143 deletions(-)
 create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst

-- 
2.20.1



Re: [PATCH 1/7] video: add HDMI state notifier support

2019-06-11 Thread Hans Verkuil
On 6/11/19 2:10 PM, Cheng-yi Chiang wrote:
> On Tue, Jun 4, 2019 at 3:24 PM Daniel Vetter  wrote:
>>
>> On Tue, Jun 04, 2019 at 10:32:50AM +0800, Cheng-yi Chiang wrote:
>>> On Mon, Jun 3, 2019 at 4:09 PM Daniel Vetter  wrote:
>>>>
>>>> On Mon, Jun 03, 2019 at 09:45:49AM +0200, Hans Verkuil wrote:
>>>>> On 6/3/19 6:32 AM, Cheng-Yi Chiang wrote:
>>>>>> From: Hans Verkuil 
>>>>>>
>>>>>> Add support for HDMI hotplug and EDID notifiers, which is used to convey
>>>>>> information from HDMI drivers to their CEC and audio counterparts.
>>>>>>
>>>>>> Based on an earlier version from Russell King:
>>>>>>
>>>>>> https://patchwork.kernel.org/patch/9277043/
>>>>>>
>>>>>> The hdmi_notifier is a reference counted object containing the HDMI state
>>>>>> of an HDMI device.
>>>>>>
>>>>>> When a new notifier is registered the current state will be reported to
>>>>>> that notifier at registration time.
>>>>>>
>>>>>> Based on Hans Verkuil's patch:
>>>>>>
>>>>>> https://patchwork.kernel.org/patch/9472521/
>>>>>
>>>>> Erm, you are aware that this patch morphed into a CEC-specific notifier
>>>>> found in drivers/media/cec/cec-notifier.c?
>>>>>
>>>>> I don't think it makes sense to have two notifier implementations in the 
>>>>> kernel.
>>>>> The original intention was to have the notifier deal with both CEC and 
>>>>> ASoC
>>>>> notifications, but there was not enough interest for the ASoC bits at the 
>>>>> time
>>>>> and it was dropped.
>>>>>
>>>>> I am planning changes to the cec-notifier API, I hope to work on that this
>>>>> week. I'll CC you when I post those. Those might be a good starting point
>>>>> to convert the cec-notifier to an hdmi-notifier as was originally 
>>>>> intended.
>>>>>
>>>>> I've added your colleague Dariusz Marcinkiewicz to the CC list since he's 
>>>>> been
>>>>> working on some nice cec-notifier improvements as well.
>>>>
>>>> We also have some interfaces for drm/alsa interactions around hdmi
>>>> already in drm/drm_audio_component.h, but it's not used by anything
>>>> outside of i915. Imo we should extend that, not reinvent a new wheel.
>>>>
>>> Hi Daniel,
>>> Thank you for the pointer. Looking at the ops, it seems that it is
>>> specific to HDA.
>>> I am not familiar with drm and HDA. I am not sure how applicable it
>>> would be to report jack status to ASoC.
>>> There is a use case in sound/soc/codecs/hdac_hdmi.c though so it
>>> should be possible.
>>
>> Currently hda is the only user, but the idea was to make it more generic.
>> Jack status in alsa is what drm calls connector status btw.
>>
>> So if we can take that as a baseline and extend it (probably needs some
>> registration boilerplate and helpers to look up the right endpoint using
>> of/dt for soc systems, we use component.c in i915/hda for this), that
>> would be great I think.
>>
>>>> Another note: notifiers considered evil, imo. Gets the job done for one
>>>> case, as soon as you have multiple devices and need to make sure you get
>>>> the update for the right one it all comes crashing down. Please create an
>>>> api which registers for updates from a specific device only, plus
>>>> something that has real callbacks (like the drm_audio_component.h thing we
>>>> started already).
>>>
>>> To clarify a bit, this hdmi-notifier indeed supports updating from a
>>> specific device only.
>>> hdmi_notifier_get takes a device and return the notifier.
>>
>> Hm I missed that, I thought it's global, so one of my usual notifier
>> concerns addressed.
>>
>>> It seems that a major difference between drm_audio_components and
>>> hdmi-notifier is that
>>> drm_audio_components defines all supported ops in 
>>> drm_audio_component_audio_ops.
>>> On the other hand, hdmi-notifier passes different events using an enum
>>> like HDMI_CONNECTED and let listener handle different events.
>>> In this regard I agree with you that drm_audio_component is cleaner.
>>> Anyway, I will look into it a bit more and see 

Re: [PATCH 5/8] drivers: media: coda: fix warning same module names

2019-06-11 Thread Hans Verkuil
On 6/11/19 10:15 AM, Philipp Zabel wrote:
> Hi,
> 
> On Mon, 2019-06-10 at 13:14 +, Matt Redfearn wrote:
>>
>> On 10/06/2019 14:03, Anders Roxell wrote:
>>> On Thu, 6 Jun 2019 at 12:13, Hans Verkuil  wrote:
>>>>
>>>> On 6/6/19 11:47 AM, Anders Roxell wrote:
>>>>> When building with CONFIG_VIDEO_CODA and CONFIG_CODA_FS enabled as
>>>>> loadable modules, we see the following warning:
>>>>>
>>>>> warning: same module names found:
>>>>>fs/coda/coda.ko
>>>>>drivers/media/platform/coda/coda.ko
>>>>>
>>>>> Rework so media coda matches the config fragment. Leaving CODA_FS as is
>>>>> since thats a well known module.
>>>>>
>>>>> Signed-off-by: Anders Roxell 
>>>>> ---
>>>>>   drivers/media/platform/coda/Makefile | 4 ++--
>>>>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/media/platform/coda/Makefile 
>>>>> b/drivers/media/platform/coda/Makefile
>>>>> index 54e9a73a92ab..588e6bf7c190 100644
>>>>> --- a/drivers/media/platform/coda/Makefile
>>>>> +++ b/drivers/media/platform/coda/Makefile
>>>>> @@ -1,6 +1,6 @@
>>>>>   # SPDX-License-Identifier: GPL-2.0-only
>>>>>
>>>>> -coda-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o 
>>>>> coda-mpeg2.o coda-mpeg4.o coda-jpeg.o
>>>>> +video-coda-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o 
>>>>> coda-mpeg2.o coda-mpeg4.o coda-jpeg.o
>>>>>
>>>>> -obj-$(CONFIG_VIDEO_CODA) += coda.o
>>>>> +obj-$(CONFIG_VIDEO_CODA) += video-coda.o
>>>>
>>>> How about imx-coda? video-coda suggests it is part of the video subsystem,
>>>> which it isn't.
>>>
>>> I'll resend a v2 shortly with imx-coda instead.
> 
> I'd be in favor of calling it "coda-vpu" instead.

Fine by me!

> 
>> What about other vendor SoCs implementing the Coda IP block which are 
>> not an imx? I'd prefer a more generic name - maybe media-coda.
> 
> Right, this driver can be used on other SoCs [1].

Good point.

Regards,

Hans

> 
> [1] https://www.mail-archive.com/linux-media@vger.kernel.org/msg146498.html
> 
> regards
> Philipp
> 



Re: [PATCH 5/8] drivers: media: coda: fix warning same module names

2019-06-06 Thread Hans Verkuil
On 6/6/19 11:47 AM, Anders Roxell wrote:
> When building with CONFIG_VIDEO_CODA and CONFIG_CODA_FS enabled as
> loadable modules, we see the following warning:
> 
> warning: same module names found:
>   fs/coda/coda.ko
>   drivers/media/platform/coda/coda.ko
> 
> Rework so media coda matches the config fragment. Leaving CODA_FS as is
> since thats a well known module.
> 
> Signed-off-by: Anders Roxell 
> ---
>  drivers/media/platform/coda/Makefile | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/coda/Makefile 
> b/drivers/media/platform/coda/Makefile
> index 54e9a73a92ab..588e6bf7c190 100644
> --- a/drivers/media/platform/coda/Makefile
> +++ b/drivers/media/platform/coda/Makefile
> @@ -1,6 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  
> -coda-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o coda-mpeg2.o 
> coda-mpeg4.o coda-jpeg.o
> +video-coda-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o 
> coda-mpeg2.o coda-mpeg4.o coda-jpeg.o
>  
> -obj-$(CONFIG_VIDEO_CODA) += coda.o
> +obj-$(CONFIG_VIDEO_CODA) += video-coda.o

How about imx-coda? video-coda suggests it is part of the video subsystem,
which it isn't.

Regards,

Hans

>  obj-$(CONFIG_VIDEO_IMX_VDOA) += imx-vdoa.o
> 



Re: [PATCH 4/8] drivers: media: i2c: fix warning same module names

2019-06-06 Thread Hans Verkuil
On 6/6/19 11:47 AM, Anders Roxell wrote:
> When building with CONFIG_VIDEO_ADV7511 and CONFIG_DRM_I2C_ADV7511
> enabled as loadable modules, we see the following warning:
> 
> warning: same module names found:
>   drivers/gpu/drm/bridge/adv7511/adv7511.ko
>   drivers/media/i2c/adv7511.ko
> 
> Rework so the names matches the config fragment.
> 
> Signed-off-by: Anders Roxell 

Change it in media, not in drm. The v4l2 adv7511 is rarely used, so it
makes sense to rename that, and not this drm driver.

> ---
> This is only one issue that have been addressed.
> The other issue is that itseems to refer to the same device name in
> i2c_device_id, any guidance how that should be solved?

You should never have both modules loaded. In fact, I think it is a good
idea to disable VIDEO_ADV7511 if DRM_I2C_ADV7511 is set in the Kconfig,
unless TEST_COMPILE is also set.

Regards,

Hans

> 
> 
> Cheers,
> Anders
> 
>  drivers/gpu/drm/bridge/adv7511/Makefile | 10 +-
>  drivers/media/i2c/Makefile  |  3 ++-
>  2 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/Makefile 
> b/drivers/gpu/drm/bridge/adv7511/Makefile
> index b46ebeb35fd4..e367426bd73e 100644
> --- a/drivers/gpu/drm/bridge/adv7511/Makefile
> +++ b/drivers/gpu/drm/bridge/adv7511/Makefile
> @@ -1,6 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> -adv7511-y := adv7511_drv.o
> -adv7511-$(CONFIG_DRM_I2C_ADV7511_AUDIO) += adv7511_audio.o
> -adv7511-$(CONFIG_DRM_I2C_ADV7511_CEC) += adv7511_cec.o
> -adv7511-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o
> -obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
> +drm-i2c-adv7511-y := adv7511_drv.o
> +drm-i2c-adv7511-$(CONFIG_DRM_I2C_ADV7511_AUDIO) += adv7511_audio.o
> +drm-i2c-adv7511-$(CONFIG_DRM_I2C_ADV7511_CEC) += adv7511_cec.o
> +drm-i2c-adv7511-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o
> +obj-$(CONFIG_DRM_I2C_ADV7511) += drm-i2c-adv7511.o
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index d8ad9dad495d..b71a427a89fd 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -35,7 +35,8 @@ obj-$(CONFIG_VIDEO_ADV748X) += adv748x/
>  obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
>  obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o
>  obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
> -obj-$(CONFIG_VIDEO_ADV7511) += adv7511.o
> +obj-$(CONFIG_VIDEO_ADV7511) += video-adv7511.o
> +video-adv7511-objs  := adv7511.o
>  obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
>  obj-$(CONFIG_VIDEO_VS6624)  += vs6624.o
>  obj-$(CONFIG_VIDEO_BT819) += bt819.o
> 



Re: [PATCH 1/7] video: add HDMI state notifier support

2019-06-03 Thread Hans Verkuil
On 6/3/19 10:09 AM, Daniel Vetter wrote:
> On Mon, Jun 03, 2019 at 09:45:49AM +0200, Hans Verkuil wrote:
>> On 6/3/19 6:32 AM, Cheng-Yi Chiang wrote:
>>> From: Hans Verkuil 
>>>
>>> Add support for HDMI hotplug and EDID notifiers, which is used to convey
>>> information from HDMI drivers to their CEC and audio counterparts.
>>>
>>> Based on an earlier version from Russell King:
>>>
>>> https://patchwork.kernel.org/patch/9277043/
>>>
>>> The hdmi_notifier is a reference counted object containing the HDMI state
>>> of an HDMI device.
>>>
>>> When a new notifier is registered the current state will be reported to
>>> that notifier at registration time.
>>>
>>> Based on Hans Verkuil's patch:
>>>
>>> https://patchwork.kernel.org/patch/9472521/
>>
>> Erm, you are aware that this patch morphed into a CEC-specific notifier
>> found in drivers/media/cec/cec-notifier.c?
>>
>> I don't think it makes sense to have two notifier implementations in the 
>> kernel.
>> The original intention was to have the notifier deal with both CEC and ASoC
>> notifications, but there was not enough interest for the ASoC bits at the 
>> time
>> and it was dropped.
>>
>> I am planning changes to the cec-notifier API, I hope to work on that this
>> week. I'll CC you when I post those. Those might be a good starting point
>> to convert the cec-notifier to an hdmi-notifier as was originally intended.
>>
>> I've added your colleague Dariusz Marcinkiewicz to the CC list since he's 
>> been
>> working on some nice cec-notifier improvements as well.
> 
> We also have some interfaces for drm/alsa interactions around hdmi
> already in drm/drm_audio_component.h, but it's not used by anything
> outside of i915. Imo we should extend that, not reinvent a new wheel.

If that can be used instead of this hdmi-notifier, then that's fine by me.

> Another note: notifiers considered evil, imo. Gets the job done for one
> case, as soon as you have multiple devices and need to make sure you get
> the update for the right one it all comes crashing down. Please create an
> api which registers for updates from a specific device only, plus
> something that has real callbacks (like the drm_audio_component.h thing we
> started already).

For CEC the notifier works very well. But CEC has some special requirements
that ASoC doesn't have:

- The cec-notifier can be used by both HDMI transmitters and receivers (so
has to work with two different subsystems).

- There may be multiple CEC devices connected to one HDMI transmitter: one
that is used when the system is in Standby, and a more capable CEC device
used when the system is powered up. This isn't supported yet, but it is likely
that we'll need this.

- HDMI and CEC devices are often completely independent and one or the other
(or both) can be unbound at any time. A real-world example is when an FPGA
containing the HDMI and/or CEC support is unloaded to save power when in 
standby.

- In some cases you want to register a CEC device via a notifier to an HDMI
connector based on userspace information. E.g. the popular USB Pulse-Eight CEC
device can be connected to any HDMI output by the user, there is no way to know
this in the kernel. An application that knows about the Pulse-Eight currently
has to parse the EDID and set the Physical Address of the Pulse-Eight 
accordingly.
I want to make it possible that the user can just tell the Pulse-Eight which 
HDMI
output is used and have it connect to that output using the notifier. I have a
proof-of-concept, but this needs Dariusz' series to make it work.

Regards,

Hans

> -Daniel
> 
>>
>> Regards,
>>
>>  Hans
>>
>>>
>>> Modified by Cheng-Yi Chiang:
>>>  - Add a section in MAINTAINER.
>>>  - Changes connected and has_eld to bitfield of unsigned int.
>>>  - Other minor fixes to pass checkpatch.pl --strict checks.
>>>
>>> Signed-off-by: Hans Verkuil 
>>> Acked-by: Philipp Zabel 
>>> Signed-off-by: Cheng-Yi Chiang 
>>> ---
>>> The original patch is at
>>> https://lore.kernel.org/linux-arm-kernel/20161213150813.37966-2-hverk...@xs4all.nl
>>>
>>>  MAINTAINERS   |   6 ++
>>>  drivers/video/Kconfig |   3 +
>>>  drivers/video/Makefile|   1 +
>>>  drivers/video/hdmi-notifier.c | 145 ++
>>>  include/linux/hdmi-notifier.h | 112 ++
>>>  5 files changed, 267 insertions(+)
>>>  create mode 100644 drivers/video/hdmi-notifier.c
>>>  create mode 100644 include/li

Re: [PATCH 1/7] video: add HDMI state notifier support

2019-06-03 Thread Hans Verkuil
On 6/3/19 6:32 AM, Cheng-Yi Chiang wrote:
> From: Hans Verkuil 
> 
> Add support for HDMI hotplug and EDID notifiers, which is used to convey
> information from HDMI drivers to their CEC and audio counterparts.
> 
> Based on an earlier version from Russell King:
> 
> https://patchwork.kernel.org/patch/9277043/
> 
> The hdmi_notifier is a reference counted object containing the HDMI state
> of an HDMI device.
> 
> When a new notifier is registered the current state will be reported to
> that notifier at registration time.
> 
> Based on Hans Verkuil's patch:
> 
> https://patchwork.kernel.org/patch/9472521/

Erm, you are aware that this patch morphed into a CEC-specific notifier
found in drivers/media/cec/cec-notifier.c?

I don't think it makes sense to have two notifier implementations in the kernel.
The original intention was to have the notifier deal with both CEC and ASoC
notifications, but there was not enough interest for the ASoC bits at the time
and it was dropped.

I am planning changes to the cec-notifier API, I hope to work on that this
week. I'll CC you when I post those. Those might be a good starting point
to convert the cec-notifier to an hdmi-notifier as was originally intended.

I've added your colleague Dariusz Marcinkiewicz to the CC list since he's been
working on some nice cec-notifier improvements as well.

Regards,

Hans

> 
> Modified by Cheng-Yi Chiang:
>  - Add a section in MAINTAINER.
>  - Changes connected and has_eld to bitfield of unsigned int.
>  - Other minor fixes to pass checkpatch.pl --strict checks.
> 
> Signed-off-by: Hans Verkuil 
> Acked-by: Philipp Zabel 
> Signed-off-by: Cheng-Yi Chiang 
> ---
> The original patch is at
> https://lore.kernel.org/linux-arm-kernel/20161213150813.37966-2-hverk...@xs4all.nl
> 
>  MAINTAINERS   |   6 ++
>  drivers/video/Kconfig |   3 +
>  drivers/video/Makefile|   1 +
>  drivers/video/hdmi-notifier.c | 145 ++
>  include/linux/hdmi-notifier.h | 112 ++
>  5 files changed, 267 insertions(+)
>  create mode 100644 drivers/video/hdmi-notifier.c
>  create mode 100644 include/linux/hdmi-notifier.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5cfbea4ce575..ffb7376f9509 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16676,6 +16676,12 @@ W:   https://linuxtv.org
>  S:   Maintained
>  F:   drivers/media/platform/vicodec/*
>  
> +VIDEO FRAMEWORK
> +M:   Hans Verkuil 
> +L:   linux-me...@vger.kernel.org
> +F:   drivers/video/hdmi-notifier.*
> +S:   Maintained
> +
>  VIDEO MULTIPLEXER DRIVER
>  M:   Philipp Zabel 
>  L:   linux-me...@vger.kernel.org
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 83d3d271ca15..000ba9bc0ae7 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -34,6 +34,9 @@ config VIDEOMODE_HELPERS
>  config HDMI
>   bool
>  
> +config HDMI_NOTIFIERS
> + bool
> +
>  endif # HAS_IOMEM
>  
>  if VT
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index df7650adede9..eff4736102ca 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_VGASTATE)+= vgastate.o
>  obj-$(CONFIG_HDMI)+= hdmi.o
> +obj-$(CONFIG_HDMI_NOTIFIERS)  += hdmi-notifier.o
>  
>  obj-$(CONFIG_VT)   += console/
>  obj-$(CONFIG_FB_STI)   += console/
> diff --git a/drivers/video/hdmi-notifier.c b/drivers/video/hdmi-notifier.c
> new file mode 100644
> index ..d1eedf661648
> --- /dev/null
> +++ b/drivers/video/hdmi-notifier.c
> @@ -0,0 +1,145 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* hdmi-notifier.c - notify interested parties of (dis)connect and EDID
> + * events
> + *
> + * Copyright 2016 Russell King 
> + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates.
> + * All rights reserved.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +static LIST_HEAD(hdmi_notifiers);
> +static DEFINE_MUTEX(hdmi_notifiers_lock);
> +
> +struct hdmi_notifier *hdmi_notifier_get(struct device *dev)
> +{
> + struct hdmi_notifier *n;
> +
> + mutex_lock(_notifiers_lock);
> + list_for_each_entry(n, _notifiers, head) {
> + if (n->dev == dev) {
> + mutex_unlock(_notifiers_lock);
> + kref_get(>kref);
> + return n;
> + }
> + }
> + n = kzalloc(sizeof(*n), GFP_KERNEL);
> + if (!n)
> + goto unlock;
> + n->dev = dev;
> + mutex_init(>lock);
> + 

Re: [PATCH 00/20] drm: Split out the formats API and move it to a common place

2019-05-02 Thread Hans Verkuil
Hi Maxime,

Apologies for the late reply, most if this thread happened when I was on
vacation, and I missed that I should reply to it. Thank you for reminding
me.

Please let me know if I should reply to other mails in the discussion of
this patch series.

On 4/18/19 10:56 PM, Maxime Ripard wrote:
> On Thu, Apr 18, 2019 at 02:32:14PM +0200, Daniel Vetter wrote:
>> Unifying the formats themselves, and all the associated metadata is
>> imo a no-go, and was a pretty conscious decision when we implemented
>> drm_fourcc a few years back.
>>
>>> If we want to keep the current library in DRM, we have two options
>>> then:
>>>
>>>   - Support all the v4l2 formats in the DRM library, which is
>>> essentially what I'm doing in the last patches. However, that
>>> would require to have the v4l2 developpers also reviewing stuff
>>> there. And given how busy they are, I cannot really see how that
>>> would work.
>>
>> Well, if we end up with a common library then yes we need cross
>> review. There's no way around that. Doesn't matter where exactly that
>> library is in the filesystem tree, and adding a special MAINTAINERS
>> entry for anything related to fourcc (both drm and v4l) to make sure
>> they get cross-posted is easy. No file renaming needed.
>
> That would create some governing issues as well. For example, if you
> ever have a patch from one fourcc addition (that might or might not be
> covered by v4l2), will you wait for any v4l2 developper to review it?

 None of this is fixed by code renaming or locations. Either way we
 need to figure that out.

 And yes part of the reasons for not moving this out of drm is that I'm
 not a fan of boutique trees for small stuff. If sharing means we need
 to split the drm_fourcc code and library out of drm trees, I'm not
 sure that's a good idea. We're already super liberal with merging
 anything through driver trees with acks, and integrating them quickly
 into drm-next. This would still be workable if v4l sends regular pull
 requests to drm-next (every 1-2 weeks, like the other big gpu trees
 do). If we can only sync up once per merge window with a shared
 boutique tree for formats only, life is going to be painful.
>>>
>>> I don't get why we want to turn DRM into some kind of a black hole
>>> that would pull everything. We don't have to, really. And at the same
>>> time it carries the message that v4l2 is less important than DRM for
>>> some reason, which I'm really not comfortable with.
>>
>> Make another tree somewhere that pulls in trees more often than every
>> merge window, and I'm happy. It's the coordination effort of lots of
>> trees that creates the black hole, not the other way round. Yes topic
>> trees work, but if topic trees are persistent something with the
>> organization of trees is wrong and needs to change. This very much
>> looks like we'll end up with a perpetual topic branch for format stuff
>> between drm and v4l.
> 
> Well, if v4l2 sends a PR to DRM every 1 or 2 weeks, that definitely
> looks like a topic branch to me. And on a far more frequent basis than
> when we will merge a format description.
> 
>> The other shared stuff (like hdmi infoframes) seems to change a lot
>> less often, so the occasional patch hasn't been a pain. But drm_fourcc
>> related stuff sees a lot of work, both in adding new formats and in
>> refactoring the library to keep up with all the new use-cases.
> 
> When was the last time a refactoring that changed the API happened?
> 
> Most of the changes will be new format descriptions, and I guess that
> would only concern a single tree.
> 
> And really, we're doing this all the time, so I'm not sure what the
> big deal is here.
> 
> I feel like there's something that you don't really like about this,
> but you're not saying this out loud.
> 
> Sure, the exact process needs to be figured out, and everyone needs to
> agree upon that process. But that's pretty much it, and it's nothing
> out of the ordinary.
> 
>> And yes I think an overall gfx-like-stuff.git tree for drm and v4l and
>> the few other bits really makes tons of sense. Not as a tree where
>> people commit, but as the 2nd-level integration tree (like drm.git
>> right now for gpu stuff).
>>
>>> And I don't really get why you're against this in the first
>>> place. When you have some code in a single driver that would benefit
>>> more driver, you create a helper and move it into the core.
>>
>> It's a feature that drm doesn't share that much code with other parts
>> of the kernel, it makes backporting the gfx stack to lts kernels a lot
>> easier. Until someone fixes the upstream kernel release model to no
>> longer need large scale gpu driver backports, we need to keep that.
>>
>>> In this case, we have some code used by a framework that more
>>> framework could use, and we move it to a core-er place. How is that
>>> 

  1   2   3   4   5   6   7   8   9   10   >