diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-10-21 18:00:02 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-10-21 18:00:02 -0200 |
commit | f6d43b4abf8f3952809dd9890402d842847ee0a7 (patch) | |
tree | a3b2e091107a3e0f82bfdd5ab79fa877f1d40f3e /linux/drivers/media/dvb | |
parent | 417dfe4bde154a61c7f5e9065a66033e45b26b31 (diff) | |
download | mediapointer-dvb-s2-f6d43b4abf8f3952809dd9890402d842847ee0a7.tar.gz mediapointer-dvb-s2-f6d43b4abf8f3952809dd9890402d842847ee0a7.tar.bz2 |
IRQ: Maintain regs pointer globally rather than passing to IRQ handlers
Kernel-sync:
This patch is required to allow compilation of the tree with kernel
2.6.19.
This is the original description of the original patch, signed by
David Howells <dhowells@redhat.com>:
Maintain a per-CPU global "struct pt_regs *" variable which can be used instead
of passing regs around manually through all ~1800 interrupt handlers in the
Linux kernel.
The regs pointer is used in few places, but it potentially costs both stack
space and code to pass it around. On the FRV arch, removing the regs parameter
from all the genirq function results in a 20% speed up of the IRQ exit path
(ie: from leaving timer_interrupt() to leaving do_IRQ()).
Where appropriate, an arch may override the generic storage facility and do
something different with the variable. On FRV, for instance, the address is
maintained in GR28 at all times inside the kernel as part of general exception
handling.
Having looked over the code, it appears that the parameter may be handed down
through up to twenty or so layers of functions. Consider a USB character
device attached to a USB hub, attached to a USB controller that posts its
interrupts through a cascaded auxiliary interrupt controller. A character
device driver may want to pass regs to the sysrq handler through the input
layer which adds another few layers of parameter passing.
I've build this code with allyesconfig for x86_64 and i386. I've runtested the
main part of the code on FRV and i386, though I can't test most of the drivers.
I've also done partial conversion for powerpc and MIPS - these at least compile
with minimal configurations.
This will affect all archs. Mostly the changes should be relatively easy.
Take do_IRQ(), store the regs pointer at the beginning, saving the old one:
struct pt_regs *old_regs = set_irq_regs(regs);
And put the old one back at the end:
set_irq_regs(old_regs);
Don't pass regs through to generic_handle_irq() or __do_IRQ().
In timer_interrupt(), this sort of change will be necessary:
- update_process_times(user_mode(regs));
- profile_tick(CPU_PROFILING, regs);
+ update_process_times(user_mode(get_irq_regs()));
+ profile_tick(CPU_PROFILING);
I'd like to move update_process_times()'s use of get_irq_regs() into itself,
except that i386, alone of the archs, uses something other than user_mode().
Some notes on the interrupt handling in the drivers:
(*) input_dev() is now gone entirely. The regs pointer is no longer stored in
the input_dev struct.
(*) finish_unlinks() in drivers/usb/host/ohci-q.c needs checking. It does
something different depending on whether it's been supplied with a regs
pointer or not.
(*) Various IRQ handler function pointers have been moved to type
irq_handler_t.
Signed-Off-By: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r-- | linux/drivers/media/dvb/b2c2/flexcop-pci.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/b2c2/flexcop-usb.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/bt8xx/bt878.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/cinergyT2/cinergyT2.c | 8 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/usb-urb.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/pluto2/pluto2.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c | 8 |
8 files changed, 40 insertions, 0 deletions
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c index eb2e6432c..e6362f304 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c @@ -122,7 +122,11 @@ static void flexcop_pci_irq_check_work(void *data) /* When PID filtering is turned on, we use the timer IRQ, because small amounts * of data need to be passed to the user space instantly as well. When PID * filtering is turned off, we use the page-change-IRQ */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs) +#else +static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) +#endif { struct flexcop_pci *fc_pci = dev_id; struct flexcop_device *fc = fc_pci->fc_dev; diff --git a/linux/drivers/media/dvb/b2c2/flexcop-usb.c b/linux/drivers/media/dvb/b2c2/flexcop-usb.c index 8a3ae27f8..8d16d6e72 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-usb.c @@ -328,7 +328,11 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in fc_usb->tmp_buffer_length = l; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) +#else +static void flexcop_usb_urb_complete(struct urb *urb) +#endif { struct flexcop_usb *fc_usb = urb->context; int i; diff --git a/linux/drivers/media/dvb/bt8xx/bt878.c b/linux/drivers/media/dvb/bt8xx/bt878.c index 755822ee6..c63314b9f 100644 --- a/linux/drivers/media/dvb/bt8xx/bt878.c +++ b/linux/drivers/media/dvb/bt8xx/bt878.c @@ -266,7 +266,11 @@ EXPORT_SYMBOL(bt878_stop); /* Interrupt service routine */ /*****************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs) +#else +static irqreturn_t bt878_irq(int irq, void *dev_id) +#endif { u32 stat, astat, mask; int count; diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index 5964b27f9..90672efea 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -255,7 +255,11 @@ static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep) cinergyt2->sleeping = sleep; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs); +#else +static void cinergyt2_stream_irq (struct urb *urb); +#endif static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb) { @@ -275,7 +279,11 @@ static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb return err; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs) +#else +static void cinergyt2_stream_irq (struct urb *urb) +#endif { struct cinergyt2 *cinergyt2 = urb->context; diff --git a/linux/drivers/media/dvb/dvb-usb/usb-urb.c b/linux/drivers/media/dvb/dvb-usb/usb-urb.c index 572b2d9aa..2ed0a214b 100644 --- a/linux/drivers/media/dvb/dvb-usb/usb-urb.c +++ b/linux/drivers/media/dvb/dvb-usb/usb-urb.c @@ -11,7 +11,11 @@ #include "dvb-usb-common.h" /* URB stuff for streaming */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) +#else +static void usb_urb_complete(struct urb *urb) +#endif { struct usb_data_stream *stream = urb->context; int ptype = usb_pipetype(urb->pipe); diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c index 2310b2bfe..3de55e0cc 100644 --- a/linux/drivers/media/dvb/pluto2/pluto2.c +++ b/linux/drivers/media/dvb/pluto2/pluto2.c @@ -306,7 +306,11 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) TS_DMA_BYTES, PCI_DMA_FROMDEVICE); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs) +#else +static irqreturn_t pluto_irq(int irq, void *dev_id) +#endif { struct pluto *pluto = dev_id; u32 tscr; diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index af3391314..239a48bcb 100644 --- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -740,7 +740,11 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs) +#else +static void ttusb_iso_irq(struct urb *urb) +#endif { struct ttusb *ttusb = urb->context; diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 36dd35db4..f2d18a5fb 100644 --- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -214,7 +214,11 @@ static u16 rc_keys[] = { static void ttusb_dec_set_model(struct ttusb_dec *dec, enum ttusb_dec_model model); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs) +#else +static void ttusb_dec_handle_irq( struct urb *urb) +#endif { struct ttusb_dec * dec = urb->context; char *buffer = dec->irq_buffer; @@ -766,7 +770,11 @@ static void ttusb_dec_process_urb_frame_list(unsigned long data) } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static void ttusb_dec_process_urb(struct urb *urb, struct pt_regs *ptregs) +#else +static void ttusb_dec_process_urb(struct urb *urb) +#endif { struct ttusb_dec *dec = urb->context; |