diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-02-02 21:56:16 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-02-20 01:00:50 -0500 |
commit | 4f47643dbb4c345c5beebe53588682a7ff2c872a (patch) | |
tree | 824b98893e562bedab63d6987c1d248332b45f3f /drivers/gpu/drm/nouveau/nouveau_connector.c | |
parent | 0f0800661a125ddb038462570c869fe6f8ab5737 (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.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)"); | |||
55 | static int nouveau_duallink = 1; | 55 | static int nouveau_duallink = 1; |
56 | module_param_named(duallink, nouveau_duallink, int, 0400); | 56 | module_param_named(duallink, nouveau_duallink, int, 0400); |
57 | 57 | ||
58 | static void nouveau_connector_hotplug(void *, int); | ||
59 | |||
60 | struct nouveau_encoder * | 58 | struct nouveau_encoder * |
61 | find_encoder(struct drm_connector *connector, int type) | 59 | find_encoder(struct drm_connector *connector, int type) |
62 | { | 60 | { |
@@ -100,22 +98,6 @@ static void | |||
100 | nouveau_connector_destroy(struct drm_connector *connector) | 98 | nouveau_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 | ||
897 | static void | ||
898 | nouveau_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 | |||
919 | static int | ||
920 | nouveau_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 | |||
915 | static int | 928 | static int |
916 | drm_conntype_from_dcb(enum dcb_connector_type dcb) | 929 | drm_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 | |||
1143 | static void | ||
1144 | nouveau_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 | } | ||