bool te_enabled;
+ struct workqueue_struct *workqueue;
+
struct work_struct framedone_work;
void (*framedone_callback)(int, void *);
void *framedone_data;
unsigned packet_payload;
unsigned packet_len;
u32 l;
+ int r;
const unsigned channel = dsi.update_channel;
/* line buffer is 1024 x 24bits */
/* XXX: for some reason using full buffer size causes considerable TX
dsi_perf_mark_start();
- schedule_delayed_work(&dsi.framedone_timeout_work,
+ r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work,
msecs_to_jiffies(250));
+ BUG_ON(r == 0);
dss_start_update(dssdev);
DSSERR("Framedone not received for 250ms!\n");
+ /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after
+ * 250ms which would conflict with this timeout work. What should be
+ * done is first cancel the transfer on the HW, and then cancel the
+ * possibly scheduled framedone work */
+
/* SIDLEMODE back to smart-idle */
dispc_enable_sidle();
static void dsi_framedone_irq_callback(void *data, u32 mask)
{
+ int r;
/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
* turns itself off. However, DSI still has the pixels in its buffers,
* and is sending the data.
/* SIDLEMODE back to smart-idle */
dispc_enable_sidle();
- schedule_work(&dsi.framedone_work);
+ r = queue_work(dsi.workqueue, &dsi.framedone_work);
+ BUG_ON(r == 0);
}
static void dsi_handle_framedone(void)
mutex_init(&dsi.lock);
sema_init(&dsi.bus_lock, 1);
+ dsi.workqueue = create_singlethread_workqueue("dsi");
+ if (dsi.workqueue == NULL)
+ return -ENOMEM;
+
INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback);
INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
dsi_framedone_timeout_work_callback);
err2:
iounmap(dsi.base);
err1:
+ destroy_workqueue(dsi.workqueue);
return r;
}
{
iounmap(dsi.base);
+ destroy_workqueue(dsi.workqueue);
+
DSSDBG("omap_dsi_exit\n");
}