forked from Minki/linux
drm/dp: Add backpointer to drm_device in drm_dp_aux
This is something that we've wanted for a while now: the ability to actually look up the respective drm_device for a given drm_dp_aux struct. This will also allow us to transition over to using the drm_dbg_*() helpers for debug message printing, as we'll finally have a drm_device to reference for doing so. Note that there is one limitation with this - because some DP AUX adapters exist as platform devices which are initialized independently of their respective DRM devices, one cannot rely on drm_dp_aux->drm_dev to always be non-NULL until drm_dp_aux_register() has been called. We make sure to point this out in the documentation for struct drm_dp_aux. v3: * Add WARN_ON_ONCE() to drm_dp_aux_register() if drm_dev isn't filled out Signed-off-by: Lyude Paul <lyude@redhat.com> Acked-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210423184309.207645-4-lyude@redhat.com Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
fd43ad9d47
commit
6cba3fe433
@ -188,6 +188,8 @@ void amdgpu_atombios_dp_aux_init(struct amdgpu_connector *amdgpu_connector)
|
|||||||
{
|
{
|
||||||
amdgpu_connector->ddc_bus->rec.hpd = amdgpu_connector->hpd.hpd;
|
amdgpu_connector->ddc_bus->rec.hpd = amdgpu_connector->hpd.hpd;
|
||||||
amdgpu_connector->ddc_bus->aux.transfer = amdgpu_atombios_dp_aux_transfer;
|
amdgpu_connector->ddc_bus->aux.transfer = amdgpu_atombios_dp_aux_transfer;
|
||||||
|
amdgpu_connector->ddc_bus->aux.drm_dev = amdgpu_connector->base.dev;
|
||||||
|
|
||||||
drm_dp_aux_init(&amdgpu_connector->ddc_bus->aux);
|
drm_dp_aux_init(&amdgpu_connector->ddc_bus->aux);
|
||||||
amdgpu_connector->ddc_bus->has_aux = true;
|
amdgpu_connector->ddc_bus->has_aux = true;
|
||||||
}
|
}
|
||||||
|
@ -433,6 +433,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
|
|||||||
kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
|
kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
|
||||||
link_index);
|
link_index);
|
||||||
aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer;
|
aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer;
|
||||||
|
aconnector->dm_dp_aux.aux.drm_dev = dm->ddev;
|
||||||
aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc;
|
aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc;
|
||||||
|
|
||||||
drm_dp_aux_init(&aconnector->dm_dp_aux.aux);
|
drm_dp_aux_init(&aconnector->dm_dp_aux.aux);
|
||||||
|
@ -537,6 +537,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge,
|
|||||||
/* Register aux channel */
|
/* Register aux channel */
|
||||||
anx6345->aux.name = "DP-AUX";
|
anx6345->aux.name = "DP-AUX";
|
||||||
anx6345->aux.dev = &anx6345->client->dev;
|
anx6345->aux.dev = &anx6345->client->dev;
|
||||||
|
anx6345->aux.drm_dev = bridge->dev;
|
||||||
anx6345->aux.transfer = anx6345_aux_transfer;
|
anx6345->aux.transfer = anx6345_aux_transfer;
|
||||||
|
|
||||||
err = drm_dp_aux_register(&anx6345->aux);
|
err = drm_dp_aux_register(&anx6345->aux);
|
||||||
|
@ -905,6 +905,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge,
|
|||||||
/* Register aux channel */
|
/* Register aux channel */
|
||||||
anx78xx->aux.name = "DP-AUX";
|
anx78xx->aux.name = "DP-AUX";
|
||||||
anx78xx->aux.dev = &anx78xx->client->dev;
|
anx78xx->aux.dev = &anx78xx->client->dev;
|
||||||
|
anx78xx->aux.drm_dev = bridge->dev;
|
||||||
anx78xx->aux.transfer = anx78xx_aux_transfer;
|
anx78xx->aux.transfer = anx78xx_aux_transfer;
|
||||||
|
|
||||||
err = drm_dp_aux_register(&anx78xx->aux);
|
err = drm_dp_aux_register(&anx78xx->aux);
|
||||||
|
@ -1765,6 +1765,7 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
|
|||||||
dp->aux.name = "DP-AUX";
|
dp->aux.name = "DP-AUX";
|
||||||
dp->aux.transfer = analogix_dpaux_transfer;
|
dp->aux.transfer = analogix_dpaux_transfer;
|
||||||
dp->aux.dev = dp->dev;
|
dp->aux.dev = dp->dev;
|
||||||
|
dp->aux.drm_dev = drm_dev;
|
||||||
|
|
||||||
ret = drm_dp_aux_register(&dp->aux);
|
ret = drm_dp_aux_register(&dp->aux);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1719,6 +1719,7 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge,
|
|||||||
|
|
||||||
dev_dbg(mhdp->dev, "%s\n", __func__);
|
dev_dbg(mhdp->dev, "%s\n", __func__);
|
||||||
|
|
||||||
|
mhdp->aux.drm_dev = bridge->dev;
|
||||||
ret = drm_dp_aux_register(&mhdp->aux);
|
ret = drm_dp_aux_register(&mhdp->aux);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1414,6 +1414,7 @@ static int tc_bridge_attach(struct drm_bridge *bridge,
|
|||||||
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
|
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
tc->aux.drm_dev = drm;
|
||||||
ret = drm_dp_aux_register(&tc->aux);
|
ret = drm_dp_aux_register(&tc->aux);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -350,6 +350,7 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdata->aux.drm_dev = bridge->dev;
|
||||||
ret = drm_dp_aux_register(&pdata->aux);
|
ret = drm_dp_aux_register(&pdata->aux);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
drm_err(bridge->dev, "Failed to register DP AUX channel: %d\n", ret);
|
drm_err(bridge->dev, "Failed to register DP AUX channel: %d\n", ret);
|
||||||
|
@ -278,6 +278,12 @@ void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
|
|||||||
if (!aux_dev) /* attach must have failed */
|
if (!aux_dev) /* attach must have failed */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As some AUX adapters may exist as platform devices which outlive their respective DRM
|
||||||
|
* devices, we clear drm_dev to ensure that we never accidentally reference a stale pointer
|
||||||
|
*/
|
||||||
|
aux->drm_dev = NULL;
|
||||||
|
|
||||||
mutex_lock(&aux_idr_mutex);
|
mutex_lock(&aux_idr_mutex);
|
||||||
idr_remove(&aux_idr, aux_dev->index);
|
idr_remove(&aux_idr, aux_dev->index);
|
||||||
mutex_unlock(&aux_idr_mutex);
|
mutex_unlock(&aux_idr_mutex);
|
||||||
|
@ -1767,6 +1767,8 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
WARN_ON_ONCE(!aux->drm_dev);
|
||||||
|
|
||||||
if (!aux->ddc.algo)
|
if (!aux->ddc.algo)
|
||||||
drm_dp_aux_init(aux);
|
drm_dp_aux_init(aux);
|
||||||
|
|
||||||
|
@ -2350,6 +2350,7 @@ drm_dp_mst_add_port(struct drm_device *dev,
|
|||||||
port->aux.is_remote = true;
|
port->aux.is_remote = true;
|
||||||
|
|
||||||
/* initialize the MST downstream port's AUX crc work queue */
|
/* initialize the MST downstream port's AUX crc work queue */
|
||||||
|
port->aux.drm_dev = dev;
|
||||||
drm_dp_remote_aux_init(&port->aux);
|
drm_dp_remote_aux_init(&port->aux);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -682,6 +682,7 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
|
|||||||
else
|
else
|
||||||
intel_dp->get_aux_send_ctl = g4x_get_aux_send_ctl;
|
intel_dp->get_aux_send_ctl = g4x_get_aux_send_ctl;
|
||||||
|
|
||||||
|
intel_dp->aux.drm_dev = &dev_priv->drm;
|
||||||
drm_dp_aux_init(&intel_dp->aux);
|
drm_dp_aux_init(&intel_dp->aux);
|
||||||
|
|
||||||
/* Failure to allocate our preferred name is not critical */
|
/* Failure to allocate our preferred name is not critical */
|
||||||
|
@ -46,8 +46,7 @@ void edp_bridge_destroy(struct drm_bridge *bridge);
|
|||||||
struct drm_connector *msm_edp_connector_init(struct msm_edp *edp);
|
struct drm_connector *msm_edp_connector_init(struct msm_edp *edp);
|
||||||
|
|
||||||
/* AUX */
|
/* AUX */
|
||||||
void *msm_edp_aux_init(struct device *dev, void __iomem *regbase,
|
void *msm_edp_aux_init(struct msm_edp *edp, void __iomem *regbase, struct drm_dp_aux **drm_aux);
|
||||||
struct drm_dp_aux **drm_aux);
|
|
||||||
void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux);
|
void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux);
|
||||||
irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr);
|
irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr);
|
||||||
void msm_edp_aux_ctrl(struct edp_aux *aux, int enable);
|
void msm_edp_aux_ctrl(struct edp_aux *aux, int enable);
|
||||||
|
@ -184,9 +184,9 @@ unlock_exit:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *msm_edp_aux_init(struct device *dev, void __iomem *regbase,
|
void *msm_edp_aux_init(struct msm_edp *edp, void __iomem *regbase, struct drm_dp_aux **drm_aux)
|
||||||
struct drm_dp_aux **drm_aux)
|
|
||||||
{
|
{
|
||||||
|
struct device *dev = &edp->pdev->dev;
|
||||||
struct edp_aux *aux = NULL;
|
struct edp_aux *aux = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -201,6 +201,7 @@ void *msm_edp_aux_init(struct device *dev, void __iomem *regbase,
|
|||||||
|
|
||||||
aux->drm_aux.name = "msm_edp_aux";
|
aux->drm_aux.name = "msm_edp_aux";
|
||||||
aux->drm_aux.dev = dev;
|
aux->drm_aux.dev = dev;
|
||||||
|
aux->drm_aux.drm_dev = edp->dev;
|
||||||
aux->drm_aux.transfer = edp_aux_transfer;
|
aux->drm_aux.transfer = edp_aux_transfer;
|
||||||
ret = drm_dp_aux_register(&aux->drm_aux);
|
ret = drm_dp_aux_register(&aux->drm_aux);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -1153,7 +1153,7 @@ int msm_edp_ctrl_init(struct msm_edp *edp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Init aux and phy */
|
/* Init aux and phy */
|
||||||
ctrl->aux = msm_edp_aux_init(dev, ctrl->base, &ctrl->drm_aux);
|
ctrl->aux = msm_edp_aux_init(edp, ctrl->base, &ctrl->drm_aux);
|
||||||
if (!ctrl->aux || !ctrl->drm_aux) {
|
if (!ctrl->aux || !ctrl->drm_aux) {
|
||||||
pr_err("%s:failed to init aux\n", __func__);
|
pr_err("%s:failed to init aux\n", __func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1354,6 +1354,7 @@ nouveau_connector_create(struct drm_device *dev,
|
|||||||
case DRM_MODE_CONNECTOR_DisplayPort:
|
case DRM_MODE_CONNECTOR_DisplayPort:
|
||||||
case DRM_MODE_CONNECTOR_eDP:
|
case DRM_MODE_CONNECTOR_eDP:
|
||||||
nv_connector->aux.dev = connector->kdev;
|
nv_connector->aux.dev = connector->kdev;
|
||||||
|
nv_connector->aux.drm_dev = dev;
|
||||||
nv_connector->aux.transfer = nouveau_connector_aux_xfer;
|
nv_connector->aux.transfer = nouveau_connector_aux_xfer;
|
||||||
snprintf(aux_name, sizeof(aux_name), "sor-%04x-%04x",
|
snprintf(aux_name, sizeof(aux_name), "sor-%04x-%04x",
|
||||||
dcbe->hasht, dcbe->hashm);
|
dcbe->hasht, dcbe->hashm);
|
||||||
|
@ -232,6 +232,7 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
|
|||||||
|
|
||||||
radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
|
radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
|
||||||
radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
|
radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
|
||||||
|
radeon_connector->ddc_bus->aux.drm_dev = radeon_connector->base.dev;
|
||||||
if (ASIC_IS_DCE5(rdev)) {
|
if (ASIC_IS_DCE5(rdev)) {
|
||||||
if (radeon_auxch)
|
if (radeon_auxch)
|
||||||
radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_native;
|
radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_native;
|
||||||
|
@ -719,6 +719,7 @@ int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
|
|||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
aux->drm_dev = output->connector.dev;
|
||||||
err = drm_dp_aux_register(aux);
|
err = drm_dp_aux_register(aux);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -1069,6 +1069,7 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp)
|
|||||||
|
|
||||||
dp->aux.name = "ZynqMP DP AUX";
|
dp->aux.name = "ZynqMP DP AUX";
|
||||||
dp->aux.dev = dp->dev;
|
dp->aux.dev = dp->dev;
|
||||||
|
dp->aux.drm_dev = dp->drm;
|
||||||
dp->aux.transfer = zynqmp_dp_aux_transfer;
|
dp->aux.transfer = zynqmp_dp_aux_transfer;
|
||||||
|
|
||||||
return drm_dp_aux_register(&dp->aux);
|
return drm_dp_aux_register(&dp->aux);
|
||||||
|
@ -1840,6 +1840,8 @@ struct drm_dp_aux_cec {
|
|||||||
* @name: user-visible name of this AUX channel and the I2C-over-AUX adapter
|
* @name: user-visible name of this AUX channel and the I2C-over-AUX adapter
|
||||||
* @ddc: I2C adapter that can be used for I2C-over-AUX communication
|
* @ddc: I2C adapter that can be used for I2C-over-AUX communication
|
||||||
* @dev: pointer to struct device that is the parent for this AUX channel
|
* @dev: pointer to struct device that is the parent for this AUX channel
|
||||||
|
* @drm_dev: pointer to the &drm_device that owns this AUX channel. Beware, this
|
||||||
|
* may be %NULL before drm_dp_aux_register() has been called.
|
||||||
* @crtc: backpointer to the crtc that is currently using this AUX channel
|
* @crtc: backpointer to the crtc that is currently using this AUX channel
|
||||||
* @hw_mutex: internal mutex used for locking transfers
|
* @hw_mutex: internal mutex used for locking transfers
|
||||||
* @crc_work: worker that captures CRCs for each frame
|
* @crc_work: worker that captures CRCs for each frame
|
||||||
@ -1847,7 +1849,11 @@ struct drm_dp_aux_cec {
|
|||||||
* @transfer: transfers a message representing a single AUX transaction
|
* @transfer: transfers a message representing a single AUX transaction
|
||||||
*
|
*
|
||||||
* The @dev field should be set to a pointer to the device that implements the
|
* The @dev field should be set to a pointer to the device that implements the
|
||||||
* AUX channel.
|
* AUX channel. As well, the @drm_dev field should be set to the &drm_device
|
||||||
|
* that will be using this AUX channel as early as possible. For many graphics
|
||||||
|
* drivers this should happen before drm_dp_aux_init(), however it's perfectly
|
||||||
|
* fine to set this field later so long as it's assigned before calling
|
||||||
|
* drm_dp_aux_register().
|
||||||
*
|
*
|
||||||
* The @name field may be used to specify the name of the I2C adapter. If set to
|
* The @name field may be used to specify the name of the I2C adapter. If set to
|
||||||
* %NULL, dev_name() of @dev will be used.
|
* %NULL, dev_name() of @dev will be used.
|
||||||
@ -1879,6 +1885,7 @@ struct drm_dp_aux {
|
|||||||
const char *name;
|
const char *name;
|
||||||
struct i2c_adapter ddc;
|
struct i2c_adapter ddc;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct drm_device *drm_dev;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct mutex hw_mutex;
|
struct mutex hw_mutex;
|
||||||
struct work_struct crc_work;
|
struct work_struct crc_work;
|
||||||
|
Loading…
Reference in New Issue
Block a user