|
@@ -977,3 +977,70 @@ void bfin_gpio_free(unsigned gpio)
|
|
|
|
|
|
unreserve(gpio, gpio);
|
|
|
|
|
|
+ set_label(gpio, "free");
|
|
|
+
|
|
|
+ hard_local_irq_restore(flags);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(bfin_gpio_free);
|
|
|
+
|
|
|
+#ifdef BFIN_SPECIAL_GPIO_BANKS
|
|
|
+DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
|
|
|
+
|
|
|
+int bfin_special_gpio_request(unsigned gpio, const char *label)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ flags = hard_local_irq_save();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Allow that the identical GPIO can
|
|
|
+ * be requested from the same driver twice
|
|
|
+ * Do nothing and return -
|
|
|
+ */
|
|
|
+
|
|
|
+ if (cmp_label(gpio, label) == 0) {
|
|
|
+ hard_local_irq_restore(flags);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (unlikely(is_reserved(special_gpio, gpio, 1))) {
|
|
|
+ hard_local_irq_restore(flags);
|
|
|
+ printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
|
|
|
+ gpio, get_label(gpio));
|
|
|
+
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+ if (unlikely(is_reserved(peri, gpio, 1))) {
|
|
|
+ hard_local_irq_restore(flags);
|
|
|
+ printk(KERN_ERR
|
|
|
+ "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
|
|
|
+ gpio, get_label(gpio));
|
|
|
+
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+
|
|
|
+ reserve(special_gpio, gpio);
|
|
|
+ reserve(peri, gpio);
|
|
|
+
|
|
|
+ set_label(gpio, label);
|
|
|
+ hard_local_irq_restore(flags);
|
|
|
+ port_setup(gpio, GPIO_USAGE);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(bfin_special_gpio_request);
|
|
|
+
|
|
|
+void bfin_special_gpio_free(unsigned gpio)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ might_sleep();
|
|
|
+
|
|
|
+ flags = hard_local_irq_save();
|
|
|
+
|
|
|
+ if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
|
|
|
+ gpio_error(gpio);
|
|
|
+ hard_local_irq_restore(flags);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|