@@ -97,7 +97,6 @@ struct ufx_data {
97
97
struct kref kref ;
98
98
int fb_count ;
99
99
bool virtualized ; /* true when physical usb device not present */
100
- struct delayed_work free_framebuffer_work ;
101
100
atomic_t usb_active ; /* 0 = update virtual buffer, but no usb traffic */
102
101
atomic_t lost_pixels ; /* 1 = a render op failed. Need screen refresh */
103
102
u8 * edid ; /* null until we read edid from hw or get from sysfs */
@@ -1117,15 +1116,24 @@ static void ufx_free(struct kref *kref)
1117
1116
{
1118
1117
struct ufx_data * dev = container_of (kref , struct ufx_data , kref );
1119
1118
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
+ }
1123
1121
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 ;
1125
1126
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 );
1127
1134
}
1128
1135
1136
+
1129
1137
static void ufx_release_urb_work (struct work_struct * work )
1130
1138
{
1131
1139
struct urb_node * unode = container_of (work , struct urb_node ,
@@ -1134,14 +1142,9 @@ static void ufx_release_urb_work(struct work_struct *work)
1134
1142
up (& unode -> dev -> urbs .limit_sem );
1135
1143
}
1136
1144
1137
- static void ufx_free_framebuffer_work (struct work_struct * work )
1145
+ static void ufx_free_framebuffer (struct ufx_data * dev )
1138
1146
{
1139
- struct ufx_data * dev = container_of (work , struct ufx_data ,
1140
- free_framebuffer_work .work );
1141
1147
struct fb_info * info = dev -> info ;
1142
- int node = info -> node ;
1143
-
1144
- unregister_framebuffer (info );
1145
1148
1146
1149
if (info -> cmap .len != 0 )
1147
1150
fb_dealloc_cmap (& info -> cmap );
@@ -1153,11 +1156,6 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
1153
1156
1154
1157
dev -> info = NULL ;
1155
1158
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
-
1161
1159
/* ref taken in probe() as part of registering framebfufer */
1162
1160
kref_put (& dev -> kref , ufx_free );
1163
1161
}
@@ -1169,11 +1167,13 @@ static int ufx_ops_release(struct fb_info *info, int user)
1169
1167
{
1170
1168
struct ufx_data * dev = info -> par ;
1171
1169
1170
+ mutex_lock (& disconnect_mutex );
1171
+
1172
1172
dev -> fb_count -- ;
1173
1173
1174
1174
/* We can't free fb_info here - fbmem will touch it when we return */
1175
1175
if (dev -> virtualized && (dev -> fb_count == 0 ))
1176
- schedule_delayed_work ( & dev -> free_framebuffer_work , HZ );
1176
+ ufx_free_framebuffer ( dev );
1177
1177
1178
1178
if ((dev -> fb_count == 0 ) && (info -> fbdefio )) {
1179
1179
fb_deferred_io_cleanup (info );
@@ -1186,6 +1186,8 @@ static int ufx_ops_release(struct fb_info *info, int user)
1186
1186
1187
1187
kref_put (& dev -> kref , ufx_free );
1188
1188
1189
+ mutex_unlock (& disconnect_mutex );
1190
+
1189
1191
return 0 ;
1190
1192
}
1191
1193
@@ -1292,6 +1294,7 @@ static const struct fb_ops ufx_ops = {
1292
1294
.fb_blank = ufx_ops_blank ,
1293
1295
.fb_check_var = ufx_ops_check_var ,
1294
1296
.fb_set_par = ufx_ops_set_par ,
1297
+ .fb_destroy = ufx_ops_destory ,
1295
1298
};
1296
1299
1297
1300
/* Assumes &info->lock held by caller
@@ -1673,9 +1676,6 @@ static int ufx_usb_probe(struct usb_interface *interface,
1673
1676
goto destroy_modedb ;
1674
1677
}
1675
1678
1676
- INIT_DELAYED_WORK (& dev -> free_framebuffer_work ,
1677
- ufx_free_framebuffer_work );
1678
-
1679
1679
retval = ufx_reg_read (dev , 0x3000 , & id_rev );
1680
1680
check_warn_goto_error (retval , "error %d reading 0x3000 register from device" , retval );
1681
1681
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,
1748
1748
static void ufx_usb_disconnect (struct usb_interface * interface )
1749
1749
{
1750
1750
struct ufx_data * dev ;
1751
+ struct fb_info * info ;
1751
1752
1752
1753
mutex_lock (& disconnect_mutex );
1753
1754
1754
1755
dev = usb_get_intfdata (interface );
1756
+ info = dev -> info ;
1755
1757
1756
1758
pr_debug ("USB disconnect starting\n" );
1757
1759
@@ -1765,12 +1767,15 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
1765
1767
1766
1768
/* if clients still have us open, will be freed on last close */
1767
1769
if (dev -> fb_count == 0 )
1768
- schedule_delayed_work ( & dev -> free_framebuffer_work , 0 );
1770
+ ufx_free_framebuffer ( dev );
1769
1771
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 );
1772
1775
1773
- /* consider ufx_data freed */
1776
+ pr_debug ("freeing ufx_data %p" , dev );
1777
+
1778
+ unregister_framebuffer (info );
1774
1779
1775
1780
mutex_unlock (& disconnect_mutex );
1776
1781
}
0 commit comments