@@ -101,6 +101,7 @@ static int nv_drm_revoke_modeset_permission(struct drm_device *dev,
101101 NvU32 dpyId );
102102static int nv_drm_revoke_sub_ownership (struct drm_device * dev );
103103
104+ static DEFINE_MUTEX (dev_list_mutex );
104105static struct nv_drm_device * dev_list = NULL ;
105106
106107static const char * nv_get_input_colorspace_name (
@@ -2067,8 +2068,10 @@ void nv_drm_register_drm_device(const struct NvKmsKapiGpuInfo *gpu_info)
20672068
20682069 /* Add NVIDIA-DRM device into list */
20692070
2071+ mutex_lock (& dev_list_mutex );
20702072 nv_dev -> next = dev_list ;
20712073 dev_list = nv_dev ;
2074+ mutex_unlock (& dev_list_mutex );
20722075
20732076 return ; /* Success */
20742077
@@ -2106,22 +2109,81 @@ int nv_drm_probe_devices(void)
21062109}
21072110#endif
21082111
2112+ static struct nv_drm_device *
2113+ nv_drm_pop_device (void )
2114+ {
2115+ struct nv_drm_device * nv_dev ;
2116+
2117+ mutex_lock (& dev_list_mutex );
2118+
2119+ nv_dev = dev_list ;
2120+ if (nv_dev ) {
2121+ dev_list = nv_dev -> next ;
2122+ nv_dev -> next = NULL ;
2123+ }
2124+
2125+ mutex_unlock (& dev_list_mutex );
2126+ return nv_dev ;
2127+ }
2128+
2129+ static struct nv_drm_device *
2130+ nv_drm_find_and_remove_device (NvU32 gpuId )
2131+ {
2132+ struct nv_drm_device * * pPrev = & dev_list ;
2133+ struct nv_drm_device * nv_dev ;
2134+
2135+ mutex_lock (& dev_list_mutex );
2136+ nv_dev = * pPrev ;
2137+
2138+ while (nv_dev ) {
2139+ if (nv_dev -> gpu_info .gpu_id == gpuId ) {
2140+ /* Remove it from the linked list */
2141+ * pPrev = nv_dev -> next ;
2142+ nv_dev -> next = NULL ;
2143+ break ;
2144+ }
2145+
2146+ pPrev = & nv_dev -> next ;
2147+ nv_dev = * pPrev ;
2148+ }
2149+
2150+ mutex_unlock (& dev_list_mutex );
2151+ return nv_dev ;
2152+ }
2153+
2154+ static void nv_drm_dev_destroy (struct nv_drm_device * nv_dev )
2155+ {
2156+ struct drm_device * dev = nv_dev -> dev ;
2157+
2158+ nv_drm_dev_unload (dev );
2159+ drm_dev_put (dev );
2160+ nv_drm_free (nv_dev );
2161+ }
2162+
21092163/*
2110- * Unregister all NVIDIA DRM devices .
2164+ * Unregister a single NVIDIA DRM device .
21112165 */
2112- void nv_drm_remove_devices ( void )
2166+ void nv_drm_remove ( NvU32 gpuId )
21132167{
2114- while (dev_list != NULL ) {
2115- struct nv_drm_device * next = dev_list -> next ;
2116- struct drm_device * dev = dev_list -> dev ;
2168+ struct nv_drm_device * nv_dev = nv_drm_find_and_remove_device (gpuId );
21172169
2118- drm_dev_unregister (dev );
2119- nv_drm_dev_unload (dev );
2120- drm_dev_put (dev );
2170+ if (nv_dev ) {
2171+ NV_DRM_DEV_LOG_INFO (nv_dev , "Removing device" );
2172+ drm_dev_unplug (nv_dev -> dev );
2173+ nv_drm_dev_destroy (nv_dev );
2174+ }
2175+ }
21212176
2122- nv_drm_free (dev_list );
2177+ /*
2178+ * Unregister all NVIDIA DRM devices.
2179+ */
2180+ void nv_drm_remove_devices (void )
2181+ {
2182+ struct nv_drm_device * nv_dev ;
21232183
2124- dev_list = next ;
2184+ while ((nv_dev = nv_drm_pop_device ())) {
2185+ drm_dev_unregister (nv_dev -> dev );
2186+ nv_drm_dev_destroy (nv_dev );
21252187 }
21262188}
21272189
@@ -2143,11 +2205,10 @@ void nv_drm_remove_devices(void)
21432205 */
21442206void nv_drm_suspend_resume (NvBool suspend )
21452207{
2146- static DEFINE_MUTEX (nv_drm_suspend_mutex );
21472208 static NvU32 nv_drm_suspend_count = 0 ;
21482209 struct nv_drm_device * nv_dev ;
21492210
2150- mutex_lock (& nv_drm_suspend_mutex );
2211+ mutex_lock (& dev_list_mutex );
21512212
21522213 /*
21532214 * Count the number of times the driver is asked to suspend. Suspend all DRM
@@ -2195,7 +2256,7 @@ void nv_drm_suspend_resume(NvBool suspend)
21952256 }
21962257
21972258done :
2198- mutex_unlock (& nv_drm_suspend_mutex );
2259+ mutex_unlock (& dev_list_mutex );
21992260}
22002261
22012262#endif /* NV_DRM_AVAILABLE */
0 commit comments