]> Pileus Git - ~andy/linux/blobdiff - drivers/pinctrl/core.c
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[~andy/linux] / drivers / pinctrl / core.c
index cec6072cd7c1247436064c764a343d2948be06a0..5cdee8669ea35a8221e17c364e50df0d4c90c781 100644 (file)
@@ -345,6 +345,62 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev,
 }
 EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges);
 
+struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
+               struct pinctrl_gpio_range *range)
+{
+       struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname);
+
+       /*
+        * If we can't find this device, let's assume that is because
+        * it has not probed yet, so the driver trying to register this
+        * range need to defer probing.
+        */
+       if (!pctldev)
+               return ERR_PTR(-EPROBE_DEFER);
+
+       pinctrl_add_gpio_range(pctldev, range);
+       return pctldev;
+}
+EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range);
+
+/**
+ * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin
+ * @pctldev: the pin controller device to look in
+ * @pin: a controller-local number to find the range for
+ */
+struct pinctrl_gpio_range *
+pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
+                                unsigned int pin)
+{
+       struct pinctrl_gpio_range *range = NULL;
+
+       /* Loop over the ranges */
+       list_for_each_entry(range, &pctldev->gpio_ranges, node) {
+               /* Check if we're in the valid range */
+               if (pin >= range->pin_base &&
+                   pin < range->pin_base + range->npins) {
+                       return range;
+               }
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);
+
+/**
+ * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller
+ * @pctldev: pin controller device to remove the range from
+ * @range: the GPIO range to remove
+ */
+void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
+                              struct pinctrl_gpio_range *range)
+{
+       mutex_lock(&pinctrl_mutex);
+       list_del(&range->node);
+       mutex_unlock(&pinctrl_mutex);
+}
+EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
+
 /**
  * pinctrl_get_group_selector() - returns the group selector for a group
  * @pctldev: the pin controller handling the group