media: cec: expose HDMI connector to CEC dev mapping
Subsystems (16)
PATCH v6 1/3 media: cec: expose HDMI connector to CEC dev mapping
This patch proposes to expose explicit mapping between HDMI connectors and /dev/cecX adapters to userland.
New structure with connector info (card number and connector id in case of DRM connectors) is added to cec_adapter. That connector info is expected to be provided when an adapter is created.
CEC notifier is extended so that it can be used to communicate the connector's info to CEC adapters' creators.
New ioctl, exposing connector info to userland, is added to /dev/cec.
Changes since v5:
- make the patch apply against the latest changes in the affected code
Changes since v4:
- small tweaks + added documentation
Changes since v3:
- cec_get_connter_conn takes connector_info as argument
Changes since v2:
- cec_s_connector_info removed, the connector info is now passed to cec_allocate_adapter
- updated commit message
Changes since v1:
- removed the unnecessary event,
- extended cec_connctor_info to allow for various types of connectors.
--- Documentation/media/kapi/cec-core.rst | 7 +- 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/adv7511/adv7511_cec.c | 3 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 2 +- drivers/gpu/drm/drm_dp_cec.c | 22 ++-- drivers/gpu/drm/i2c/tda9950.c | 3 +- drivers/gpu/drm/i915/intel_dp.c | 4 +- drivers/gpu/drm/i915/intel_hdmi.c | 6 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 +- drivers/media/cec/cec-adap.c | 13 +++ drivers/media/cec/cec-api.c | 12 ++ drivers/media/cec/cec-core.c | 8 +- drivers/media/cec/cec-notifier.c | 20 +++- drivers/media/cec/cec-pin.c | 2 +- drivers/media/i2c/tc358743.c | 3 +- .../media/platform/cros-ec-cec/cros-ec-cec.c | 7 +- drivers/media/platform/meson/ao-cec.c | 6 +- drivers/media/platform/s5p-cec/s5p_cec.c | 6 +- drivers/media/platform/seco-cec/seco-cec.c | 8 +- drivers/media/platform/sti/cec/stih-cec.c | 6 +- drivers/media/platform/stm32/stm32-cec.c | 2 +- drivers/media/platform/tegra-cec/tegra_cec.c | 5 +- drivers/media/platform/vivid/vivid-cec.c | 2 +- drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +- .../media/usb/rainshadow-cec/rainshadow-cec.c | 3 +- include/drm/drm_dp_helper.h | 14 +-- include/media/cec-notifier.h | 34 ++++-- include/media/cec.h | 16 ++- include/uapi/linux/cec.h | 24 ++++ 32 files changed, 310 insertions(+), 54 deletions(-) create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
Documentation/media/kapi/cec-core.rst +6 -1
@@ -37,7 +37,8 @@ calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): .. c:function:: struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, - const char *name, u32 caps, u8 available_las); + const char *name, u32 caps, u8 available_las, + const struct cec_connector_info *connector_info); .. c:function:: void cec_delete_adapter(struct cec_adapter *adap);
@@ -65,6 +66,10 @@ available_las: the number of simultaneous logical addresses that this adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. +connector_info: + pointer to a struct describing connector this adapter is associated with, + can be NULL. + To obtain the priv pointer use this helper function: .. c:function::
Documentation/media/uapi/cec/cec-funcs.rst +1 -0
@@ -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
Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst new file +109 -0
109 lines not on this page · raw message
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +1 -1
@@ -394,7 +394,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,drm_dp_aux_register (&aconnector->dm_dp_aux.aux);drm_dp_cec_register_connector (&aconnector->dm_dp_aux.aux, - aconnector->base.name, dm->adev->dev); + &aconnector->base); aconnector->mst_mgr.cbs = &dm_mst_cbs; drm_dp_mst_topology_mgr_init( &aconnector->mst_mgr,
drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +2 -1
@@ -310,7 +310,8 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) goto err_cec_parse_dt; adv7511->cec_adap =cec_allocate_adapter (&adv7511_cec_adap_ops, - adv7511,dev_name (dev),CEC_CAP_DEFAULTS ,ADV7511_MAX_ADDRS ); + adv7511,dev_name (dev),CEC_CAP_DEFAULTS ,ADV7511_MAX_ADDRS , +NULL );if (IS_ERR (adv7511->cec_adap)) { ret =PTR_ERR (adv7511->cec_adap); goto err_cec_alloc;
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +1 -1
@@ -261,7 +261,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );if (IS_ERR (cec->adap))return PTR_ERR (cec->adap);
drivers/gpu/drm/drm_dp_cec.c +13 -9
@@ -8,7 +8,9 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <drm/drm_connector.h> #include <drm/drm_dp_helper.h> +#include <drm/drmP.h> #include <media/cec.h> /*
@@ -295,7 +297,9 @@ 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) { +struct drm_connector *connector = aux->cec.connector;u32 cec_caps =CEC_CAP_DEFAULTS |CEC_CAP_NEEDS_HPD ; +struct cec_connector_info conn_info;unsigned int num_las =1 ;u8 cap;
@@ -342,15 +346,17 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)cec_unregister_adapter (aux->cec.adap); } +cec_fill_connector_info (&conn_info, connector); +/* Create a new adapter */ aux->cec.adap =cec_allocate_adapter (&drm_dp_cec_adap_ops, - aux, aux->cec.name, cec_caps, - num_las); + aux, connector->name, cec_caps, + num_las, &conn_info);if (IS_ERR (aux->cec.adap)) { aux->cec.adap =NULL ; goto unlock; } -if (cec_register_adapter (aux->cec.adap, aux->cec.parent)) { +if (cec_register_adapter (aux->cec.adap, connector->dev->dev)) {cec_delete_adapter (aux->cec.adap); aux->cec.adap =NULL ; }else {
@@ -406,22 +412,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 (&aux->cec.unregister_work, drm_dp_cec_unregister_work); }
drivers/gpu/drm/i2c/tda9950.c +2 -1
@@ -424,7 +424,8 @@ static int tda9950_probe(struct i2c_client *client, priv->adap =cec_allocate_adapter (&tda9950_cec_ops, priv,"tda9950" ,CEC_CAP_DEFAULTS , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS , +NULL );if (IS_ERR (priv->adap))return PTR_ERR (priv->adap);
drivers/gpu/drm/i915/intel_dp.c +1 -3
@@ -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 (&intel_dp->aux);if (!ret) -drm_dp_cec_register_connector (&intel_dp->aux, - connector->name, dev->dev); +drm_dp_cec_register_connector (&intel_dp->aux, connector);return ret; }
drivers/gpu/drm/i915/intel_hdmi.c +5 -1
@@ -2968,6 +2968,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 +3021,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,I915_WRITE (PEG_BAND_GAP_DATA , (temp & ~0xf ) |0xd ); } +cec_fill_connector_info (&conn_info, connector); + intel_hdmi->cec_notifier =cec_notifier_get_conn (dev->dev, -port_identifier (port)); +port_identifier (port), + &conn_info);if (!intel_hdmi->cec_notifier)DRM_DEBUG_KMS ("CEC notifier get failed\n" ); }
drivers/gpu/drm/nouveau/nouveau_connector.c +1 -2
@@ -1413,8 +1413,7 @@ nouveau_connector_create(struct drm_device *dev,switch (type) {case DRM_MODE_CONNECTOR_DisplayPort:case DRM_MODE_CONNECTOR_eDP: -drm_dp_cec_register_connector (&nv_connector->aux, - connector->name, dev->dev); +drm_dp_cec_register_connector (&nv_connector->aux, connector);break ; }
drivers/gpu/drm/vc4/vc4_hdmi.c +7 -1
@@ -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;
@@ -1395,12 +1398,15 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) goto err_destroy_encoder; }#ifdef CONFIG_DRM_VC4_HDMI_CEC +cec_fill_connector_info (&conn_info, hdmi->connector); + hdmi->cec_adap =cec_allocate_adapter (&vc4_hdmi_cec_adap_ops, vc4,"vc4" ,CEC_CAP_TRANSMIT |CEC_CAP_LOG_ADDRS |CEC_CAP_PASSTHROUGH | -CEC_CAP_RC ,1 ); +CEC_CAP_RC ,1 , + &conn_info); ret =PTR_ERR_OR_ZERO (hdmi->cec_adap);if (ret <0 ) goto err_destroy_conn;
drivers/media/cec/cec-adap.c +13 -0
@@ -16,7 +16,10 @@#include <linux/string.h> #include <linux/types.h> +#include <drm/drm_connector.h> +#include <drm/drm_device.h> #include <drm/drm_edid.h> +#include <drm/drm_file.h> #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_connector_info (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_connector_info); +/* * Queue a new event for this filehandle. If ts == 0, then set it * to the current time.
drivers/media/cec/cec-api.c +12 -0
@@ -187,6 +187,15 @@ 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 (copy_to_user (parg, &adap->connector_info, +sizeof (adap->connector_info))) +return -EFAULT ; +return 0 ; +} +static long cec_transmit (struct cec_adapter *adap,struct cec_fh *fh,bool block,struct cec_msg __user *parg) {
@@ -514,6 +523,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);
drivers/media/cec/cec-core.c +6 -2
@@ -250,8 +250,9 @@ static const struct file_operations cec_error_inj_fops = {#endif struct cec_adapter *cec_allocate_adapter (const struct cec_adap_ops *ops, -void *priv,const char *name,u32 caps, -u8 available_las) +void *priv,const char *name,u32 caps, +u8 available_las, +const struct cec_connector_info *connector_info) {struct cec_adapter *adap;int res;
@@ -288,6 +289,9 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,INIT_LIST_HEAD (&adap->wait_queue);init_waitqueue_head (&adap->kthread_waitq); +if (connector_info) + adap->connector_info = *connector_info; +/* adap->devnode initialization */ INIT_LIST_HEAD (&adap->devnode.fhs);mutex_init (&adap->devnode.lock);
drivers/media/cec/cec-notifier.c +18 -2
@@ -27,12 +27,16 @@ struct cec_notifier {void (*callback)(struct cec_adapter *adap,u16 pa);u16 phys_addr; +struct cec_connector_info connector_info; };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 *dev, +const char *conn, +const struct cec_connector_info *connector_info) {struct cec_notifier *n;
@@ -52,6 +56,10 @@ struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn)if (conn) n->conn =kstrdup (conn,GFP_KERNEL ); n->phys_addr =CEC_PHYS_ADDR_INVALID ; + +if (connector_info) + n->connector_info = *connector_info; +mutex_init (&n->lock);kref_init (&n->kref);list_add_tail (&n->head, &cec_notifiers);
@@ -107,9 +115,17 @@ void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, }EXPORT_SYMBOL_GPL (cec_notifier_set_phys_addr_from_edid); +const struct cec_connector_info *cec_notifier_get_conn_info ( +struct cec_notifier *n) +{ +return &n->connector_info; +} +EXPORT_SYMBOL_GPL (cec_notifier_get_conn_info); +void cec_notifier_register (struct cec_notifier *n,struct cec_adapter *adap, -void (*callback)(struct cec_adapter *adap,u16 pa)) +void (*callback)(struct cec_adapter *adap, +u16 pa)) {kref_get (&n->kref);mutex_lock (&n->lock);
drivers/media/cec/cec-pin.c +1 -1
@@ -1320,7 +1320,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, adap =cec_allocate_adapter (&cec_pin_adap_ops, priv, name, caps |CEC_CAP_MONITOR_ALL |CEC_CAP_MONITOR_PIN , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );if (IS_ERR (adap)) {kfree (pin);
drivers/media/i2c/tc358743.c +2 -1
@@ -2117,7 +2117,8 @@ static int tc358743_probe(struct i2c_client *client,#ifdef CONFIG_VIDEO_TC358743_CEC state->cec_adap =cec_allocate_adapter (&tc358743_cec_adap_ops, state,dev_name (&client->dev), -CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL ,CEC_MAX_LOG_ADDRS ); +CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL ,CEC_MAX_LOG_ADDRS , +NULL );if (IS_ERR (state->cec_adap)) { err =PTR_ERR (state->cec_adap); goto err_hdl;
drivers/media/platform/cros-ec-cec/cros-ec-cec.c +5 -2
@@ -235,7 +235,7 @@ static int cros_ec_cec_get_notifier(struct device *dev,if (!d)return -EPROBE_DEFER ; - *notify =cec_notifier_get_conn (d, m->conn); + *notify =cec_notifier_get_conn (d, m->conn,NULL );put_device (d);return 0 ; }
@@ -261,6 +261,7 @@ static int cros_ec_cec_probe(struct platform_device *pdev) {struct cros_ec_dev *ec_dev =dev_get_drvdata (pdev->dev.parent);struct cros_ec_device *cros_ec = ec_dev->ec_dev; +const struct cec_connector_info *conn_info;struct cros_ec_cec *cros_ec_cec;int ret;
@@ -282,8 +283,10 @@ static int cros_ec_cec_probe(struct platform_device *pdev)return ret; } + conn_info =cec_notifier_get_conn_info (cros_ec_cec->notify); + cros_ec_cec->adap =cec_allocate_adapter (&cros_ec_cec_ops, cros_ec_cec, -DRV_NAME ,CEC_CAP_DEFAULTS ,1 ); +DRV_NAME ,CEC_CAP_DEFAULTS ,1 , conn_info);if (IS_ERR (cros_ec_cec->adap))return PTR_ERR (cros_ec_cec->adap);
drivers/media/platform/meson/ao-cec.c +5 -1
@@ -600,6 +600,7 @@ static const struct cec_adap_ops meson_ao_cec_ops = {static int meson_ao_cec_probe (struct platform_device *pdev) { +const struct cec_connector_info *conn_info;struct meson_ao_cec_device *ao_cec;struct device *hdmi_dev;struct resource *res;
@@ -620,13 +621,16 @@ static int meson_ao_cec_probe(struct platform_device *pdev)if (!ao_cec->notify)return -ENOMEM ; + conn_info =cec_notifier_get_conn_info (ao_cec->notify); + ao_cec->adap =cec_allocate_adapter (&meson_ao_cec_ops, ao_cec,"meson_ao_cec" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -1 );/* Use 1 for now */ +1 ,/* Use 1 for now */ + conn_info);if (IS_ERR (ao_cec->adap)) { ret =PTR_ERR (ao_cec->adap); goto out_probe_notify;
drivers/media/platform/s5p-cec/s5p_cec.c +5 -1
@@ -177,6 +177,7 @@ static const struct cec_adap_ops s5p_cec_adap_ops = {static int s5p_cec_probe (struct platform_device *pdev) { +const struct cec_connector_info *conn_info;struct device *dev = &pdev->dev;struct device *hdmi_dev;struct resource *res;
@@ -222,8 +223,11 @@ static int s5p_cec_probe(struct platform_device *pdev)if (cec->notifier ==NULL )return -ENOMEM ; + conn_info =cec_notifier_get_conn_info (cec->notifier); + cec->adap =cec_allocate_adapter (&s5p_cec_adap_ops, cec,CEC_NAME , -CEC_CAP_DEFAULTS | (needs_hpd ?CEC_CAP_NEEDS_HPD :0 ),1 ); +CEC_CAP_DEFAULTS | (needs_hpd ?CEC_CAP_NEEDS_HPD :0 ),1 , + conn_info); ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;
drivers/media/platform/seco-cec/seco-cec.c +6 -2
@@ -535,7 +535,7 @@ static int secocec_cec_get_notifier(struct cec_notifier **notify)if (!d)return -EPROBE_DEFER ; - *notify =cec_notifier_get_conn (d, m->conn); + *notify =cec_notifier_get_conn (d, m->conn,NULL );put_device (d);return 0 ;
@@ -571,6 +571,7 @@ static int secocec_acpi_probe(struct secocec_data *sdev)static int secocec_probe (struct platform_device *pdev) { +const struct cec_connector_info *conn_info;struct secocec_data *secocec;struct device *dev = &pdev->dev;int ret;
@@ -636,12 +637,15 @@ static int secocec_probe(struct platform_device *pdev) goto err; } + conn_info =cec_notifier_get_conn_info (secocec->notifier); +/* Allocate CEC adapter */ secocec->cec_adap =cec_allocate_adapter (&secocec_cec_adap_ops, secocec,dev_name (dev),CEC_CAP_DEFAULTS , -SECOCEC_MAX_ADDRS ); +SECOCEC_MAX_ADDRS , + conn_info);if (IS_ERR (secocec->cec_adap)) { ret =PTR_ERR (secocec->cec_adap);
drivers/media/platform/sti/cec/stih-cec.c +5 -1
@@ -298,6 +298,7 @@ static const struct cec_adap_ops sti_cec_adap_ops = {static int stih_cec_probe (struct platform_device *pdev) { +const struct cec_connector_info *conn_info;struct device *dev = &pdev->dev;struct resource *res;struct stih_cec *cec;
@@ -340,8 +341,11 @@ static int stih_cec_probe(struct platform_device *pdev)return PTR_ERR (cec->clk); } + conn_info =cec_notifier_get_conn_info (cec->notifier); + cec->adap =cec_allocate_adapter (&sti_cec_adap_ops, cec, -CEC_NAME ,CEC_CAP_DEFAULTS ,CEC_MAX_LOG_ADDRS ); +CEC_NAME ,CEC_CAP_DEFAULTS ,CEC_MAX_LOG_ADDRS , + conn_info); ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;
drivers/media/platform/stm32/stm32-cec.c +1 -1
@@ -315,7 +315,7 @@ static int stm32_cec_probe(struct platform_device *pdev)* available for example when a drm driver can provide edid */ cec->adap =cec_allocate_adapter (&stm32_cec_adap_ops, cec, -CEC_NAME , caps,CEC_MAX_LOG_ADDRS ); +CEC_NAME , caps,CEC_MAX_LOG_ADDRS ,NULL ); ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;
drivers/media/platform/tegra-cec/tegra_cec.c +4 -1
@@ -327,6 +327,7 @@ static const struct cec_adap_ops tegra_cec_ops = {static int tegra_cec_probe (struct platform_device *pdev) { +const struct cec_connector_info *conn_info;struct device *hdmi_dev;struct tegra_cec *cec;struct resource *res;
@@ -400,9 +401,11 @@ static int tegra_cec_probe(struct platform_device *pdev) goto clk_error; } + conn_info =cec_notifier_get_conn_info (cec->notifier); + cec->adap =cec_allocate_adapter (&tegra_cec_ops, cec,TEGRA_CEC_NAME ,CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS , conn_info);if (IS_ERR (cec->adap)) { ret = -ENOMEM ;dev_err (&pdev->dev,"Couldn't create cec adapter\n" );
drivers/media/platform/vivid/vivid-cec.c +1 -1
@@ -283,5 +283,5 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, idx);return cec_allocate_adapter (&vivid_cec_adap_ops, dev, - name, caps,1 ); + name, caps,1 ,NULL ); }
drivers/media/usb/pulse8-cec/pulse8-cec.c +2 -1
@@ -656,7 +656,8 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) pulse8->serio = serio; pulse8->adap =cec_allocate_adapter (&pulse8_cec_adap_ops, pulse8, -dev_name (&serio->dev), caps,1 ); +dev_name (&serio->dev), caps,1 , +NULL ); err =PTR_ERR_OR_ZERO (pulse8->adap);if (err <0 ) goto free_device;
drivers/media/usb/rainshadow-cec/rainshadow-cec.c +2 -1
@@ -323,7 +323,8 @@ static int rain_connect(struct serio *serio, struct serio_driver *drv) rain->serio = serio; rain->adap =cec_allocate_adapter (&rain_cec_adap_ops, rain, -dev_name (&serio->dev), caps,1 ); +dev_name (&serio->dev), caps,1 , +NULL ); err =PTR_ERR_OR_ZERO (rain->adap);if (err <0 ) goto free_device;
include/drm/drm_dp_helper.h +7 -7
@@ -1208,6 +1208,7 @@ struct drm_dp_aux_msg {struct cec_adapter ;struct edid ; +struct drm_connector ;/** * struct drm_dp_aux_cec - DisplayPort CEC-Tunneling-over-AUX
@@ -1220,8 +1221,7 @@ struct edid;struct drm_dp_aux_cec {struct mutex lock;struct cec_adapter *adap; -const char *name; -struct device *parent; +struct drm_connector *connector;struct delayed_work unregister_work; };
@@ -1418,8 +1418,8 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)#ifdef CONFIG_DRM_DP_CEC void drm_dp_cec_irq (struct drm_dp_aux *aux); -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);void drm_dp_cec_unregister_connector (struct drm_dp_aux *aux);void drm_dp_cec_set_edid (struct drm_dp_aux *aux,const struct edid *edid);void drm_dp_cec_unset_edid (struct drm_dp_aux *aux);
@@ -1428,9 +1428,9 @@ static inline void drm_dp_cec_irq(struct drm_dp_aux *aux) { } -static inline void drm_dp_cec_register_connector (struct drm_dp_aux *aux, -const char *name, -struct device *parent) +static inline void +drm_dp_cec_register_connector (struct drm_dp_aux *aux, +struct drm_connector *connector) { }
include/media/cec-notifier.h +27 -7
@@ -24,6 +24,8 @@ struct cec_notifier;* device and connector tuple. * @dev: device that sends the events. * @conn: the connector name from which the event occurs +* @connector_info: relevant only if the call is used to create a notifier, +* the connector's info to associate with new notifier. * * If a notifier for device @dev already exists, then increase the refcount * and return that notifier.
@@ -33,8 +35,10 @@ struct cec_notifier;* * Return NULL if the memory could not be allocated. */ -struct cec_notifier *cec_notifier_get_conn (struct device *dev, -const char *conn); +struct cec_notifier *cec_notifier_get_conn ( +struct device *dev, +const char *conn, +const struct cec_connector_info *connector_info);/** * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
@@ -79,6 +83,14 @@ void cec_notifier_register(struct cec_notifier *n,*/ void cec_notifier_unregister (struct cec_notifier *n); +/** +* cec_notifier_get_conn_info - get connector info associated with a +* notifier. +* @n: the CEC notifier +*/ +const struct cec_connector_info * +cec_notifier_get_conn_info (struct cec_notifier *n); +/** * cec_register_cec_notifier - register the notifier with the cec adapter. * @adap: the CEC adapter
@@ -99,8 +111,10 @@ void cec_register_cec_notifier(struct cec_adapter *adap,struct device *cec_notifier_parse_hdmi_phandle (struct device *dev);#else -static inline struct cec_notifier *cec_notifier_get_conn (struct device *dev, -const char *conn) +static inline struct cec_notifier * +cec_notifier_get_conn (struct device *dev, +const char *conn, +const struct cec_connector_info *connector_info) {/* A non-NULL pointer is expected on success */ return (struct cec_notifier *)0xdeadfeed ;
@@ -119,9 +133,15 @@ static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, { } +static inline const struct cec_connector_info * +cec_notifier_get_conn_info (struct cec_notifier *n) +{ +return NULL ; +} +static inline void cec_notifier_register (struct cec_notifier *n, -struct cec_adapter *adap, -void (*callback)(struct cec_adapter *adap,u16 pa)) +struct cec_adapter *adap, +void (*callback)(struct cec_adapter *adap,u16 pa)) { }
@@ -155,7 +175,7 @@ static inline struct device *cec_notifier_parse_hdmi_phandle(struct device *dev)*/ static inline struct cec_notifier *cec_notifier_get (struct device *dev) { -return cec_notifier_get_conn (dev,NULL ); +return cec_notifier_get_conn (dev,NULL ,NULL ); }/**
include/media/cec.h +15 -1
@@ -200,6 +200,8 @@ struct cec_adapter {u32 sequence;char input_phys[32 ]; + +struct cec_connector_info connector_info; };static inline void *cec_get_drvdata (const struct cec_adapter *adap)
@@ -233,10 +235,12 @@ static inline bool cec_is_registered(const struct cec_adapter *adap) ((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xfstruct edid ; +struct drm_connector ;#if IS_REACHABLE (CONFIG_CEC_CORE )struct cec_adapter *cec_allocate_adapter (const struct cec_adap_ops *ops, -void *priv,const char *name,u32 caps,u8 available_las); +void *priv,const char *name,u32 caps,u8 available_las, +const struct cec_connector_info *connector_info);int cec_register_adapter (struct cec_adapter *adap,struct device *parent);void cec_unregister_adapter (struct cec_adapter *adap);void cec_delete_adapter (struct cec_adapter *adap);
@@ -331,6 +335,9 @@ void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts);u16 cec_get_edid_phys_addr (const u8 *edid,unsigned int size,unsigned int *offset); +void cec_fill_connector_info (struct cec_connector_info *connector_info, +const struct drm_connector *connector); +#else static inline int cec_register_adapter(struct cec_adapter *adap,
@@ -365,6 +372,13 @@ static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, return CEC_PHYS_ADDR_INVALID; } +static inline void +cec_fill_connector_info (const struct drm_connector *connector, +struct cec_connector_info *conn_info) +{ +memset (conn_info,0 ,sizeof (*conn_info)); +} +#endif /**
include/uapi/linux/cec.h +24 -0
@@ -411,6 +411,27 @@ struct cec_event_lost_msgs {__u32 lost_msgs; }; +/** +* 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 ]; + }; +}; +/** * struct cec_event - CEC event structure * @ts: the timestamp of when the event was sent.
@@ -475,6 +496,9 @@ struct cec_event {#define CEC_G_MODE _IOR('a', 8, __u32)#define CEC_S_MODE _IOW('a', 9, __u32) +/* Gets the connector info */ +#define CEC_ADAP_G_CONNECTOR_INFO _IOR('a', 10, struct cec_connector_info) +/* * The remainder of this header defines all CEC messages and operands. * The format matters since it the cec-ctl utility parses it to generate
Signature · 1 line
2.18.1
PATCH v6 2/3 drm/bridge: dw-hdmi: pass connector info to the CEC adapter
This patch makes dw-hdmi pass DRM connector info to a respective CEC adapter. In order to be able to do that it delays creation of the dw-hdmi-cec platform device until DRM connector is initialized.
Requires testing.
--- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 5 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h | 2 + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 82 +++++++++++-------- 3 files changed, 52 insertions(+), 37 deletions(-)
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +4 -1
@@ -232,6 +232,7 @@ static void dw_hdmi_cec_del(void *data)static int dw_hdmi_cec_probe (struct platform_device *pdev) {struct dw_hdmi_cec_data *data =dev_get_platdata (&pdev->dev); +struct cec_connector_info conn_info;struct dw_hdmi_cec *cec;int ret;
@@ -258,10 +259,12 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)dw_hdmi_write (cec, ~0 ,HDMI_IH_MUTE_CEC_STAT0 );dw_hdmi_write (cec,0 ,HDMI_CEC_POLARITY ); +cec_fill_connector_info (&conn_info, data->connector); + cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ,NULL ); +CEC_MAX_LOG_ADDRS , &conn_info);if (IS_ERR (cec->adap))return PTR_ERR (cec->adap);
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h +2 -0
@@ -1,6 +1,7 @@#ifndef DW_HDMI_CEC_H #define DW_HDMI_CEC_H +struct drm_connector ;struct dw_hdmi ; struct dw_hdmi_cec_ops {
@@ -13,6 +14,7 @@ struct dw_hdmi_cec_ops {struct dw_hdmi_cec_data {struct dw_hdmi *hdmi;const struct dw_hdmi_cec_ops *ops; +const struct drm_connector *connector;int irq; };
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +46 -36
130 lines not on this page · raw message
Signature · 1 line
2.18.1
Re: [PATCH v6 2/3] drm/bridge: dw-hdmi: pass connector info to the CEC adapter
Quoted 5 lines · Dariusz Marcinkiewicz
This patch makes dw-hdmi pass DRM connector info to a respective CEC adapter. In order to be able to do that it delays creation of the dw-hdmi-cec platform device until DRM connector is initialized.
Requires testing.
Testing this patch with the Khadas VIM2 board gives this kernel warning:
[ 3.468499] meson-dw-hdmi c883a000.hdmi-tx: Detected HDMI TX controller v2.01a with HDCP (meson_dw_hdmi_phy) [ 3.473123] meson-dw-hdmi c883a000.hdmi-tx: registered DesignWare HDMI I2C bus driver [ 3.481151] WARNING: CPU: 4 PID: 66 at mm/page_alloc.c:4584 __alloc_pages_nodemask+0x7c8/0xb98 [ 3.488962] Modules linked in: [ 3.491984] CPU: 4 PID: 66 Comm: kworker/4:1 Not tainted 5.1.0-rc1-arm64 #26 [ 3.498965] Hardware name: Khadas VIM2 (DT) [ 3.503114] Workqueue: events deferred_probe_work_func [ 3.508197] pstate: 20000005 (nzCv daif -PAN -UAO) [ 3.512941] pc : __alloc_pages_nodemask+0x7c8/0xb98 [ 3.517771] lr : alloc_pages_current+0x80/0xf0 [ 3.522167] sp : ffff0000119db680 [ 3.525444] x29: ffff0000119db680 x28: 0000000000000000 [ 3.530705] x27: ffff000010c0d108 x26: ffff8000be900cf0 [ 3.535966] x25: 0000000000000001 x24: ffff8000be93d400 [ 3.541228] x23: ffff00001119cd90 x22: ffff8000be900c80 [ 3.546489] x21: 0000000000000000 x20: 000000000000001a [ 3.551750] x19: 0000000000040cc0 x18: 0000000000000001 [ 3.557011] x17: 0000000000000001 x16: 0000000000000019 [ 3.562273] x15: ffffffffffffffff x14: ffff00001103d6c8 [ 3.567534] x13: ffff8000be529e09 x12: 0000000000000018 [ 3.572795] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f [ 3.578056] x9 : 0000000000000000 x8 : ffff8000bdb4f000 [ 3.583317] x7 : ffff8000bdb4ecf0 x6 : 0000000000000041 [ 3.588579] x5 : 0000000000000000 x4 : ffff00001103d6c8 [ 3.593840] x3 : 0000000000000000 x2 : 0000000000000000 [ 3.599101] x1 : 000000000000001a x0 : 0000000000040cc0 [ 3.604363] Call trace: [ 3.606781] __alloc_pages_nodemask+0x7c8/0xb98 [ 3.611264] alloc_pages_current+0x80/0xf0 [ 3.615320] kmalloc_order+0x14/0x38 [ 3.618857] __kmalloc_track_caller+0x1c8/0x220 [ 3.623341] kmemdup+0x28/0x50 [ 3.626360] platform_device_add_resources+0x30/0x68 [ 3.631275] platform_device_register_full+0xa8/0x130 [ 3.636279] dw_hdmi_bridge_attach+0xc4/0xd0 [ 3.640507] drm_bridge_attach+0x64/0xc0 [ 3.644384] dw_hdmi_bind+0x4c/0x98 [ 3.647838] meson_dw_hdmi_bind+0x424/0x568 [ 3.651975] component_bind_all+0x110/0x238 [ 3.656116] meson_drv_bind_master+0x308/0x488 [ 3.660514] meson_drv_bind+0x10/0x18 [ 3.664136] try_to_bring_up_master+0x164/0x1c0 [ 3.668621] component_master_add_with_match+0xbc/0xf8 [ 3.673710] meson_drv_probe+0xd0/0x120 [ 3.677505] platform_drv_probe+0x50/0xa8 [ 3.681472] really_probe+0x1c8/0x2a0 [ 3.685094] driver_probe_device+0x54/0xf0 [ 3.689148] __device_attach_driver+0x80/0xb8 [ 3.693463] bus_for_each_drv+0x78/0xc8 [ 3.697255] __device_attach+0xd4/0x130 [ 3.701051] device_initial_probe+0x10/0x18 [ 3.705190] bus_probe_device+0x90/0x98 [ 3.708986] deferred_probe_work_func+0x6c/0xa0 [ 3.713473] process_one_work+0x1e0/0x330 [ 3.717439] worker_thread+0x240/0x448 [ 3.721150] kthread+0x120/0x128 [ 3.724340] ret_from_fork+0x10/0x1c [ 3.727874] ---[ end trace 729b3a53d3f3eac1 ]--- [ 3.732510] meson-drm d0100000.vpu: bound c883a000.hdmi-tx (ops meson_dw_hdmi_ops) [ 3.740366] [drm] Initialized meson 1.0.0 20161109 for d0100000.vpu on minor 0 [ 3.747158] [drm] Cannot find any crtc or sizes [ 3.752380] libphy: mdio_mux: probed [ 3.755243] [drm] Cannot find any crtc or sizes
If I revert this patch, then it's fine again.
I get this even if CONFIG_DRM_DW_HDMI_CEC is not set.
The Khadas VIM2 board uses dw-hdmi for the HDMI support, but it uses its own CEC meson driver. I do have other HW that uses dw-hdmi for CEC, but won't have access to it until next week.
Regards,
Hans
Quoted 197 lines
Signed-off-by Dariusz Marcinkiewicz <[email protected]>--- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 5 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h | 2 + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 82 +++++++++++-------- 3 files changed, 52 insertions(+), 37 deletions(-)drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +4
-1@@ -232,6 +232,7 @@ static void dw_hdmi_cec_del(void *data)static int dw_hdmi_cec_probe (struct platform_device *pdev) {struct dw_hdmi_cec_data *data =dev_get_platdata (&pdev->dev); +struct cec_connector_info conn_info;struct dw_hdmi_cec *cec;int ret;@@ -258,10 +259,12 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev)dw_hdmi_write (cec, ~0 ,HDMI_IH_MUTE_CEC_STAT0 );dw_hdmi_write (cec,0 ,HDMI_CEC_POLARITY ); +cec_fill_connector_info (&conn_info, data->connector); + cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ,NULL ); +CEC_MAX_LOG_ADDRS , &conn_info);if (IS_ERR (cec->adap))return PTR_ERR (cec->adap);drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h +2
-0@@ -1,6 +1,7 @@#ifndef DW_HDMI_CEC_H #define DW_HDMI_CEC_H +struct drm_connector ;struct dw_hdmi ; struct dw_hdmi_cec_ops {@@ -13,6 +14,7 @@ struct dw_hdmi_cec_ops {struct dw_hdmi_cec_data {struct dw_hdmi *hdmi;const struct dw_hdmi_cec_ops *ops; +const struct drm_connector *connector;int irq; };drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +46
-36@@ -138,6 +138,8 @@ struct dw_hdmi {struct drm_connector connector;struct drm_bridge bridge; +int irq; +unsigned int version;struct platform_device *audio;@@ -189,6 +191,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; };@@ -2113,6 +2116,29 @@ 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 (&hdmi->mutex); + hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE ; +hdmi_writeb (hdmi, hdmi->mc_clkdis,HDMI_MC_CLKDIS ); +mutex_unlock (&hdmi->mutex); +} + +static void dw_hdmi_cec_disable (struct dw_hdmi *hdmi) +{ +mutex_lock (&hdmi->mutex); + hdmi->mc_clkdis |=HDMI_MC_CLKDIS_CECCLK_DISABLE ; +hdmi_writeb (hdmi, hdmi->mc_clkdis,HDMI_MC_CLKDIS ); +mutex_unlock (&hdmi->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;@@ -2129,6 +2155,23 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)drm_connector_attach_encoder (connector, encoder); +if (hdmi->cec_configured) { +struct platform_device_info pdevinfo; +struct dw_hdmi_cec_data cec; + + cec.hdmi = hdmi; + cec.ops = &dw_hdmi_cec_ops; + cec.irq = hdmi->irq; + cec.connector = connector; + + pdevinfo.name ="dw-hdmi-cec" ; + pdevinfo.data = &cec; + pdevinfo.size_data =sizeof (cec); + pdevinfo.dma_mask =0 ; + + hdmi->cec =platform_device_register_full (&pdevinfo); + } +return 0 ; }@@ -2398,29 +2441,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 (&hdmi->mutex); - hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE ; -hdmi_writeb (hdmi, hdmi->mc_clkdis,HDMI_MC_CLKDIS ); -mutex_unlock (&hdmi->mutex); -} - -static void dw_hdmi_cec_disable (struct dw_hdmi *hdmi) -{ -mutex_lock (&hdmi->mutex); - hdmi->mc_clkdis |=HDMI_MC_CLKDIS_CECCLK_DISABLE ; -hdmi_writeb (hdmi, hdmi->mc_clkdis,HDMI_MC_CLKDIS ); -mutex_unlock (&hdmi->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 ,@@ -2443,7 +2463,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;@@ -2593,6 +2612,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,@@ -2668,18 +2688,8 @@ __dw_hdmi_probe(struct platform_device *pdev, hdmi->audio =platform_device_register_full (&pdevinfo); } -if (config0 &HDMI_CONFIG0_CEC ) { - cec.hdmi = hdmi; - cec.ops = &dw_hdmi_cec_ops; - cec.irq = irq; - - pdevinfo.name ="dw-hdmi-cec" ; - pdevinfo.data = &cec; - pdevinfo.size_data =sizeof (cec); - pdevinfo.dma_mask =0 ; - - hdmi->cec =platform_device_register_full (&pdevinfo); - } +if (config0 &HDMI_CONFIG0_CEC ) + hdmi->cec_configured = true;/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */ if (hdmi->i2c)
Re: [PATCH v6 2/3] drm/bridge: dw-hdmi: pass connector info to the CEC adapter
Quoted 10 lines · Hans Verkuil
Quoted 5 lines · Dariusz Marcinkiewicz
This patch makes dw-hdmi pass DRM connector info to a respective CEC adapter. In order to be able to do that it delays creation of the dw-hdmi-cec platform device until DRM connector is initialized.
Requires testing.
Testing this patch with the Khadas VIM2 board gives this kernel warning:
Thank you for testing!
This was probably because the platform device info was not fully initialized. Hopefully it is better in v7.
Regards.
Re: [PATCH v6 2/3] drm/bridge: dw-hdmi: pass connector info to the CEC adapter
Quoted 7 lines · Dariusz Marcinkiewicz
Quoted 6 lines · Hans Verkuil
Quoted 4 lines · Dariusz Marcinkiewicz
This patch makes dw-hdmi pass DRM connector info to a respective CEC adapter. In order to be able to do that it delays creation of the dw-hdmi-cec platform device until DRM connector is initialized.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
Requires testing.
Testing this patch with the Khadas VIM2 board gives this kernel warning:
Thank you for testing!
This was probably because the platform device info was not fully initialized. Hopefully it is better in v7.
This now works without a crash on my Khadas board!
Thanks,
Hans
PATCH v6 3/3 drm/i2c: tda9950: pass HDMI connector info to CEC adapter
In reply to Dariusz MarcinkiewiczWith that change tda998x provides a connector info to the CEC adapter. In order to be able to that it delays creation of respective CEC device until the DRM connector is initialized.
Requires testing.
--- drivers/gpu/drm/i2c/tda9950.c | 7 ++++- drivers/gpu/drm/i2c/tda998x_drv.c | 41 +++++++++++++-------------- include/linux/platform_data/tda9950.h | 2 ++ 3 files changed, 28 insertions(+), 22 deletions(-)
drivers/gpu/drm/i2c/tda9950.c +6 -1
@@ -382,6 +382,7 @@ static int tda9950_probe(struct i2c_client *client, const struct i2c_device_id *id) {struct tda9950_glue *glue = client->dev.platform_data; +struct cec_connector_info conn_info;struct device *dev = &client->dev;struct tda9950_priv *priv;unsigned long irqflags;
@@ -422,10 +423,14 @@ static int tda9950_probe(struct i2c_client *client,if (glue && glue->parent) priv->hdmi = glue->parent; +memset (&conn_info,0 ,sizeof (conn_info)); +if (glue) +cec_fill_connector_info (&conn_info, glue->connector); + priv->adap =cec_allocate_adapter (&tda9950_cec_ops, priv,"tda9950" ,CEC_CAP_DEFAULTS ,CEC_MAX_LOG_ADDRS , -NULL ); + &conn_info);if (IS_ERR (priv->adap))return PTR_ERR (priv->adap);
drivers/gpu/drm/i2c/tda998x_drv.c +20 -21
71 lines not on this page · raw message
include/linux/platform_data/tda9950.h +2 -0
@@ -2,10 +2,12 @@#define LINUX_PLATFORM_DATA_TDA9950_H struct device ; +struct drm_connector ;struct tda9950_glue {struct device *parent;unsigned long irq_flags; +const struct drm_connector *connector;void *data;int (*init)(void *);void (*exit)(void *);
Signature · 1 line
2.18.1
Hi Dariusz,
Quoted 54 lines · Dariusz Marcinkiewicz
This patch proposes to expose explicit mapping between HDMI connectors and
/dev/cecXadapters to userland.New structure with connector info (card number and connector id in case of DRM connectors) is added to
cec_adapter. That connector info is expected to be provided when an adapter is created.CEC notifier is extended so that it can be used to communicate the connector's info to CEC adapters' creators.
New ioctl, exposing connector info to userland, is added to
/dev/cec.Changes since v5:
- make the patch apply against the latest changes in the affected code
Changes since v4:
- small tweaks + added documentation
Changes since v3:
-cec_get_connter_conntakesconnector_infoas argument
Changes since v2:
-cec_s_connector_inforemoved, the connector info is now passed tocec_allocate_adapter
- updated commit message
Changes since v1:
- removed the unnecessary event,
- extendedcec_connctor_infoto allow for various types of connectors.Signed-off-by Dariusz Marcinkiewicz <[email protected]>--- Documentation/media/kapi/cec-core.rst | 7 +- 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/adv7511/adv7511_cec.c | 3 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 2 +- drivers/gpu/drm/drm_dp_cec.c | 22 ++-- drivers/gpu/drm/i2c/tda9950.c | 3 +- drivers/gpu/drm/i915/intel_dp.c | 4 +- drivers/gpu/drm/i915/intel_hdmi.c | 6 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 +- drivers/media/cec/cec-adap.c | 13 +++ drivers/media/cec/cec-api.c | 12 ++ drivers/media/cec/cec-core.c | 8 +- drivers/media/cec/cec-notifier.c | 20 +++- drivers/media/cec/cec-pin.c | 2 +- drivers/media/i2c/tc358743.c | 3 +- .../media/platform/cros-ec-cec/cros-ec-cec.c | 7 +- drivers/media/platform/meson/ao-cec.c | 6 +- drivers/media/platform/s5p-cec/s5p_cec.c | 6 +- drivers/media/platform/seco-cec/seco-cec.c | 8 +- drivers/media/platform/sti/cec/stih-cec.c | 6 +- drivers/media/platform/stm32/stm32-cec.c | 2 +- drivers/media/platform/tegra-cec/tegra_cec.c | 5 +- drivers/media/platform/vivid/vivid-cec.c | 2 +-
Quoted 9 lines
drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +- .../media/usb/rainshadow-cec/rainshadow-cec.c | 3 +- include/drm/drm_dp_helper.h | 14 +-- include/media/cec-notifier.h | 34 ++++-- include/media/cec.h | 16 ++- include/uapi/linux/cec.h | 24 ++++ 32 files changed, 310 insertions(+), 54 deletions(-) create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
I've been doing some testing with my Khadas VIM2 board (amlogic SoC).
It's a bit unusual since it uses the Synopsys bridge, but not the Synopsys CEC driver (it has its own meson cec driver).
The first thing I noticed is that I did not get any connector info.
I think that the root cause of that is that you forgot that there are several drm drivers that call cec_notifier_get() instead of cec_notifier_get_conn().
I think all those calls to cec_notifier_get() in drm drivers should be replaced by cec_notifier_get_conn() where the second argument is NULL, but the third argument should contain valid connector info.
A quick grep gives me the following drivers that need work:
drivers/gpu/drm/bridge/synopsys/dw-hdmi.cdrivers/gpu/drm/exynos/exynos_hdmi.cdrivers/gpu/drm/i2c/tda998x_drv.cdrivers/gpu/drm/sti/sti_hdmi.cdrivers/gpu/drm/tegra/output.c
The second thing I noticed is that patch 2 gave me a new kernel warning, but I'll do some more testing for that and reply to patch 2/3 once I know more.
Regards,
Hans
Quoted 80 lines · Hans Verkuil
Hi Dariusz,
Quoted 54 lines · Dariusz Marcinkiewicz
This patch proposes to expose explicit mapping between HDMI connectors and
/dev/cecXadapters to userland.New structure with connector info (card number and connector id in case of DRM connectors) is added to
cec_adapter. That connector info is expected to be provided when an adapter is created.CEC notifier is extended so that it can be used to communicate the connector's info to CEC adapters' creators.
New ioctl, exposing connector info to userland, is added to
/dev/cec.Changes since v5:
- make the patch apply against the latest changes in the affected code
Changes since v4:
- small tweaks + added documentation
Changes since v3:
-cec_get_connter_conntakesconnector_infoas argument
Changes since v2:
-cec_s_connector_inforemoved, the connector info is now passed tocec_allocate_adapter
- updated commit message
Changes since v1:
- removed the unnecessary event,
- extendedcec_connctor_infoto allow for various types of connectors.Signed-off-by Dariusz Marcinkiewicz <[email protected]>--- Documentation/media/kapi/cec-core.rst | 7 +- 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/adv7511/adv7511_cec.c | 3 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 2 +- drivers/gpu/drm/drm_dp_cec.c | 22 ++-- drivers/gpu/drm/i2c/tda9950.c | 3 +- drivers/gpu/drm/i915/intel_dp.c | 4 +- drivers/gpu/drm/i915/intel_hdmi.c | 6 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 +- drivers/media/cec/cec-adap.c | 13 +++ drivers/media/cec/cec-api.c | 12 ++ drivers/media/cec/cec-core.c | 8 +- drivers/media/cec/cec-notifier.c | 20 +++- drivers/media/cec/cec-pin.c | 2 +- drivers/media/i2c/tc358743.c | 3 +- .../media/platform/cros-ec-cec/cros-ec-cec.c | 7 +- drivers/media/platform/meson/ao-cec.c | 6 +- drivers/media/platform/s5p-cec/s5p_cec.c | 6 +- drivers/media/platform/seco-cec/seco-cec.c | 8 +- drivers/media/platform/sti/cec/stih-cec.c | 6 +- drivers/media/platform/stm32/stm32-cec.c | 2 +- drivers/media/platform/tegra-cec/tegra_cec.c | 5 +- drivers/media/platform/vivid/vivid-cec.c | 2 +-Quoted 9 lines
drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +- .../media/usb/rainshadow-cec/rainshadow-cec.c | 3 +- include/drm/drm_dp_helper.h | 14 +-- include/media/cec-notifier.h | 34 ++++-- include/media/cec.h | 16 ++- include/uapi/linux/cec.h | 24 ++++ 32 files changed, 310 insertions(+), 54 deletions(-) create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rstI've been doing some testing with my Khadas VIM2 board (amlogic SoC).
It's a bit unusual since it uses the Synopsys bridge, but not the Synopsys CEC driver (it has its own meson cec driver).
The first thing I noticed is that I did not get any connector info.
I think that the root cause of that is that you forgot that there are several drm drivers that callcec_notifier_get()instead ofcec_notifier_get_conn().I think all those calls to
cec_notifier_get()in drm drivers should be replaced bycec_notifier_get_conn()where the second argument is NULL, but the third argument should contain valid connector info.
Quoted 7 lines
A quick grep gives me the following drivers that need work:
drivers/gpu/drm/bridge/synopsys/dw-hdmi.cdrivers/gpu/drm/exynos/exynos_hdmi.cdrivers/gpu/drm/i2c/tda998x_drv.cdrivers/gpu/drm/sti/sti_hdmi.cdrivers/gpu/drm/tegra/output.c
You also missed updating drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c: the cec_allocate_adapter call should be extended with the connector info.
You also missed these three v4l cec adapters:
drivers/media/i2c/adv7511.cdrivers/media/i2c/adv7604.cdrivers/media/i2c/adv7842.c
Use NULL for the connector info for these three drivers.
Also note that in 5.2-rc1 a new meson cec driver was added, that should be updated as well, similar to the existing meson cec driver.
Regards,
Hans
Quoted 8 lines
The second thing I noticed is that patch 2 gave me a new kernel warning, but I'll do some more testing for that and reply to patch 2/3 once I know more.
Regards,
Hans
Quoted 12 lines · Hans Verkuil
It's a bit unusual since it uses the Synopsys bridge, but not the Synopsys CEC driver (it has its own meson cec driver).
The first thing I noticed is that I did not get any connector info.
I think that the root cause of that is that you forgot that there are several drm drivers that callcec_notifier_get()instead ofcec_notifier_get_conn().I think all those calls to
cec_notifier_get()in drm drivers should be replaced bycec_notifier_get_conn()where the second argument is NULL, but the third argument should contain valid connector info.
Quoted 8 lines
A quick grep gives me the following drivers that need work:
drivers/gpu/drm/bridge/synopsys/dw-hdmi.cdrivers/gpu/drm/exynos/exynos_hdmi.cdrivers/gpu/drm/i2c/tda998x_drv.cdrivers/gpu/drm/sti/sti_hdmi.cdrivers/gpu/drm/tegra/output.c
I am afraid that just replacing cec_notifier_get with cec_notifier_get_conn won't necessarily make this information available, as, e.g. looking at tegra, those would also require some reshuffling of the code so that notifier is created once connector is initialized. Btw. I've updated dw-hdmi.c and tda998x_drv.c to use cec_notifier_get_conn, so at least those 2 will be covered.
Quoted 3 lines
The second thing I noticed is that patch 2 gave me a new kernel warning, but I'll do some more testing for that and reply to patch 2/3 once I know more.
I hope this is fixed in v7.
Thank you for your testing and best regards!