diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-02-03 03:56:16 +0100 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-02-20 07:00:50 +0100 |
commit | 4f47643dbb4c345c5beebe53588682a7ff2c872a (patch) | |
tree | 824b98893e562bedab63d6987c1d248332b45f3f /drivers/gpu/drm/nouveau/nouveau_connector.c | |
parent | drm/nouveau/gpio: pass number of on-die gpio lines to base (diff) | |
download | linux-4f47643dbb4c345c5beebe53588682a7ff2c872a.tar.xz linux-4f47643dbb4c345c5beebe53588682a7ff2c872a.zip |
drm/nouveau/gpio: use event interfaces for interrupt signalling
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_connector.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 77 |
1 files changed, 35 insertions, 42 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index a64e8777cbe9..9c4b3f5fba01 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -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); -} |