diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-07-29 15:41:40 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-07-29 15:41:40 -0300 |
commit | 9a9f822910db8450c5478fd7146b5b52088d7aaa (patch) | |
tree | 9b588f2096c3b7351e4c127a2c8ffbc8b45a6c55 /linux/drivers/media/dvb/dvb-core | |
parent | 7272f8f51ed77805115b9716b72ab4b6d3db0049 (diff) | |
parent | f7eb6e544385a7d7a594e4bedb982e39a500a838 (diff) | |
download | mediapointer-dvb-s2-9a9f822910db8450c5478fd7146b5b52088d7aaa.tar.gz mediapointer-dvb-s2-9a9f822910db8450c5478fd7146b5b52088d7aaa.tar.bz2 |
merge: http://linuxtv.org/hg/~quincy/v4l-dvb-attach
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/dvb/dvb-core')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/Kconfig | 11 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 42 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 7 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvbdev.h | 22 |
4 files changed, 72 insertions, 10 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/Kconfig b/linux/drivers/media/dvb/dvb-core/Kconfig index 12ee912a5..785388061 100644 --- a/linux/drivers/media/dvb/dvb-core/Kconfig +++ b/linux/drivers/media/dvb/dvb-core/Kconfig @@ -9,3 +9,14 @@ config DVB_CORE in-kernel drivers will select this automatically if needed. If unsure say N. +config DVB_CORE_ATTACH + bool "Load and attach frontend modules as needed" + depends on DVB_CORE + depends on MODULES + help + Remove the static dependency of DVB card drivers on all + frontend modules for all possible card variants. Instead, + allow the card drivers to only load the frontend modules + they require. This saves several KBytes of memory. + + If unsure say Y. diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 2f992b982..ba5ffa981 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1111,18 +1111,42 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) mutex_lock(&frontend_mutex); dvb_unregister_device (fepriv->dvbdev); dvb_frontend_stop (fe); - if (fe->ops.tuner_ops.release) { - fe->ops.tuner_ops.release(fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.release) - fe->ops.release(fe); - else - printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops.info.name); + /* fe is invalid now */ kfree(fepriv); mutex_unlock(&frontend_mutex); return 0; } EXPORT_SYMBOL(dvb_unregister_frontend); + +#ifdef CONFIG_DVB_DETACH +void dvb_frontend_detach(struct dvb_frontend* fe) +{ + void *ptr; + + if (fe->ops.release_sec) { + fe->ops.release_sec(fe); + symbol_put_addr(fe->ops.release_sec); + } + if (fe->ops.tuner_ops.release) { + fe->ops.tuner_ops.release(fe); + symbol_put_addr(fe->ops.tuner_ops.release); + } + ptr = (void*)fe->ops.release; + if (ptr) { + fe->ops.release(fe); + symbol_put_addr(ptr); + } +} +#else +void dvb_frontend_detach(struct dvb_frontend* fe) +{ + if (fe->ops.release_sec) + fe->ops.release_sec(fe); + if (fe->ops.tuner_ops.release) + fe->ops.tuner_ops.release(fe); + if (fe->ops.release) + fe->ops.release(fe); +} +#endif +EXPORT_SYMBOL(dvb_frontend_detach); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 2887e2b86..e5d5028b3 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -92,10 +92,13 @@ struct dvb_frontend_ops { struct dvb_frontend_info info; void (*release)(struct dvb_frontend* fe); + void (*release_sec)(struct dvb_frontend* fe); int (*init)(struct dvb_frontend* fe); int (*sleep)(struct dvb_frontend* fe); + int (*write)(struct dvb_frontend* fe, u8* buf, int len); + /* if this is set, it overrides the default swzigzag */ int (*tune)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, @@ -147,7 +150,7 @@ struct dvb_frontend { void* demodulator_priv; void* tuner_priv; void* frontend_priv; - void* misc_priv; + void* sec_priv; }; extern int dvb_register_frontend(struct dvb_adapter* dvb, @@ -155,6 +158,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb, extern int dvb_unregister_frontend(struct dvb_frontend* fe); +extern void dvb_frontend_detach(struct dvb_frontend* fe); + extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h index 1e7c036d5..26e4a9135 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.h +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h @@ -103,4 +103,26 @@ extern int dvb_usercopy(struct inode *inode, struct file *file, int (*func)(struct inode *inode, struct file *file, unsigned int cmd, void *arg)); +/** generic DVB attach function. */ +#ifdef CONFIG_DVB_CORE_ATTACH +#define dvb_attach(FUNCTION, ARGS...) ({ \ + void *__r = NULL; \ + typeof(&FUNCTION) __a = symbol_request(FUNCTION); \ + if (__a) { \ + __r = (void *) __a(ARGS); \ + if (__r == NULL) \ + symbol_put(FUNCTION); \ + } else { \ + printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \ + } \ + __r; \ +}) + +#else +#define dvb_attach(FUNCTION, ARGS...) ({ \ + FUNCTION(ARGS); \ +}) + +#endif + #endif /* #ifndef _DVBDEV_H_ */ |