- if (new->flags & SA_SAMPLE_RANDOM) {
- /*
- * This function might sleep, we want to call it first,
- * outside of the atomic block.
- * Yes, this might clear the entropy pool if the wrong
- * driver is attempted to be loaded, without actually
- * installing a new handler, but is this really a problem,
- * only the sysadmin is able to do this.
- */
- rand_initialize_irq(irq);
- }
-
- if (new->flags & SA_PERCPU_IRQ) {
- desc->status |= IRQ_PER_CPU;
- desc->handler = &irq_type_ia64_lsapic;
- }
-
- /*
- * The following block of code has to be executed atomically
- */
- spin_lock_irqsave(&desc->lock,flags);
- p = &desc->action;
- if ((old = *p) != NULL) {
- /* Can't share interrupts unless both agree to */
- if (!(old->flags & new->flags & SA_SHIRQ)) {
- spin_unlock_irqrestore(&desc->lock,flags);
- return -EBUSY;
- }
-
- /* add new interrupt at end of irq queue */
- do {
- p = &old->next;
- old = *p;
- } while (old);
- shared = 1;
- }
-
- *p = new;
-
- if (!shared) {
- desc->depth = 0;
- desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
- desc->handler->startup(irq);
- }
- spin_unlock_irqrestore(&desc->lock,flags);
-
- register_irq_proc(irq);
- return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir [NR_IRQS];
-
-#ifdef CONFIG_SMP
-
-static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
-
-static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
-
-static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
-
-void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
-{
- cpumask_t mask = CPU_MASK_NONE;
-
- cpu_set(cpu_logical_id(hwid), mask);
-
- if (irq < NR_IRQS) {
- irq_affinity[irq] = mask;
- irq_redir[irq] = (char) (redir & 0xff);
- }
-}
-
-static int irq_affinity_read_proc (char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
- if (count - len < 2)
- return -EINVAL;
- len += sprintf(page + len, "\n");
- return len;
-}
-
-static int irq_affinity_write_proc (struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- unsigned int irq = (unsigned long) data;
- int full_count = count, err;
- cpumask_t new_value, tmp;
-# define R_PREFIX_LEN 16
- char rbuf[R_PREFIX_LEN];
- int rlen;
- int prelen;
- irq_desc_t *desc = irq_descp(irq);
-
- if (!desc->handler->set_affinity)
- return -EIO;
-
- /*
- * If string being written starts with a prefix of 'r' or 'R'
- * and some limited number of spaces, set IA64_IRQ_REDIRECTED.
- * If more than (R_PREFIX_LEN - 2) spaces are passed, they won't
- * all be trimmed as part of prelen, the untrimmed spaces will
- * cause the hex parsing to fail, and this write() syscall will
- * fail with EINVAL.
- */
-
- if (!count)
- return -EINVAL;
- rlen = min(sizeof(rbuf)-1, count);
- if (copy_from_user(rbuf, buffer, rlen))
- return -EFAULT;
- rbuf[rlen] = 0;
- prelen = 0;
- if (tolower(*rbuf) == 'r') {
- prelen = strspn(rbuf, "Rr ");
- irq |= IA64_IRQ_REDIRECTED;
- }
-
- err = cpumask_parse(buffer+prelen, count-prelen, new_value);
- if (err)
- return err;
-
- /*
- * Do not allow disabling IRQs completely - it's a too easy
- * way to make the system unusable accidentally :-) At least
- * one online CPU still has to be targeted.
- */
- cpus_and(tmp, new_value, cpu_online_map);
- if (cpus_empty(tmp))
- return -EINVAL;
-
- desc->handler->set_affinity(irq, new_value);
- return full_count;
-}
-
-#endif /* CONFIG_SMP */
-
-static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len = cpumask_scnprintf(page, count, *(cpumask_t *)data);
- if (count - len < 2)
- return -EINVAL;
- len += sprintf(page + len, "\n");
- return len;
-}
-
-static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- cpumask_t *mask = (cpumask_t *)data;
- unsigned long full_count = count, err;
- cpumask_t new_value;
-
- err = cpumask_parse(buffer, count, new_value);
- if (err)
- return err;
-
- *mask = new_value;
- return full_count;