|
@@ -55,8 +55,6 @@ MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)");
|
|
|
static int nouveau_duallink = 1;
|
|
|
module_param_named(duallink, nouveau_duallink, int, 0400);
|
|
|
|
|
|
-static void nouveau_connector_hotplug(void *, int);
|
|
|
-
|
|
|
struct nouveau_encoder *
|
|
|
find_encoder(struct drm_connector *connector, int type)
|
|
|
{
|
|
@@ -100,22 +98,6 @@ static void
|
|
|
nouveau_connector_destroy(struct drm_connector *connector)
|
|
|
{
|
|
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
|
|
- struct nouveau_gpio *gpio;
|
|
|
- struct nouveau_drm *drm;
|
|
|
- struct drm_device *dev;
|
|
|
-
|
|
|
- if (!nv_connector)
|
|
|
- return;
|
|
|
-
|
|
|
- dev = nv_connector->base.dev;
|
|
|
- drm = nouveau_drm(dev);
|
|
|
- gpio = nouveau_gpio(drm->device);
|
|
|
-
|
|
|
- if (gpio && nv_connector->hpd.func != DCB_GPIO_UNUSED) {
|
|
|
- gpio->isr_del(gpio, 0, nv_connector->hpd.func, 0xff,
|
|
|
- nouveau_connector_hotplug, connector);
|
|
|
- }
|
|
|
-
|
|
|
kfree(nv_connector->edid);
|
|
|
drm_sysfs_connector_remove(connector);
|
|
|
drm_connector_cleanup(connector);
|
|
@@ -912,6 +894,37 @@ nouveau_connector_funcs_lvds = {
|
|
|
.force = nouveau_connector_force
|
|
|
};
|
|
|
|
|
|
+static void
|
|
|
+nouveau_connector_hotplug_work(struct work_struct *work)
|
|
|
+{
|
|
|
+ struct nouveau_connector *nv_connector =
|
|
|
+ container_of(work, struct nouveau_connector, hpd_work);
|
|
|
+ struct drm_connector *connector = &nv_connector->base;
|
|
|
+ struct drm_device *dev = connector->dev;
|
|
|
+ struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
|
|
|
+ bool plugged = gpio->get(gpio, 0, nv_connector->hpd.func, 0xff);
|
|
|
+
|
|
|
+ NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un",
|
|
|
+ drm_get_connector_name(connector));
|
|
|
+
|
|
|
+ if (plugged)
|
|
|
+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
|
|
+ else
|
|
|
+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
|
|
+
|
|
|
+ drm_helper_hpd_irq_event(dev);
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+nouveau_connector_hotplug(struct nouveau_eventh *event, int index)
|
|
|
+{
|
|
|
+ struct nouveau_connector *nv_connector =
|
|
|
+ container_of(event, struct nouveau_connector, hpd_func);
|
|
|
+ schedule_work(&nv_connector->hpd_work);
|
|
|
+ return NVKM_EVENT_KEEP;
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
drm_conntype_from_dcb(enum dcb_connector_type dcb)
|
|
|
{
|
|
@@ -962,6 +975,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
connector = &nv_connector->base;
|
|
|
+ INIT_WORK(&nv_connector->hpd_work, nouveau_connector_hotplug_work);
|
|
|
nv_connector->index = index;
|
|
|
|
|
|
/* attempt to parse vbios connector type and hotplug gpio */
|
|
@@ -978,6 +992,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
|
|
|
|
|
|
ret = gpio->find(gpio, 0, hpd[ffs((entry & 0x07033000) >> 12)],
|
|
|
DCB_GPIO_UNUSED, &nv_connector->hpd);
|
|
|
+ nv_connector->hpd_func.func = nouveau_connector_hotplug;
|
|
|
if (ret)
|
|
|
nv_connector->hpd.func = DCB_GPIO_UNUSED;
|
|
|
|
|
@@ -1129,31 +1144,9 @@ nouveau_connector_create(struct drm_device *dev, int index)
|
|
|
}
|
|
|
|
|
|
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
|
|
- if (gpio && nv_connector->hpd.func != DCB_GPIO_UNUSED) {
|
|
|
- ret = gpio->isr_add(gpio, 0, nv_connector->hpd.func, 0xff,
|
|
|
- nouveau_connector_hotplug, connector);
|
|
|
- if (ret == 0)
|
|
|
- connector->polled = DRM_CONNECTOR_POLL_HPD;
|
|
|
- }
|
|
|
+ if (nv_connector->hpd.func != DCB_GPIO_UNUSED)
|
|
|
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
|
|
|
|
|
|
drm_sysfs_connector_add(connector);
|
|
|
return connector;
|
|
|
}
|
|
|
-
|
|
|
-static void
|
|
|
-nouveau_connector_hotplug(void *data, int plugged)
|
|
|
-{
|
|
|
- struct drm_connector *connector = data;
|
|
|
- struct drm_device *dev = connector->dev;
|
|
|
- struct nouveau_drm *drm = nouveau_drm(dev);
|
|
|
-
|
|
|
- NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un",
|
|
|
- drm_get_connector_name(connector));
|
|
|
-
|
|
|
- if (plugged)
|
|
|
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
|
|
- else
|
|
|
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
|
|
-
|
|
|
- drm_helper_hpd_irq_event(dev);
|
|
|
-}
|