[PATCH 1/2] firedtv: replace tasklet by workqueue job
Stefan Richter
stefanr at s5r6.in-berlin.de
Mon Aug 25 15:11:28 PDT 2008
Non-atomic context is a lot nicer to work with.
Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
---
This completes the sem2mutex conversion which I sent last weekend, and
it prepares for fixing up the remote control handling.
drivers/media/dvb/firesat/avc_api.c | 57 ++++-------------------
drivers/media/dvb/firesat/avc_api.h | 1
drivers/media/dvb/firesat/firesat.h | 4 -
drivers/media/dvb/firesat/firesat_1394.c | 4 +
4 files changed, 18 insertions(+), 48 deletions(-)
Index: linux/drivers/media/dvb/firesat/avc_api.c
===================================================================
--- linux.orig/drivers/media/dvb/firesat/avc_api.c
+++ linux/drivers/media/dvb/firesat/avc_api.c
@@ -17,6 +17,7 @@
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <ieee1394_transactions.h>
@@ -34,8 +35,6 @@ static unsigned int avc_comm_debug = 0;
module_param(avc_comm_debug, int, 0644);
MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)");
-static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
-
/* Frees an allocated packet */
static void avc_free_packet(struct hpsb_packet *packet)
{
@@ -251,34 +250,8 @@ int AVCWrite(struct firesat*firesat, con
return ret;
}
-#if 0 /* FIXME: This should probably be a workqueue job. */
-static void do_schedule_remotecontrol(unsigned long ignored);
-DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0);
-
-static void do_schedule_remotecontrol(unsigned long ignored) {
- struct firesat *firesat;
- unsigned long flags;
-
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_for_each_entry(firesat,&firesat_list,list) {
- if(atomic_read(&firesat->reschedule_remotecontrol) == 1) {
- if(down_trylock(&firesat->avc_sem))
- tasklet_schedule(&schedule_remotecontrol);
- else {
- if(__AVCRegisterRemoteControl(firesat, 1) == 0)
- atomic_set(&firesat->reschedule_remotecontrol, 0);
- else
- tasklet_schedule(&schedule_remotecontrol);
-
- up(&firesat->avc_sem);
- }
- }
- }
- spin_unlock_irqrestore(&firesat_list_lock, flags);
-}
-#endif
-
-int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
+int AVCRecv(struct firesat *firesat, u8 *data, size_t length)
+{
// printk(KERN_INFO "%s\n",__func__);
// remote control handling
@@ -294,10 +267,7 @@ int AVCRecv(struct firesat *firesat, u8
if(RspFrm->resp == CHANGED) {
// printk(KERN_INFO "%s: code = %02x %02x\n",__func__,RspFrm->operand[4],RspFrm->operand[5]);
firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5]));
-
- // schedule
- atomic_set(&firesat->reschedule_remotecontrol, 1);
- tasklet_schedule(&schedule_remotecontrol);
+ schedule_work(&firesat->remote_ctrl_work);
} else if(RspFrm->resp != INTERIM)
printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp);
return 0;
@@ -910,7 +880,7 @@ int AVCSubUnitInfo(struct firesat *fires
return 0;
}
-static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal)
+int AVCRegisterRemoteControl(struct firesat *firesat)
{
AVCCmdFrm CmdFrm;
@@ -931,19 +901,16 @@ static int __AVCRegisterRemoteControl(st
CmdFrm.length = 8;
- if(internal) {
- if(__AVCWrite(firesat,&CmdFrm,NULL) < 0)
- return -EIO;
- } else
- if(AVCWrite(firesat,&CmdFrm,NULL) < 0)
- return -EIO;
-
- return 0;
+ return AVCWrite(firesat, &CmdFrm, NULL);
}
-int AVCRegisterRemoteControl(struct firesat*firesat)
+void avc_remote_ctrl_work(struct work_struct *work)
{
- return __AVCRegisterRemoteControl(firesat, 0);
+ struct firesat *firesat =
+ container_of(work, struct firesat, remote_ctrl_work);
+
+ /* Should it be rescheduled in failure cases? */
+ AVCRegisterRemoteControl(firesat);
}
int AVCTuner_Host2Ca(struct firesat *firesat)
Index: linux/drivers/media/dvb/firesat/avc_api.h
===================================================================
--- linux.orig/drivers/media/dvb/firesat/avc_api.h
+++ linux/drivers/media/dvb/firesat/avc_api.h
@@ -432,6 +432,7 @@ int AVCLNBControl(struct firesat *firesa
char conttone, char nrdiseq,
struct dvb_diseqc_master_cmd *diseqcmd);
int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
+void avc_remote_ctrl_work(struct work_struct *work);
int AVCRegisterRemoteControl(struct firesat *firesat);
int AVCTuner_Host2Ca(struct firesat *firesat);
int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length);
Index: linux/drivers/media/dvb/firesat/firesat.h
===================================================================
--- linux.orig/drivers/media/dvb/firesat/firesat.h
+++ linux/drivers/media/dvb/firesat/firesat.h
@@ -20,6 +20,7 @@
#include <linux/spinlock_types.h>
#include <linux/types.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <demux.h>
@@ -149,8 +150,7 @@ struct firesat {
struct mutex avc_mutex;
wait_queue_head_t avc_wait;
atomic_t avc_reply_received;
-
- atomic_t reschedule_remotecontrol;
+ struct work_struct remote_ctrl_work;
struct firesat_channel {
struct firesat *firesat;
Index: linux/drivers/media/dvb/firesat/firesat_1394.c
===================================================================
--- linux.orig/drivers/media/dvb/firesat/firesat_1394.c
+++ linux/drivers/media/dvb/firesat/firesat_1394.c
@@ -182,7 +182,7 @@ static int firesat_probe(struct device *
init_waitqueue_head(&firesat->avc_wait);
atomic_set(&firesat->avc_reply_received, 1);
mutex_init(&firesat->demux_mutex);
- atomic_set(&firesat->reschedule_remotecontrol, 0);
+ INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work);
spin_lock_irqsave(&firesat_list_lock, flags);
INIT_LIST_HEAD(&firesat->list);
@@ -268,6 +268,8 @@ static int firesat_remove(struct device
list_del(&firesats[k]->list);
spin_unlock_irqrestore(&firesat_list_lock, flags);
+ cancel_work_sync(&firesats[k]->remote_ctrl_work);
+
kfree(firesats[k]->fe);
kfree(firesats[k]->adapter);
kfree(firesats[k]->respfrm);
--
Stefan Richter
-=====-==--- =--- ==-=-
http://arcgraph.de/sr/
More information about the devel
mailing list