aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_connector.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-02-02 21:56:16 -0500
committerBen Skeggs <bskeggs@redhat.com>2013-02-20 01:00:50 -0500
commit4f47643dbb4c345c5beebe53588682a7ff2c872a (patch)
tree824b98893e562bedab63d6987c1d248332b45f3f /drivers/gpu/drm/nouveau/nouveau_connector.c
parent0f0800661a125ddb038462570c869fe6f8ab5737 (diff)
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.c77
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)");
55static int nouveau_duallink = 1; 55static int nouveau_duallink = 1;
56module_param_named(duallink, nouveau_duallink, int, 0400); 56module_param_named(duallink, nouveau_duallink, int, 0400);
57 57
58static void nouveau_connector_hotplug(void *, int);
59
60struct nouveau_encoder * 58struct nouveau_encoder *
61find_encoder(struct drm_connector *connector, int type) 59find_encoder(struct drm_connector *connector, int type)
62{ 60{
@@ -100,22 +98,6 @@ static void
100nouveau_connector_destroy(struct drm_connector *connector) 98nouveau_connector_destroy(struct drm_connector *connector)
101{ 99{
102 struct nouveau_connector *nv_connector = nouveau_connector(connector); 100 struct nouveau_connector *nv_connector = nouveau_connector(connector);
103 struct nouveau_gpio *gpio;
104 struct nouveau_drm *drm;
105 struct drm_device *dev;
106
107 if (!nv_connector)
108 return;
109
110 dev = nv_connector->base.dev;
111 drm = nouveau_drm(dev);
112 gpio = nouveau_gpio(drm->device);
113
114 if (gpio && nv_connector->hpd.func != DCB_GPIO_UNUSED) {
115 gpio->isr_del(gpio, 0, nv_connector->hpd.func, 0xff,
116 nouveau_connector_hotplug, connector);
117 }
118
119 kfree(nv_connector->edid); 101 kfree(nv_connector->edid);
120 drm_sysfs_connector_remove(connector); 102 drm_sysfs_connector_remove(connector);
121 drm_connector_cleanup(connector); 103 drm_connector_cleanup(connector);
@@ -912,6 +894,37 @@ nouveau_connector_funcs_lvds = {
912 .force = nouveau_connector_force 894 .force = nouveau_connector_force
913}; 895};
914 896
897static void
898nouveau_connector_hotplug_work(struct work_struct *work)
899{
900 struct nouveau_connector *nv_connector =
901 container_of(work, struct nouveau_connector, hpd_work);
902 struct drm_connector *connector = &nv_connector->base;
903 struct drm_device *dev = connector->dev;
904 struct nouveau_drm *drm = nouveau_drm(dev);
905 struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
906 bool plugged = gpio->get(gpio, 0, nv_connector->hpd.func, 0xff);
907
908 NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un",
909 drm_get_connector_name(connector));
910
911 if (plugged)
912 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
913 else
914 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
915
916 drm_helper_hpd_irq_event(dev);
917}
918
919static int
920nouveau_connector_hotplug(struct nouveau_eventh *event, int index)
921{
922 struct nouveau_connector *nv_connector =
923 container_of(event, struct nouveau_connector, hpd_func);
924 schedule_work(&nv_connector->hpd_work);
925 return NVKM_EVENT_KEEP;
926}
927
915static int 928static int
916drm_conntype_from_dcb(enum dcb_connector_type dcb) 929drm_conntype_from_dcb(enum dcb_connector_type dcb)
917{ 930{
@@ -962,6 +975,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
962 return ERR_PTR(-ENOMEM); 975 return ERR_PTR(-ENOMEM);
963 976
964 connector = &nv_connector->base; 977 connector = &nv_connector->base;
978 INIT_WORK(&nv_connector->hpd_work, nouveau_connector_hotplug_work);
965 nv_connector->index = index; 979 nv_connector->index = index;
966 980
967 /* attempt to parse vbios connector type and hotplug gpio */ 981 /* attempt to parse vbios connector type and hotplug gpio */
@@ -978,6 +992,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
978 992
979 ret = gpio->find(gpio, 0, hpd[ffs((entry & 0x07033000) >> 12)], 993 ret = gpio->find(gpio, 0, hpd[ffs((entry & 0x07033000) >> 12)],
980 DCB_GPIO_UNUSED, &nv_connector->hpd); 994 DCB_GPIO_UNUSED, &nv_connector->hpd);
995 nv_connector->hpd_func.func = nouveau_connector_hotplug;
981 if (ret) 996 if (ret)
982 nv_connector->hpd.func = DCB_GPIO_UNUSED; 997 nv_connector->hpd.func = DCB_GPIO_UNUSED;
983 998
@@ -1129,31 +1144,9 @@ nouveau_connector_create(struct drm_device *dev, int index)
1129 } 1144 }
1130 1145
1131 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1146 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1132 if (gpio && nv_connector->hpd.func != DCB_GPIO_UNUSED) { 1147 if (nv_connector->hpd.func != DCB_GPIO_UNUSED)
1133 ret = gpio->isr_add(gpio, 0, nv_connector->hpd.func, 0xff, 1148 connector->polled = DRM_CONNECTOR_POLL_HPD;
1134 nouveau_connector_hotplug, connector);
1135 if (ret == 0)
1136 connector->polled = DRM_CONNECTOR_POLL_HPD;
1137 }
1138 1149
1139 drm_sysfs_connector_add(connector); 1150 drm_sysfs_connector_add(connector);
1140 return connector; 1151 return connector;
1141} 1152}
1142
1143static void
1144nouveau_connector_hotplug(void *data, int plugged)
1145{
1146 struct drm_connector *connector = data;
1147 struct drm_device *dev = connector->dev;
1148 struct nouveau_drm *drm = nouveau_drm(dev);
1149
1150 NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un",
1151 drm_get_connector_name(connector));
1152
1153 if (plugged)
1154 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
1155 else
1156 drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
1157
1158 drm_helper_hpd_irq_event(dev);
1159}