Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b1220e2e7f03a0e86078c82819e802c25047638d
Commit:     b1220e2e7f03a0e86078c82819e802c25047638d
Parent:     5f526d1467383fbd7d64b4f7de85b2889838e454
Author:     Jesper Nilsson <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 29 11:27:19 2008 +0100
Committer:  Jesper Nilsson <[EMAIL PROTECTED]>
CommitDate: Fri Feb 8 11:06:32 2008 +0100

    CRIS v10: Update kernel/io_interface_mux.c
    
    Fixed a bug where two interfaces using pins in the same pin group could
    not be allocated at the same time even if there where no pin collisions.
    
    Change all restore and returns into goto exit pattern.
    
    Also, remove useless CVS id and correct chapter reference for ETRAX100LX
    Designer's Reference in comment.
---
 arch/cris/arch-v10/kernel/io_interface_mux.c |  515 ++++++++++++++++++++------
 1 files changed, 408 insertions(+), 107 deletions(-)

diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c 
b/arch/cris/arch-v10/kernel/io_interface_mux.c
index f3b327d..add98e0 100644
--- a/arch/cris/arch-v10/kernel/io_interface_mux.c
+++ b/arch/cris/arch-v10/kernel/io_interface_mux.c
@@ -1,10 +1,9 @@
 /* IO interface mux allocator for ETRAX100LX.
- * Copyright 2004, Axis Communications AB
- * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
+ * Copyright 2004-2007, Axis Communications AB
  */
 
 
