From caf96194c05cd97ce96546fbcb1f35ec06aaaac7 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 13 Oct 2010 20:35:56 -0400 Subject: parisc: add prlimit64 syscall Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall_table.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 3d52c97..74867df 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -419,6 +419,7 @@ ENTRY_SAME(perf_event_open) ENTRY_COMP(recvmmsg) ENTRY_SAME(accept4) /* 320 */ + ENTRY_SAME(prlimit64) /* Nothing yet */ -- cgit v1.1 From ba20085c20f1c9e8af546dea6ad0efa421bdef32 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 13 Oct 2010 21:00:55 -0400 Subject: parisc: lay groundwork for killing __do_IRQ Use proper accessors and handlers for generic irq cleanups. We just call back into __do_IRQ through desc->handler now, and remove the explicit calls. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/irq.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index efbcee5..272c29a 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -151,7 +151,7 @@ static struct irq_chip cpu_interrupt_type = { .enable = cpu_enable_irq, .disable = cpu_disable_irq, .ack = cpu_ack_irq, - .end = cpu_end_irq, + .eoi = cpu_end_irq, #ifdef CONFIG_SMP .set_affinity = cpu_set_affinity_irq, #endif @@ -247,10 +247,11 @@ int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data) if (irq_desc[irq].chip != &cpu_interrupt_type) return -EBUSY; + /* for iosapic interrupts */ if (type) { - irq_desc[irq].chip = type; - irq_desc[irq].chip_data = data; - cpu_interrupt_type.enable(irq); + set_irq_chip_and_handler(irq, type, parisc_do_IRQ); + set_irq_chip_data(irq, data); + cpu_enable_irq(irq); } return 0; } @@ -368,7 +369,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) goto set_out; } #endif - __do_IRQ(irq); + generic_handle_irq(irq); out: irq_exit(); @@ -398,14 +399,14 @@ static void claim_cpu_irqs(void) { int i; for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { - irq_desc[i].chip = &cpu_interrupt_type; + set_irq_chip_and_handler(i, &cpu_interrupt_type, parisc_do_IRQ); } - irq_desc[TIMER_IRQ].action = &timer_action; - irq_desc[TIMER_IRQ].status = IRQ_PER_CPU; + set_irq_handler(TIMER_IRQ, handle_percpu_irq); + setup_irq(TIMER_IRQ, &timer_action); #ifdef CONFIG_SMP - irq_desc[IPI_IRQ].action = &ipi_action; - irq_desc[IPI_IRQ].status = IRQ_PER_CPU; + set_irq_handler(IPI_IRQ, handle_percpu_irq); + setup_irq(IPI_IRQ, &ipi_action); #endif } @@ -423,3 +424,8 @@ void __init init_IRQ(void) set_eiem(cpu_eiem); /* EIEM : enable all external intr */ } + +void parisc_do_IRQ(unsigned int irq, struct irq_desc *desc) +{ + __do_IRQ(irq); +} -- cgit v1.1 From 4d4f681dc43a06167763ec698f5de4f2b3119ad6 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 14 Oct 2010 00:12:23 -0400 Subject: parisc: convert cpu interrupts to proper flow handlers Only major change is renaming functions to match the conventions expected by the generic irq code. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/irq.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 272c29a..13bfa97 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -52,7 +52,7 @@ static volatile unsigned long cpu_eiem = 0; */ static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL; -static void cpu_disable_irq(unsigned int irq) +static void cpu_mask_irq(unsigned int irq) { unsigned long eirr_bit = EIEM_MASK(irq); @@ -63,7 +63,7 @@ static void cpu_disable_irq(unsigned int irq) * then gets disabled */ } -static void cpu_enable_irq(unsigned int irq) +static void cpu_unmask_irq(unsigned int irq) { unsigned long eirr_bit = EIEM_MASK(irq); @@ -75,12 +75,6 @@ static void cpu_enable_irq(unsigned int irq) smp_send_all_nop(); } -static unsigned int cpu_startup_irq(unsigned int irq) -{ - cpu_enable_irq(irq); - return 0; -} - void no_ack_irq(unsigned int irq) { } void no_end_irq(unsigned int irq) { } @@ -99,7 +93,7 @@ void cpu_ack_irq(unsigned int irq) mtctl(mask, 23); } -void cpu_end_irq(unsigned int irq) +void cpu_eoi_irq(unsigned int irq) { unsigned long mask = EIEM_MASK(irq); int cpu = smp_processor_id(); @@ -146,12 +140,10 @@ static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest) static struct irq_chip cpu_interrupt_type = { .name = "CPU", - .startup = cpu_startup_irq, - .shutdown = cpu_disable_irq, - .enable = cpu_enable_irq, - .disable = cpu_disable_irq, + .mask = cpu_mask_irq, + .unmask = cpu_unmask_irq, .ack = cpu_ack_irq, - .eoi = cpu_end_irq, + .eoi = cpu_eoi_irq, #ifdef CONFIG_SMP .set_affinity = cpu_set_affinity_irq, #endif @@ -251,7 +243,7 @@ int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data) if (type) { set_irq_chip_and_handler(irq, type, parisc_do_IRQ); set_irq_chip_data(irq, data); - cpu_enable_irq(irq); + cpu_unmask_irq(irq); } return 0; } @@ -399,7 +391,8 @@ static void claim_cpu_irqs(void) { int i; for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { - set_irq_chip_and_handler(i, &cpu_interrupt_type, parisc_do_IRQ); + set_irq_chip_and_handler(i, &cpu_interrupt_type, + handle_level_irq); } set_irq_handler(TIMER_IRQ, handle_percpu_irq); -- cgit v1.1 From f3d4605977f9f30993c670a85f75d8f3853144c5 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 14 Oct 2010 00:38:27 -0400 Subject: parisc: convert iosapic interrupts to proper flow handlers Shift the ->end call (cpu eoi) from __do_IRQ into our unmask handler. Also nuke some redundant code. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 13bfa97..e873eda 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -241,7 +241,7 @@ int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data) /* for iosapic interrupts */ if (type) { - set_irq_chip_and_handler(irq, type, parisc_do_IRQ); + set_irq_chip_and_handler(irq, type, handle_level_irq); set_irq_chip_data(irq, data); cpu_unmask_irq(irq); } -- cgit v1.1 From 7da1272547ebe96982a42292dfc833457708f4da Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 14 Oct 2010 01:02:23 -0400 Subject: parisc: kill __do_IRQ Signed-off-by: Kyle McMartin --- arch/parisc/kernel/irq.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index e873eda..5024f64 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -418,7 +418,3 @@ void __init init_IRQ(void) } -void parisc_do_IRQ(unsigned int irq, struct irq_desc *desc) -{ - __do_IRQ(irq); -} -- cgit v1.1 From b1b1d4a6f244eb9513f006a188f7ed30d5014de5 Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Fri, 10 Sep 2010 13:47:59 +0300 Subject: parisc: unwind - optimise linked-list searches for modules Having many dozens of modules, the searches down the linked list of sections would dominate the lookup time, dwarfing any savings from the binary search within the section. A simple move-to-front optimisation exploits the commonality of the code paths taken, and in simple real-world tests on other architectures reduced the number of steps in the search to barely more than 1. Signed-off-by: Phil Carmody Signed-off-by: Kyle McMartin --- arch/parisc/kernel/unwind.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index d58eac1..76ed62e 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -80,8 +80,11 @@ find_unwind_entry(unsigned long addr) if (addr >= table->start && addr <= table->end) e = find_unwind_entry_in_table(table, addr); - if (e) + if (e) { + /* Move-to-front to exploit common traces */ + list_move(&table->list, &unwind_tables); break; + } } return e; -- cgit v1.1 From 2da83b90bbbac586fca2735f7da21966a31ec33f Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Mon, 6 Sep 2010 16:36:06 +0200 Subject: arch/parisc: Removing undead ifdef CONFIG_PA20 The CONFIG_PA20 ifdef isn't necessary at this point, because it is checked in an outer ifdef level already and has no effect here. Signed-off-by: Christian Dietrich Signed-off-by: Kyle McMartin --- arch/parisc/kernel/unaligned.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index 92d977b..234e368 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -619,15 +619,12 @@ void handle_unaligned(struct pt_regs *regs) flop=1; ret = emulate_std(regs, R2(regs->iir),1); break; - -#ifdef CONFIG_PA20 case OPCODE_LDD_L: ret = emulate_ldd(regs, R2(regs->iir),0); break; case OPCODE_STD_L: ret = emulate_std(regs, R2(regs->iir),0); break; -#endif } #endif switch (regs->iir & OPCODE3_MASK) -- cgit v1.1 From 650a35f868f809aade56ef960d8a465f57ac74e2 Mon Sep 17 00:00:00 2001 From: Guy Martin Date: Mon, 14 Jun 2010 19:24:41 +0200 Subject: parisc: add tty driver to PDC console This patch adds a tty driver to the PDC console. It allows the use of ports not supported by linux as a console (e.g. serial port on C8000.) The tty driver will not register the ttyB device if PDC console driver has been unregistered. This happens when the early printk console is disabled as it has not been selected as the primary console. Signed-off-by: Guy Martin Signed-off-by: Kyle McMartin --- arch/parisc/kernel/pdc_cons.c | 141 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 134 insertions(+), 7 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 1ff366c..66d1f17 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -12,6 +12,7 @@ * Copyright (C) 2001 Helge Deller * Copyright (C) 2001 Thomas Bogendoerfer * Copyright (C) 2002 Randolph Chung + * Copyright (C) 2010 Guy Martin * * * This program is free software; you can redistribute it and/or modify @@ -31,12 +32,11 @@ /* * The PDC console is a simple console, which can be used for debugging - * boot related problems on HP PA-RISC machines. + * boot related problems on HP PA-RISC machines. It is also useful when no + * other console works. * * This code uses the ROM (=PDC) based functions to read and write characters * from and to PDC's boot path. - * Since all character read from that path must be polled, this code never - * can or will be a fully functional linux console. */ /* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems. @@ -53,6 +53,7 @@ #include /* for iodc_call() proto and friends */ static DEFINE_SPINLOCK(pdc_console_lock); +static struct console pdc_cons; static void pdc_console_write(struct console *co, const char *s, unsigned count) { @@ -85,12 +86,138 @@ static int pdc_console_setup(struct console *co, char *options) #if defined(CONFIG_PDC_CONSOLE) #include +#include + +#define PDC_CONS_POLL_DELAY (30 * HZ / 1000) + +static struct timer_list pdc_console_timer; + +extern struct console * console_drivers; + +static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) +{ + + mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); + + return 0; +} + +static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) +{ + if (!tty->count) + del_timer(&pdc_console_timer); +} + +static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + pdc_console_write(NULL, buf, count); + return count; +} + +static int pdc_console_tty_write_room(struct tty_struct *tty) +{ + return 32768; /* no limit, no buffer used */ +} + +static int pdc_console_tty_chars_in_buffer(struct tty_struct *tty) +{ + return 0; /* no buffer */ +} + +static struct tty_driver *pdc_console_tty_driver; + +static const struct tty_operations pdc_console_tty_ops = { + .open = pdc_console_tty_open, + .close = pdc_console_tty_close, + .write = pdc_console_tty_write, + .write_room = pdc_console_tty_write_room, + .chars_in_buffer = pdc_console_tty_chars_in_buffer, +}; + +static void pdc_console_poll(unsigned long unused) +{ + + int data, count = 0; + + struct tty_struct *tty = pdc_console_tty_driver->ttys[0]; + + if (!tty) + return; + + while (1) { + data = pdc_console_poll_key(NULL); + if (data == -1) + break; + tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); + count ++; + } + + if (count) + tty_flip_buffer_push(tty); + + if (tty->count && (pdc_cons.flags & CON_ENABLED)) + mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); +} + +static int __init pdc_console_tty_driver_init(void) +{ + + int err; + struct tty_driver *drv; + + /* Check if the console driver is still registered. + * It is unregistered if the pdc console was not selected as the + * primary console. */ + + struct console *tmp = console_drivers; + + for (tmp = console_drivers; tmp; tmp = tmp->next) + if (tmp == &pdc_cons) + break; + + if (!tmp) { + printk(KERN_INFO "PDC console driver not registered anymore, not creating %s\n", pdc_cons.name); + return -ENODEV; + } + + printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n"); + pdc_cons.flags &= ~CON_BOOT; + + drv = alloc_tty_driver(1); + + if (!drv) + return -ENOMEM; + + drv->driver_name = "pdc_cons"; + drv->name = "ttyB"; + drv->major = MUX_MAJOR; + drv->minor_start = 0; + drv->type = TTY_DRIVER_TYPE_SYSTEM; + drv->init_termios = tty_std_termios; + drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; + tty_set_operations(drv, &pdc_console_tty_ops); + + err = tty_register_driver(drv); + if (err) { + printk(KERN_ERR "Unable to register the PDC console TTY driver\n"); + return err; + } + + pdc_console_tty_driver = drv; + + /* No need to initialize the pdc_console_timer if tty isn't allocated */ + init_timer(&pdc_console_timer); + pdc_console_timer.function = pdc_console_poll; + + return 0; +} + +module_init(pdc_console_tty_driver_init); static struct tty_driver * pdc_console_device (struct console *c, int *index) { - extern struct tty_driver console_driver; - *index = c->index ? c->index-1 : fg_console; - return &console_driver; + *index = c->index; + return pdc_console_tty_driver; } #else #define pdc_console_device NULL @@ -101,7 +228,7 @@ static struct console pdc_cons = { .write = pdc_console_write, .device = pdc_console_device, .setup = pdc_console_setup, - .flags = CON_BOOT | CON_PRINTBUFFER | CON_ENABLED, + .flags = CON_BOOT | CON_PRINTBUFFER, .index = -1, }; -- cgit v1.1