#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/seq_file.h>
        struct gpio_chip                gpio_chip;
        struct pinctrl_gpio_range       gpio_range;
        DECLARE_BITMAP(tint_slot, RZG2L_TINT_MAX_INTERRUPT);
-       spinlock_t                      bitmap_lock;
+       spinlock_t                      bitmap_lock; /* protect tint_slot bitmap */
        unsigned int                    hwirq[RZG2L_TINT_MAX_INTERRUPT];
 
-       spinlock_t                      lock;
+       spinlock_t                      lock; /* lock read/write registers */
+       struct mutex                    mutex; /* serialize adding groups and functions */
 };
 
 static const unsigned int iolh_groupa_mA[] = { 2, 4, 8, 12 };
                name = np->name;
        }
 
+       mutex_lock(&pctrl->mutex);
+
        /* Register a single pin group listing all the pins we read from DT */
        gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL);
        if (gsel < 0) {
                ret = gsel;
-               goto done;
+               goto unlock;
        }
 
        /*
                goto remove_group;
        }
 
+       mutex_unlock(&pctrl->mutex);
+
        maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
        maps[idx].data.mux.group = name;
        maps[idx].data.mux.function = name;
 
 remove_group:
        pinctrl_generic_remove_group(pctldev, gsel);
+unlock:
+       mutex_unlock(&pctrl->mutex);
 done:
        *index = idx;
        kfree(configs);
 
        spin_lock_init(&pctrl->lock);
        spin_lock_init(&pctrl->bitmap_lock);
+       mutex_init(&pctrl->mutex);
 
        platform_set_drvdata(pdev, pctrl);