VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / arch / sparc64 / kernel / irq.c
index b7f6a1e..d52b842 100644 (file)
@@ -118,10 +118,6 @@ static void register_irq_proc (unsigned int irq);
                action->flags |= __irq_ino(irq) << 48;
 #define get_ino_in_irqaction(action)   (action->flags >> 48)
 
-#if NR_CPUS > 64
-#error irqaction embedded smp affinity does not work with > 64 cpus, FIXME
-#endif
-
 #define put_smpaff_in_irqaction(action, smpaff)        (action)->mask = (smpaff)
 #define get_smpaff_in_irqaction(action)        ((action)->mask)
 
@@ -458,7 +454,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_
        action->next = NULL;
        action->dev_id = dev_id;
        put_ino_in_irqaction(action, irq);
-       put_smpaff_in_irqaction(action, 0);
+       put_smpaff_in_irqaction(action, CPU_MASK_NONE);
 
        if (tmp)
                tmp->next = action;
@@ -691,9 +687,10 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp)
         *    Just Do It.
         */
        struct irqaction *ap = bp->irq_info;
-       cpumask_t cpu_mask = get_smpaff_in_irqaction(ap);
+       cpumask_t cpu_mask;
        unsigned int buddy, ticks;
 
+       cpu_mask = get_smpaff_in_irqaction(ap);
        cpus_and(cpu_mask, cpu_mask, cpu_online_map);
        if (cpus_empty(cpu_mask))
                cpu_mask = cpu_online_map;
@@ -714,7 +711,7 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp)
                if (++buddy >= NR_CPUS)
                        buddy = 0;
                if (++ticks > NR_CPUS) {
-                       put_smpaff_in_irqaction(ap, 0);
+                       put_smpaff_in_irqaction(ap, CPU_MASK_NONE);
                        goto out;
                }
        }
@@ -948,7 +945,7 @@ int request_fast_irq(unsigned int irq,
        action->name = name;
        action->next = NULL;
        put_ino_in_irqaction(action, irq);
-       put_smpaff_in_irqaction(action, 0);
+       put_smpaff_in_irqaction(action, CPU_MASK_NONE);
 
        *(bucket->pil + irq_action) = action;
        enable_irq(irq);
@@ -1166,53 +1163,15 @@ static struct proc_dir_entry * irq_dir [NUM_IVECS];
 
 #ifdef CONFIG_SMP
 
-#define HEX_DIGITS 16
-
-static unsigned int parse_hex_value (const char __user *buffer,
-               unsigned long count, unsigned long *ret)
-{
-       unsigned char hexnum [HEX_DIGITS];
-       unsigned long value;
-       int i;
-
-       if (!count)
-               return -EINVAL;
-       if (count > HEX_DIGITS)
-               count = HEX_DIGITS;
-       if (copy_from_user(hexnum, buffer, count))
-               return -EFAULT;
-
-       /*
-        * Parse the first 8 characters as a hex string, any non-hex char
-        * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
-        */
-       value = 0;
-
-       for (i = 0; i < count; i++) {
-               unsigned int c = hexnum[i];
-
-               switch (c) {
-                       case '0' ... '9': c -= '0'; break;
-                       case 'a' ... 'f': c -= 'a'-10; break;
-                       case 'A' ... 'F': c -= 'A'-10; break;
-               default:
-                       goto out;
-               }
-               value = (value << 4) | c;
-       }
-out:
-       *ret = value;
-       return 0;
-}
-
 static int irq_affinity_read_proc (char *page, char **start, off_t off,
                        int count, int *eof, void *data)
 {
        struct ino_bucket *bp = ivector_table + (long)data;
        struct irqaction *ap = bp->irq_info;
-       cpumask_t mask = get_smpaff_in_irqaction(ap);
+       cpumask_t mask;
        int len;
 
+       mask = get_smpaff_in_irqaction(ap);
        if (cpus_empty(mask))
                mask = cpu_online_map;
 
@@ -1223,7 +1182,7 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off,
        return len;
 }
 
-static inline void set_intr_affinity(int irq, unsigned long hw_aff)
+static inline void set_intr_affinity(int irq, cpumask_t hw_aff)
 {
        struct ino_bucket *bp = ivector_table + irq;
 
@@ -1241,22 +1200,17 @@ static int irq_affinity_write_proc (struct file *file, const char __user *buffer
                                        unsigned long count, void *data)
 {
        int irq = (long) data, full_count = count, err;
-       unsigned long new_value, i;
+       cpumask_t new_value;
 
-       err = parse_hex_value(buffer, count, &new_value);
+       err = cpumask_parse(buffer, count, new_value);
 
        /*
         * 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.
         */
-       for (i = 0; i < NR_CPUS; i++) {
-               if ((new_value & (1UL << i)) != 0 &&
-                   !cpu_online(i))
-                       new_value &= ~(1UL << i);
-       }
-
-       if (!new_value)
+       cpus_and(new_value, new_value, cpu_online_map);
+       if (cpus_empty(new_value))
                return -EINVAL;
 
        set_intr_affinity(irq, new_value);
@@ -1302,6 +1256,6 @@ static void register_irq_proc (unsigned int irq)
 void init_irq_proc (void)
 {
        /* create /proc/irq */
-       root_irq_dir = proc_mkdir("irq", 0);
+       root_irq_dir = proc_mkdir("irq", NULL);
 }