-/* C.f. ETRAX100LX Designer's Reference 20.9 */
+/* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -45,17 +44,39 @@ struct watcher
 struct if_group
 {
        enum io_if_group        group;
-       unsigned char           used;
-       enum cris_io_interface  owner;
+       /* name - the name of the group 'A' to 'F' */
+       char                   *name;
+       /* used - a bit mask of all pins in the group in the order listed
+        * in the tables in 19.9.1 to 19.9.6.  Note that no
+        * distinction is made between in, out and in/out pins. */
+       unsigned int            used;
 };
 
 
 struct interface
 {
        enum cris_io_interface   ioif;
+       /* name - the name of the interface */
+       char                    *name;
+       /* groups - OR'ed together io_if_group flags describing what pin groups
+        * the interface uses pins in. */
        unsigned char            groups;
+       /* used - set when the interface is allocated. */
        unsigned char            used;
        char                    *owner;
+       /* group_a through group_f - bit masks describing what pins in the
+        * pin groups the interface uses. */
+       unsigned int             group_a;
+       unsigned int             group_b;
+       unsigned int             group_c;
+       unsigned int             group_d;
+       unsigned int             group_e;
+       unsigned int             group_f;
+
+       /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
+        * GPIO ports the interface uses.  This could be reconstucted using
+        * the group_X masks and a table of what pins the GPIO ports use,
+        * but that would be messy. */
        unsigned int             gpio_g_in;
        unsigned int             gpio_g_out;
        unsigned char            gpio_b;
@@ -64,26 +85,32 @@ struct interface
 static struct if_group if_groups[6] = {
        {
                .group = group_a,
+               .name = "A",
                .used = 0,
        },
        {
                .group = group_b,
+               .name = "B",
                .used = 0,
        },
        {
                .group = group_c,
+               .name = "C",
                .used = 0,
        },
        {
                .group = group_d,
+               .name = "D",
                .used = 0,
        },
        {
                .group = group_e,
+               .name = "E",
                .used = 0,
        },
        {
                .group = group_f,
+               .name = "F",
                .used = 0,
        }
 };
@@ -94,14 +121,32 @@ static struct interface interfaces[] = {
        /* Begin Non-multiplexed interfaces */
        {
                .ioif = if_eth,
+               .name = "ethernet",
                .groups = 0,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in = 0,
                .gpio_g_out = 0,
                .gpio_b = 0
        },
        {
                .ioif = if_serial_0,
+               .name = "serial_0",
                .groups = 0,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in = 0,
                .gpio_g_out = 0,
                .gpio_b = 0
@@ -109,172 +154,385 @@ static struct interface interfaces[] = {
        /* End Non-multiplexed interfaces */
        {
                .ioif = if_serial_1,
+               .name = "serial_1",
                .groups = group_e,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0x0f,
+               .group_f = 0,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_serial_2,
+               .name = "serial_2",
                .groups = group_b,
+
+               .group_a = 0,
+               .group_b = 0x0f,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x000000c0,
                .gpio_g_out = 0x000000c0,
                .gpio_b = 0x00
        },
        {
                .ioif = if_serial_3,
+               .name = "serial_3",
                .groups = group_c,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0x0f,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0xc0000000,
                .gpio_g_out = 0xc0000000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_sync_serial_1,
-               .groups = group_e | group_f, /* if_sync_serial_1 and 
if_sync_serial_3
-                                              can be used simultaneously */
+               .name = "sync_serial_1",
+               .groups = group_e | group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0x0f,
+               .group_f = 0x10,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0x10
        },
        {
                .ioif = if_sync_serial_3,
+               .name = "sync_serial_3",
                .groups = group_c | group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0x0f,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0x80,
+
                .gpio_g_in =  0xc0000000,
                .gpio_g_out = 0xc0000000,
                .gpio_b = 0x80
        },
        {
                .ioif = if_shared_ram,
+               .name = "shared_ram",
                .groups = group_a,
+
+               .group_a = 0x7f8ff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x0000ff3e,
                .gpio_g_out = 0x0000ff38,
                .gpio_b = 0x00
        },
        {
                .ioif = if_shared_ram_w,
+               .name = "shared_ram_w",
                .groups = group_a | group_d,
+
+               .group_a = 0x7f8ff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0xff,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x00ffff3e,
                .gpio_g_out = 0x00ffff38,
                .gpio_b = 0x00
        },
        {
                .ioif = if_par_0,
+               .name = "par_0",
                .groups = group_a,
+
+               .group_a = 0x7fbff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x0000ff3e,
                .gpio_g_out = 0x0000ff3e,
                .gpio_b = 0x00
        },
        {
                .ioif = if_par_1,
+               .name = "par_1",
                .groups = group_d,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0x7feff,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x3eff0000,
                .gpio_g_out = 0x3eff0000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_par_w,
+               .name = "par_w",
                .groups = group_a | group_d,
+
+               .group_a = 0x7fbff,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0xff,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x00ffff3e,
                .gpio_g_out = 0x00ffff3e,
                .gpio_b = 0x00
        },
        {
                .ioif = if_scsi8_0,
-               .groups = group_a | group_b | group_f, /* if_scsi8_0 and 
if_scsi8_1
-                                                         can be used 
simultaneously */
+               .name = "scsi8_0",
+               .groups = group_a | group_b | group_f,
+
+               .group_a = 0x7ffff,
+               .group_b = 0x0f,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0x10,
+
                .gpio_g_in =  0x0000ffff,
                .gpio_g_out = 0x0000ffff,
                .gpio_b = 0x10
        },
        {
                .ioif = if_scsi8_1,
-               .groups = group_c | group_d | group_f, /* if_scsi8_0 and 
if_scsi8_1
-                                                         can be used 
simultaneously */
+               .name = "scsi8_1",
+               .groups = group_c | group_d | group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0x0f,
+               .group_d = 0x7ffff,
+               .group_e = 0,
+               .group_f = 0x80,
+
                .gpio_g_in =  0xffff0000,
                .gpio_g_out = 0xffff0000,
                .gpio_b = 0x80
        },
        {
                .ioif = if_scsi_w,
+               .name = "scsi_w",
                .groups = group_a | group_b | group_d | group_f,
+
+               .group_a = 0x7ffff,
+               .group_b = 0x0f,
+               .group_c = 0,
+               .group_d = 0x601ff,
+               .group_e = 0,
+               .group_f = 0x90,
+
                .gpio_g_in =  0x01ffffff,
                .gpio_g_out = 0x07ffffff,
                .gpio_b = 0x80
        },
        {
                .ioif = if_ata,
+               .name = "ata",
                .groups = group_a | group_b | group_c | group_d,
+
+               .group_a = 0x7ffff,
+               .group_b = 0x0f,
+               .group_c = 0x0f,
+               .group_d = 0x7cfff,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0xf9ffffff,
                .gpio_g_out = 0xffffffff,
                .gpio_b = 0x80
        },
        {
                .ioif = if_csp,
-               .groups = group_f, /* if_csp and if_i2c can be used 
simultaneously */
+               .name = "csp",
+               .groups = group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0xfc,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0xfc
        },
        {
                .ioif = if_i2c,
-               .groups = group_f, /* if_csp and if_i2c can be used 
simultaneously */
+               .name = "i2c",
+               .groups = group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0x03,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0x03
        },
        {
                .ioif = if_usb_1,
+               .name = "usb_1",
                .groups = group_e | group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0x0f,
+               .group_f = 0x2c,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0x2c
        },
        {
                .ioif = if_usb_2,
+               .name = "usb_2",
                .groups = group_d,
-               .gpio_g_in =  0x0e000000,
-               .gpio_g_out = 0x3c000000,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0x33e00,
+               .group_f = 0,
+
+               .gpio_g_in =  0x3e000000,
+               .gpio_g_out = 0x0c000000,
                .gpio_b = 0x00
        },
        /* GPIO pins */
        {
                .ioif = if_gpio_grp_a,
+               .name = "gpio_a",
                .groups = group_a,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x0000ff3f,
                .gpio_g_out = 0x0000ff3f,
                .gpio_b = 0x00
        },
        {
                .ioif = if_gpio_grp_b,
+               .name = "gpio_b",
                .groups = group_b,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x000000c0,
                .gpio_g_out = 0x000000c0,
                .gpio_b = 0x00
        },
        {
                .ioif = if_gpio_grp_c,
+               .name = "gpio_c",
                .groups = group_c,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0xc0000000,
                .gpio_g_out = 0xc0000000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_gpio_grp_d,
+               .name = "gpio_d",
                .groups = group_d,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x3fff0000,
                .gpio_g_out = 0x3fff0000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_gpio_grp_e,
+               .name = "gpio_e",
                .groups = group_e,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0x00
        },
        {
                .ioif = if_gpio_grp_f,
+               .name = "gpio_f",
                .groups = group_f,
+
+               .group_a = 0,
+               .group_b = 0,
+               .group_c = 0,
+               .group_d = 0,
+               .group_e = 0,
+               .group_f = 0,
+
                .gpio_g_in =  0x00000000,
                .gpio_g_out = 0x00000000,
                .gpio_b = 0xff
@@ -284,11 +542,13 @@ static struct interface interfaces[] = {
 
 static struct watcher *watchers = NULL;
 
+/* The pins that are free to use in the GPIO ports. */
 static unsigned int gpio_in_pins =  0xffffffff;
 static unsigned int gpio_out_pins = 0xffffffff;
 static unsigned char gpio_pb_pins = 0xff;
 static unsigned char gpio_pa_pins = 0xff;
 
+/* Identifiers for the owners of the GPIO pins. */
 static enum cris_io_interface gpio_pa_owners[8];
 static enum cris_io_interface gpio_pb_owners[8];
 static enum cris_io_interface gpio_pg_owners[32];
@@ -338,13 +598,15 @@ int cris_request_io_interface(enum cris_io_interface 
ioif, const char *device_id
        struct if_group *grp;
        unsigned char group_set;
        unsigned long flags;
+       int res = 0;
 
        (void)cris_io_interface_init();
 
        DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
 
        if ((ioif >= if_max_interfaces) || (ioif < 0)) {
-               printk(KERN_CRIT "cris_request_io_interface: Bad interface %u 
submitted for %s\n",
+               printk(KERN_CRIT "cris_request_io_interface: Bad interface "
+                       "%u submitted for %s\n",
                       ioif,
                       device_id);
                return -EINVAL;
@@ -353,59 +615,69 @@ int cris_request_io_interface(enum cris_io_interface 
ioif, const char *device_id
        local_irq_save(flags);
 
        if (interfaces[ioif].used) {
-               local_irq_restore(flags);
-               printk(KERN_CRIT "cris_io_interface: Cannot allocate interface 
for %s, in use by %s\n",
+               printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
+                       "%s for %s, in use by %s\n",
+                      interfaces[ioif].name,
                       device_id,
                       interfaces[ioif].owner);
-               return -EBUSY;
+               res = -EBUSY;
+               goto exit;
        }
 
-       /* Check that all required groups are free before allocating, */
+       /* Check that all required pins in the used groups are free
+        * before allocating. */
        group_set = interfaces[ioif].groups;
        while (NULL != (grp = get_group(group_set))) {
-               if (grp->used) {
-                       if (grp->group == group_f) {
-                               if ((if_sync_serial_1 ==  ioif) ||
-                                   (if_sync_serial_3 ==  ioif)) {
-                                       if ((grp->owner != if_sync_serial_1) &&
-                                           (grp->owner != if_sync_serial_3)) {
-                                               local_irq_restore(flags);
-                                               return -EBUSY;
-                                       }
-                               } else if ((if_scsi8_0 == ioif) ||
-                                          (if_scsi8_1 == ioif)) {
-                                       if ((grp->owner != if_scsi8_0) &&
-                                           (grp->owner != if_scsi8_1)) {
-                                               local_irq_restore(flags);
-                                               return -EBUSY;
-                                       }
-                               }
-                       } else {
-                               local_irq_restore(flags);
-                               return -EBUSY;
-                       }
+               unsigned int if_group_use = 0;
+
+               switch (grp->group) {
+               case group_a:
+                       if_group_use = interfaces[ioif].group_a;
+                       break;
+               case group_b:
+                       if_group_use = interfaces[ioif].group_b;
+                       break;
+               case group_c:
+                       if_group_use = interfaces[ioif].group_c;
+                       break;
+               case group_d:
+                       if_group_use = interfaces[ioif].group_d;
+                       break;
+               case group_e:
+                       if_group_use = interfaces[ioif].group_e;
+                       break;
+               case group_f:
+                       if_group_use = interfaces[ioif].group_f;
+                       break;
+               default:
+                       BUG_ON(1);
                }
+
+               if (if_group_use & grp->used) {
+                       printk(KERN_INFO "cris_request_io_interface: group "
+                               "%s needed by %s not available\n",
+                               grp->name, interfaces[ioif].name);
+                       res = -EBUSY;
+                       goto exit;
+               }
+
                group_set = clear_group_from_set(group_set, grp);
        }
 
        /* Are the required GPIO pins available too? */
-       if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != 
interfaces[ioif].gpio_g_in) ||
-           ((interfaces[ioif].gpio_g_out & gpio_out_pins) != 
interfaces[ioif].gpio_g_out) ||
-           ((interfaces[ioif].gpio_b & gpio_pb_pins) != 
interfaces[ioif].gpio_b)) {
-               local_irq_restore(flags);
-               printk(KERN_CRIT "cris_request_io_interface: Could not get 
required pins for interface %u\n",
-                      ioif);
-               return -EBUSY;
-       }
-
-       /* All needed I/O pins and pin groups are free, allocate. */
-       group_set = interfaces[ioif].groups;
-       while (NULL != (grp = get_group(group_set))) {
-               grp->used = 1;
-               grp->owner = ioif;
-               group_set = clear_group_from_set(group_set, grp);
+       if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
+                       interfaces[ioif].gpio_g_in) ||
+               ((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
+                       interfaces[ioif].gpio_g_out) ||
+               ((interfaces[ioif].gpio_b & gpio_pb_pins) !=
+                       interfaces[ioif].gpio_b)) {
+               printk(KERN_CRIT "cris_request_io_interface: Could not get "
+                       "required pins for interface %u\n", ioif);
+               res = -EBUSY;
+               goto exit;
        }
 
+       /* Check which registers need to be reconfigured. */
        gens = genconfig_shadow;
        gens_ii = gen_config_ii_shadow;
 
@@ -495,9 +767,43 @@ int cris_request_io_interface(enum cris_io_interface ioif, 
const char *device_id
                set_gen_config = 0;
                break;
        default:
-               panic("cris_request_io_interface: Bad interface %u submitted 
for %s\n",
-                     ioif,
-                     device_id);
+               printk(KERN_INFO "cris_request_io_interface: Bad interface "
+                       "%u submitted for %s\n",
+                       ioif, device_id);
+               res = -EBUSY;
+               goto exit;
+       }
+
+       /* All needed I/O pins and pin groups are free, allocate. */
+       group_set = interfaces[ioif].groups;
+       while (NULL != (grp = get_group(group_set))) {
+               unsigned int if_group_use = 0;
+
+               switch (grp->group) {
+               case group_a:
+                       if_group_use = interfaces[ioif].group_a;
+                       break;
+               case group_b:
+                       if_group_use = interfaces[ioif].group_b;
+                       break;
+               case group_c:
+                       if_group_use = interfaces[ioif].group_c;
+                       break;
+               case group_d:
+                       if_group_use = interfaces[ioif].group_d;
+                       break;
+               case group_e:
+                       if_group_use = interfaces[ioif].group_e;
+                       break;
+               case group_f:
+                       if_group_use = interfaces[ioif].group_f;
+                       break;
+               default:
+                       BUG_ON(1);
+               }
+               grp->used |= if_group_use;
+
+               group_set = clear_group_from_set(group_set, grp);
        }
 
        interfaces[ioif].used = 1;
@@ -516,25 +822,28 @@ int cris_request_io_interface(enum cris_io_interface 
ioif, const char *device_id
                *R_GEN_CONFIG_II = gen_config_ii_shadow;
        }
 
-       DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x 
pb=0x%02x\n",
-                  gpio_in_pins, gpio_out_pins, gpio_pb_pins));
-       DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
-                  interfaces[ioif].gpio_g_in,
-                  interfaces[ioif].gpio_g_out,
-                  interfaces[ioif].gpio_b));
+       DBG(printk(KERN_DEBUG "GPIO pins: available before: "
+               "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+               gpio_in_pins, gpio_out_pins, gpio_pb_pins));
+       DBG(printk(KERN_DEBUG
+               "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+               interfaces[ioif].gpio_g_in,
+               interfaces[ioif].gpio_g_out,
+               interfaces[ioif].gpio_b));
 
        gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
        gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
        gpio_pb_pins &= ~interfaces[ioif].gpio_b;
 
-       DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x 
pb=0x%02x\n",
-                  gpio_in_pins, gpio_out_pins, gpio_pb_pins));
+       DBG(printk(KERN_DEBUG "GPIO pins: available after: "
+               "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+               gpio_in_pins, gpio_out_pins, gpio_pb_pins));
 
+exit:
        local_irq_restore(flags);
-
-       notify_watchers();
-
-       return 0;
+       if (res == 0)
+               notify_watchers();
+       return res;
 }
 
 
@@ -560,43 +869,35 @@ void cris_free_io_interface(enum cris_io_interface ioif)
        }
        group_set = interfaces[ioif].groups;
        while (NULL != (grp = get_group(group_set))) {
-               if (grp->group == group_f) {
-                       switch (ioif)
-                       {
-                       case if_sync_serial_1:
-                               if ((grp->owner == if_sync_serial_1) &&
-                                   interfaces[if_sync_serial_3].used) {
-                                       grp->owner = if_sync_serial_3;
-                               } else
-                                       grp->used = 0;
-                               break;
-                       case if_sync_serial_3:
-                               if ((grp->owner == if_sync_serial_3) &&
-                                   interfaces[if_sync_serial_1].used) {
-                                       grp->owner = if_sync_serial_1;
-                               } else
-                                       grp->used = 0;
-                               break;
-                       case if_scsi8_0:
-                               if ((grp->owner == if_scsi8_0) &&
-                                   interfaces[if_scsi8_1].used) {
-                                       grp->owner = if_scsi8_1;
-                               } else
-                                       grp->used = 0;
-                               break;
-                       case if_scsi8_1:
-                               if ((grp->owner == if_scsi8_1) &&
-                                   interfaces[if_scsi8_0].used) {
-                                       grp->owner = if_scsi8_0;
-                               } else
-                                       grp->used = 0;
-                               break;
-                       default:
-                               grp->used = 0;
-                       }
-               } else {
-                       grp->used = 0;
+               unsigned int if_group_use = 0;
+
+               switch (grp->group) {
+               case group_a:
+                       if_group_use = interfaces[ioif].group_a;
+                       break;
+               case group_b:
+                       if_group_use = interfaces[ioif].group_b;
+                       break;
+               case group_c:
+                       if_group_use = interfaces[ioif].group_c;
+                       break;
+               case group_d:
+                       if_group_use = interfaces[ioif].group_d;
+                       break;
+               case group_e:
+                       if_group_use = interfaces[ioif].group_e;
+                       break;
+               case group_f:
+                       if_group_use = interfaces[ioif].group_f;
+                       break;
+               default:
+                       BUG_ON(1);
                }
+
+               if ((grp->used & if_group_use) != if_group_use)
+                       BUG_ON(1);
+               grp->used = grp->used & ~if_group_use;
+
                group_set = clear_group_from_set(group_set, grp);
        }
        interfaces[ioif].used = 0;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to