@@ -97,7 +97,6 @@ struct ufx_data {
9797 struct kref kref ;
9898 int fb_count ;
9999 bool virtualized ; /* true when physical usb device not present */
100- struct delayed_work free_framebuffer_work ;
101100 atomic_t usb_active ; /* 0 = update virtual buffer, but no usb traffic */
102101 atomic_t lost_pixels ; /* 1 = a render op failed. Need screen refresh */
103102 u8 * edid ; /* null until we read edid from hw or get from sysfs */
@@ -1117,15 +1116,24 @@ static void ufx_free(struct kref *kref)
11171116{
11181117 struct ufx_data * dev = container_of (kref , struct ufx_data , kref );
11191118
1120- /* this function will wait for all in-flight urbs to complete */
1121- if (dev -> urbs .count > 0 )
1122- ufx_free_urb_list (dev );
1119+ kfree (dev );
1120+ }
11231121
1124- pr_debug ("freeing ufx_data %p" , dev );
1122+ static void ufx_ops_destory (struct fb_info * info )
1123+ {
1124+ struct ufx_data * dev = info -> par ;
1125+ int node = info -> node ;
11251126
1126- kfree (dev );
1127+ /* Assume info structure is freed after this point */
1128+ framebuffer_release (info );
1129+
1130+ pr_debug ("fb_info for /dev/fb%d has been freed" , node );
1131+
1132+ /* release reference taken by kref_init in probe() */
1133+ kref_put (& dev -> kref , ufx_free );
11271134}
11281135
1136+
11291137static void ufx_release_urb_work (struct work_struct * work )
11301138{
11311139 struct urb_node * unode = container_of (work , struct urb_node ,
@@ -1134,14 +1142,9 @@ static void ufx_release_urb_work(struct work_struct *work)
11341142 up (& unode -> dev -> urbs .limit_sem );
11351143}
11361144
1137- static void ufx_free_framebuffer_work (struct work_struct * work )
1145+ static void ufx_free_framebuffer (struct ufx_data * dev )
11381146{
1139- struct ufx_data * dev = container_of (work , struct ufx_data ,
1140- free_framebuffer_work .work );
11411147 struct fb_info * info = dev -> info ;
1142- int node = info -> node ;
1143-
1144- unregister_framebuffer (info );
11451148
11461149 if (info -> cmap .len != 0 )
11471150 fb_dealloc_cmap (& info -> cmap );
@@ -1153,11 +1156,6 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
11531156
11541157 dev -> info = NULL ;
11551158
1156- /* Assume info structure is freed after this point */
1157- framebuffer_release (info );
1158-
1159- pr_debug ("fb_info for /dev/fb%d has been freed" , node );
1160-
11611159 /* ref taken in probe() as part of registering framebfufer */
11621160 kref_put (& dev -> kref , ufx_free );
11631161}
@@ -1169,11 +1167,13 @@ static int ufx_ops_release(struct fb_info *info, int user)
11691167{
11701168 struct ufx_data * dev = info -> par ;
11711169
1170+ mutex_lock (& disconnect_mutex );
1171+
11721172 dev -> fb_count -- ;
11731173
11741174 /* We can't free fb_info here - fbmem will touch it when we return */
11751175 if (dev -> virtualized && (dev -> fb_count == 0 ))
1176- schedule_delayed_work ( & dev -> free_framebuffer_work , HZ );
1176+ ufx_free_framebuffer ( dev );
11771177
11781178 if ((dev -> fb_count == 0 ) && (info -> fbdefio )) {
11791179 fb_deferred_io_cleanup (info );
@@ -1186,6 +1186,8 @@ static int ufx_ops_release(struct fb_info *info, int user)
11861186
11871187 kref_put (& dev -> kref , ufx_free );
11881188
1189+ mutex_unlock (& disconnect_mutex );
1190+
11891191 return 0 ;
11901192}
11911193
@@ -1292,6 +1294,7 @@ static const struct fb_ops ufx_ops = {
12921294 .fb_blank = ufx_ops_blank ,
12931295 .fb_check_var = ufx_ops_check_var ,
12941296 .fb_set_par = ufx_ops_set_par ,
1297+ .fb_destroy = ufx_ops_destory ,
12951298};
12961299
12971300/* Assumes &info->lock held by caller
@@ -1673,9 +1676,6 @@ static int ufx_usb_probe(struct usb_interface *interface,
16731676 goto destroy_modedb ;
16741677 }
16751678
1676- INIT_DELAYED_WORK (& dev -> free_framebuffer_work ,
1677- ufx_free_framebuffer_work );
1678-
16791679 retval = ufx_reg_read (dev , 0x3000 , & id_rev );
16801680 check_warn_goto_error (retval , "error %d reading 0x3000 register from device" , retval );
16811681 dev_dbg (dev -> gdev , "ID_REV register value 0x%08x" , id_rev );
@@ -1748,10 +1748,12 @@ static int ufx_usb_probe(struct usb_interface *interface,
17481748static void ufx_usb_disconnect (struct usb_interface * interface )
17491749{
17501750 struct ufx_data * dev ;
1751+ struct fb_info * info ;
17511752
17521753 mutex_lock (& disconnect_mutex );
17531754
17541755 dev = usb_get_intfdata (interface );
1756+ info = dev -> info ;
17551757
17561758 pr_debug ("USB disconnect starting\n" );
17571759
@@ -1765,12 +1767,15 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
17651767
17661768 /* if clients still have us open, will be freed on last close */
17671769 if (dev -> fb_count == 0 )
1768- schedule_delayed_work ( & dev -> free_framebuffer_work , 0 );
1770+ ufx_free_framebuffer ( dev );
17691771
1770- /* release reference taken by kref_init in probe() */
1771- kref_put (& dev -> kref , ufx_free );
1772+ /* this function will wait for all in-flight urbs to complete */
1773+ if (dev -> urbs .count > 0 )
1774+ ufx_free_urb_list (dev );
17721775
1773- /* consider ufx_data freed */
1776+ pr_debug ("freeing ufx_data %p" , dev );
1777+
1778+ unregister_framebuffer (info );
17741779
17751780 mutex_unlock (& disconnect_mutex );
17761781}
0 commit comments