Re: [PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-12-30 Thread Tony Lindgren
* Linus Walleij  [161230 06:12]:
> On Tue, Dec 27, 2016 at 6:20 PM, Tony Lindgren  wrote:
> 
> > We can add generic helpers for pin group handling for cases where the pin
> > controller driver does not need to use static arrays.
> >
> > Signed-off-by: Tony Lindgren 
> 
> Patch applied.
> 
> > +config GENERIC_PINCTRL
> > +   bool
> 
> Then I renamed *this* to GENERIC_PINCTRL_GROUPS.
> (Not the other patch, I got confused because gmail threads the
> second and third patch together, sorry.)

Yeah OK nice, the renames make sense to me.

> Let's see if I manage to rebase the next patch on this.

I'll do some testing with your devel branch today to make
sure things still work for me.

Regards,

Tony


Re: [PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-12-30 Thread Tony Lindgren
* Linus Walleij  [161230 06:12]:
> On Tue, Dec 27, 2016 at 6:20 PM, Tony Lindgren  wrote:
> 
> > We can add generic helpers for pin group handling for cases where the pin
> > controller driver does not need to use static arrays.
> >
> > Signed-off-by: Tony Lindgren 
> 
> Patch applied.
> 
> > +config GENERIC_PINCTRL
> > +   bool
> 
> Then I renamed *this* to GENERIC_PINCTRL_GROUPS.
> (Not the other patch, I got confused because gmail threads the
> second and third patch together, sorry.)

Yeah OK nice, the renames make sense to me.

> Let's see if I manage to rebase the next patch on this.

I'll do some testing with your devel branch today to make
sure things still work for me.

Regards,

Tony


Re: [PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-12-30 Thread Linus Walleij
On Tue, Dec 27, 2016 at 6:20 PM, Tony Lindgren  wrote:

> We can add generic helpers for pin group handling for cases where the pin
> controller driver does not need to use static arrays.
>
> Signed-off-by: Tony Lindgren 

Patch applied.

> +config GENERIC_PINCTRL
> +   bool

Then I renamed *this* to GENERIC_PINCTRL_GROUPS.
(Not the other patch, I got confused because gmail threads the
second and third patch together, sorry.)

Let's see if I manage to rebase the next patch on this.

Yours,
Linus Walleij


Re: [PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-12-30 Thread Linus Walleij
On Tue, Dec 27, 2016 at 6:20 PM, Tony Lindgren  wrote:

> We can add generic helpers for pin group handling for cases where the pin
> controller driver does not need to use static arrays.
>
> Signed-off-by: Tony Lindgren 

Patch applied.

> +config GENERIC_PINCTRL
> +   bool

Then I renamed *this* to GENERIC_PINCTRL_GROUPS.
(Not the other patch, I got confused because gmail threads the
second and third patch together, sorry.)

Let's see if I manage to rebase the next patch on this.

Yours,
Linus Walleij


[PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-12-27 Thread Tony Lindgren
We can add generic helpers for pin group handling for cases where the pin
controller driver does not need to use static arrays.

Signed-off-by: Tony Lindgren 
---
 drivers/pinctrl/Kconfig |   3 +
 drivers/pinctrl/core.c  | 178 
 drivers/pinctrl/core.h  |  47 +
 3 files changed, 228 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -8,6 +8,9 @@ config PINCTRL
 menu "Pin controllers"
depends on PINCTRL
 
+config GENERIC_PINCTRL
+   bool
+
 config PINMUX
bool "Support pin multiplexing controllers" if COMPILE_TEST
 
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -540,6 +540,182 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev 
*pctldev,
 }
 EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
 
+#ifdef CONFIG_GENERIC_PINCTRL
+
+/**
+ * pinctrl_generic_get_group_count() - returns the number of pin groups
+ * @pctldev: pin controller device
+ */
+int pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev)
+{
+   return pctldev->num_groups;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_count);
+
+/**
+ * pinctrl_generic_get_group_name() - returns the name of a pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ */
+const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev,
+  unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group->name;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_name);
+
+/**
+ * pinctrl_generic_get_group_pins() - gets the pin group pins
+ * @pctldev: pin controller device
+ * @selector: group number
+ * @pins: pins in the group
+ * @num_pins: number of pins in the group
+ */
+int pinctrl_generic_get_group_pins(struct pinctrl_dev *pctldev,
+  unsigned int selector,
+  const unsigned int **pins,
+  unsigned int *num_pins)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group) {
+   dev_err(pctldev->dev, "%s could not find pingroup%i\n",
+   __func__, selector);
+   return -EINVAL;
+   }
+
+   *pins = group->pins;
+   *num_pins = group->num_pins;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_pins);
+
+/**
+ * pinctrl_generic_get_group() - returns a pin group based on the number
+ * @pctldev: pin controller device
+ * @gselector: group number
+ */
+struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group);
+
+/**
+ * pinctrl_generic_add_group() - adds a new pin group
+ * @pctldev: pin controller device
+ * @name: name of the pin group
+ * @pins: pins in the pin group
+ * @num_pins: number of pins in the pin group
+ * @data: pin controller driver specific data
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_add_group(struct pinctrl_dev *pctldev, const char *name,
+ int *pins, int num_pins, void *data)
+{
+   struct group_desc *group;
+
+   group = devm_kzalloc(pctldev->dev, sizeof(*group), GFP_KERNEL);
+   if (!group)
+   return -ENOMEM;
+
+   group->name = name;
+   group->pins = pins;
+   group->num_pins = num_pins;
+   group->data = data;
+
+   radix_tree_insert(>pin_group_tree, pctldev->num_groups,
+ group);
+
+   pctldev->num_groups++;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_add_group);
+
+/**
+ * pinctrl_generic_remove_group() - removes a numbered pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_remove_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return -ENOENT;
+
+   radix_tree_delete(>pin_group_tree, selector);
+   devm_kfree(pctldev->dev, group);
+
+   pctldev->num_groups--;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_remove_group);
+
+/**
+ * pinctrl_generic_free_groups() - 

[PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-12-27 Thread Tony Lindgren
We can add generic helpers for pin group handling for cases where the pin
controller driver does not need to use static arrays.

Signed-off-by: Tony Lindgren 
---
 drivers/pinctrl/Kconfig |   3 +
 drivers/pinctrl/core.c  | 178 
 drivers/pinctrl/core.h  |  47 +
 3 files changed, 228 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -8,6 +8,9 @@ config PINCTRL
 menu "Pin controllers"
depends on PINCTRL
 
+config GENERIC_PINCTRL
+   bool
+
 config PINMUX
bool "Support pin multiplexing controllers" if COMPILE_TEST
 
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -540,6 +540,182 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev 
*pctldev,
 }
 EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
 
+#ifdef CONFIG_GENERIC_PINCTRL
+
+/**
+ * pinctrl_generic_get_group_count() - returns the number of pin groups
+ * @pctldev: pin controller device
+ */
+int pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev)
+{
+   return pctldev->num_groups;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_count);
+
+/**
+ * pinctrl_generic_get_group_name() - returns the name of a pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ */
+const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev,
+  unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group->name;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_name);
+
+/**
+ * pinctrl_generic_get_group_pins() - gets the pin group pins
+ * @pctldev: pin controller device
+ * @selector: group number
+ * @pins: pins in the group
+ * @num_pins: number of pins in the group
+ */
+int pinctrl_generic_get_group_pins(struct pinctrl_dev *pctldev,
+  unsigned int selector,
+  const unsigned int **pins,
+  unsigned int *num_pins)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group) {
+   dev_err(pctldev->dev, "%s could not find pingroup%i\n",
+   __func__, selector);
+   return -EINVAL;
+   }
+
+   *pins = group->pins;
+   *num_pins = group->num_pins;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_pins);
+
+/**
+ * pinctrl_generic_get_group() - returns a pin group based on the number
+ * @pctldev: pin controller device
+ * @gselector: group number
+ */
+struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group);
+
+/**
+ * pinctrl_generic_add_group() - adds a new pin group
+ * @pctldev: pin controller device
+ * @name: name of the pin group
+ * @pins: pins in the pin group
+ * @num_pins: number of pins in the pin group
+ * @data: pin controller driver specific data
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_add_group(struct pinctrl_dev *pctldev, const char *name,
+ int *pins, int num_pins, void *data)
+{
+   struct group_desc *group;
+
+   group = devm_kzalloc(pctldev->dev, sizeof(*group), GFP_KERNEL);
+   if (!group)
+   return -ENOMEM;
+
+   group->name = name;
+   group->pins = pins;
+   group->num_pins = num_pins;
+   group->data = data;
+
+   radix_tree_insert(>pin_group_tree, pctldev->num_groups,
+ group);
+
+   pctldev->num_groups++;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_add_group);
+
+/**
+ * pinctrl_generic_remove_group() - removes a numbered pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_remove_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return -ENOENT;
+
+   radix_tree_delete(>pin_group_tree, selector);
+   devm_kfree(pctldev->dev, group);
+
+   pctldev->num_groups--;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_remove_group);
+
+/**
+ * pinctrl_generic_free_groups() - removes all pin 

[PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-10-25 Thread Tony Lindgren
We can add generic helpers for pin group handling for cases where the pin
controller driver does not need to use static arrays.

Signed-off-by: Tony Lindgren 
---
 drivers/pinctrl/Kconfig |   3 +
 drivers/pinctrl/core.c  | 178 
 drivers/pinctrl/core.h  |  47 +
 3 files changed, 228 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -8,6 +8,9 @@ config PINCTRL
 menu "Pin controllers"
depends on PINCTRL
 
+config GENERIC_PINCTRL
+   bool
+
 config PINMUX
bool "Support pin multiplexing controllers" if COMPILE_TEST
 
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -540,6 +540,182 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev 
*pctldev,
 }
 EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
 
+#ifdef CONFIG_GENERIC_PINCTRL
+
+/**
+ * pinctrl_generic_get_group_count() - returns the number of pin groups
+ * @pctldev: pin controller device
+ */
+int pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev)
+{
+   return pctldev->num_groups;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_count);
+
+/**
+ * pinctrl_generic_get_group_name() - returns the name of a pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ */
+const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev,
+  unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group->name;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_name);
+
+/**
+ * pinctrl_generic_get_group_pins() - gets the pin group pins
+ * @pctldev: pin controller device
+ * @selector: group number
+ * @pins: pins in the group
+ * @num_pins: number of pins in the group
+ */
+int pinctrl_generic_get_group_pins(struct pinctrl_dev *pctldev,
+  unsigned int selector,
+  const unsigned int **pins,
+  unsigned int *num_pins)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group) {
+   dev_err(pctldev->dev, "%s could not find pingroup%i\n",
+   __func__, selector);
+   return -EINVAL;
+   }
+
+   *pins = group->pins;
+   *num_pins = group->num_pins;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_pins);
+
+/**
+ * pinctrl_generic_get_group() - returns a pin group based on the number
+ * @pctldev: pin controller device
+ * @gselector: group number
+ */
+struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group);
+
+/**
+ * pinctrl_generic_add_group() - adds a new pin group
+ * @pctldev: pin controller device
+ * @name: name of the pin group
+ * @pins: pins in the pin group
+ * @num_pins: number of pins in the pin group
+ * @data: pin controller driver specific data
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_add_group(struct pinctrl_dev *pctldev, const char *name,
+ int *pins, int num_pins, void *data)
+{
+   struct group_desc *group;
+
+   group = devm_kzalloc(pctldev->dev, sizeof(*group), GFP_KERNEL);
+   if (!group)
+   return -ENOMEM;
+
+   group->name = name;
+   group->pins = pins;
+   group->num_pins = num_pins;
+   group->data = data;
+
+   radix_tree_insert(>pin_group_tree, pctldev->num_groups,
+ group);
+
+   pctldev->num_groups++;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_add_group);
+
+/**
+ * pinctrl_generic_remove_group() - removes a numbered pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_remove_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return -ENOENT;
+
+   radix_tree_delete(>pin_group_tree, selector);
+   devm_kfree(pctldev->dev, group);
+
+   pctldev->num_groups--;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_remove_group);
+
+/**
+ * pinctrl_generic_free_groups() - 

[PATCH 2/5] pinctrl: core: Add generic pinctrl functions for managing groups

2016-10-25 Thread Tony Lindgren
We can add generic helpers for pin group handling for cases where the pin
controller driver does not need to use static arrays.

Signed-off-by: Tony Lindgren 
---
 drivers/pinctrl/Kconfig |   3 +
 drivers/pinctrl/core.c  | 178 
 drivers/pinctrl/core.h  |  47 +
 3 files changed, 228 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -8,6 +8,9 @@ config PINCTRL
 menu "Pin controllers"
depends on PINCTRL
 
+config GENERIC_PINCTRL
+   bool
+
 config PINMUX
bool "Support pin multiplexing controllers" if COMPILE_TEST
 
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -540,6 +540,182 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev 
*pctldev,
 }
 EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
 
+#ifdef CONFIG_GENERIC_PINCTRL
+
+/**
+ * pinctrl_generic_get_group_count() - returns the number of pin groups
+ * @pctldev: pin controller device
+ */
+int pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev)
+{
+   return pctldev->num_groups;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_count);
+
+/**
+ * pinctrl_generic_get_group_name() - returns the name of a pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ */
+const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev,
+  unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group->name;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_name);
+
+/**
+ * pinctrl_generic_get_group_pins() - gets the pin group pins
+ * @pctldev: pin controller device
+ * @selector: group number
+ * @pins: pins in the group
+ * @num_pins: number of pins in the group
+ */
+int pinctrl_generic_get_group_pins(struct pinctrl_dev *pctldev,
+  unsigned int selector,
+  const unsigned int **pins,
+  unsigned int *num_pins)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group) {
+   dev_err(pctldev->dev, "%s could not find pingroup%i\n",
+   __func__, selector);
+   return -EINVAL;
+   }
+
+   *pins = group->pins;
+   *num_pins = group->num_pins;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_pins);
+
+/**
+ * pinctrl_generic_get_group() - returns a pin group based on the number
+ * @pctldev: pin controller device
+ * @gselector: group number
+ */
+struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return NULL;
+
+   return group;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_group);
+
+/**
+ * pinctrl_generic_add_group() - adds a new pin group
+ * @pctldev: pin controller device
+ * @name: name of the pin group
+ * @pins: pins in the pin group
+ * @num_pins: number of pins in the pin group
+ * @data: pin controller driver specific data
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_add_group(struct pinctrl_dev *pctldev, const char *name,
+ int *pins, int num_pins, void *data)
+{
+   struct group_desc *group;
+
+   group = devm_kzalloc(pctldev->dev, sizeof(*group), GFP_KERNEL);
+   if (!group)
+   return -ENOMEM;
+
+   group->name = name;
+   group->pins = pins;
+   group->num_pins = num_pins;
+   group->data = data;
+
+   radix_tree_insert(>pin_group_tree, pctldev->num_groups,
+ group);
+
+   pctldev->num_groups++;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_add_group);
+
+/**
+ * pinctrl_generic_remove_group() - removes a numbered pin group
+ * @pctldev: pin controller device
+ * @selector: group number
+ *
+ * Note that the caller must take care of locking.
+ */
+int pinctrl_generic_remove_group(struct pinctrl_dev *pctldev,
+unsigned int selector)
+{
+   struct group_desc *group;
+
+   group = radix_tree_lookup(>pin_group_tree,
+ selector);
+   if (!group)
+   return -ENOENT;
+
+   radix_tree_delete(>pin_group_tree, selector);
+   devm_kfree(pctldev->dev, group);
+
+   pctldev->num_groups--;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_remove_group);
+
+/**
+ * pinctrl_generic_free_groups() - removes all pin