All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] Allow for gate and mux control using non-atomic GPIO
@ 2015-08-18 15:40 Michael Allwright
  2015-08-23 10:22 ` Michael Allwright
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Michael Allwright @ 2015-08-18 15:40 UTC (permalink / raw)
  To: Jyri Sarha, ce3a, mturquette, sboyd, Linus Walleij; +Cc: linux-clk

Hi,

The current implementation of clk-gpio completely ignores the use case
where GPIO pins may be accessed over a message based bus like SPI or
I2C. To fix this, and following the comments in clk.h, we should use
the prepare/unprepare methods to do the work where the GPIO operation
would be non-atomic. I propose the following UNTESTED patch (should
apply cleanly over linux-next).

>From 7a21c155e561d84741ce11f0cc4c1f8c5b97d7dc Mon Sep 17 00:00:00 2001
From: Michael Allwright <allsey87@gmail.com>
Date: Tue, 18 Aug 2015 17:26:34 +0200
Subject: [PATCH] Allow non-atomic GPIO ops to control gates and muxes.
 Following the comments in clk.h, use prepare/unprepare methods to do the GPIO
 work in cases where the specified pin can sleep

---
 drivers/clk/clk-gpio.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 10819e2..3172073 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -56,6 +56,29 @@ static int clk_gpio_gate_is_enabled(struct clk_hw *hw)
     return gpiod_get_value(clk->gpiod);
 }

+static int clk_gpio_gate_prepare(struct clk_hw *hw)
+{
+    struct clk_gpio *clk = to_clk_gpio(hw);
+
+    gpiod_set_value_cansleep(clk->gpiod, 1);
+
+    return 0;
+}
+
+static void clk_gpio_gate_unprepare(struct clk_hw *hw)
+{
+    struct clk_gpio *clk = to_clk_gpio(hw);
+
+    gpiod_set_value_cansleep(clk->gpiod, 0);
+}
+
+static int clk_gpio_gate_is_prepared(struct clk_hw *hw)
+{
+    struct clk_gpio *clk = to_clk_gpio(hw);
+
+    return gpiod_get_value_cansleep(clk->gpiod);
+}
+
 const struct clk_ops clk_gpio_gate_ops = {
     .enable = clk_gpio_gate_enable,
     .disable = clk_gpio_gate_disable,
@@ -63,6 +86,14 @@ const struct clk_ops clk_gpio_gate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);

+const struct clk_ops clk_sleepable_gpio_gate_ops = {
+    .enable = clk_gpio_gate_prepare,
+    .disable = clk_gpio_gate_unprepare,
+    .is_enabled = clk_gpio_gate_is_prepared,
+};
+EXPORT_SYMBOL_GPL(clk_sleepable_gpio_gate_ops);
+
+
 /**
  * DOC: basic clock multiplexer which can be controlled with a gpio output
  * Traits of this clock:
@@ -75,14 +106,14 @@ static u8 clk_gpio_mux_get_parent(struct clk_hw *hw)
 {
     struct clk_gpio *clk = to_clk_gpio(hw);

-    return gpiod_get_value(clk->gpiod);
+    return gpiod_get_value_cansleep(clk->gpiod);
 }

 static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
 {
     struct clk_gpio *clk = to_clk_gpio(hw);

-    gpiod_set_value(clk->gpiod, index);
+    gpiod_set_value_cansleep(clk->gpiod, index);

     return 0;
 }
@@ -170,10 +201,17 @@ struct clk *clk_register_gpio_gate(struct device
*dev, const char *name,
         const char *parent_name, unsigned gpio, bool active_low,
         unsigned long flags)
 {
-    return clk_register_gpio(dev, name,
-            (parent_name ? &parent_name : NULL),
-            (parent_name ? 1 : 0), gpio, active_low, flags,
-            &clk_gpio_gate_ops);
+    if(gpio_cansleep(gpio))
+        return clk_register_gpio(dev, name,
+                (parent_name ? &parent_name : NULL),
+                (parent_name ? 1 : 0), gpio, active_low, flags,
+                &clk_sleepable_gpio_gate_ops);
+    else
+        return clk_register_gpio(dev, name,
+                (parent_name ? &parent_name : NULL),
+                (parent_name ? 1 : 0), gpio, active_low, flags,
+                &clk_gpio_gate_ops);
+
 }
 EXPORT_SYMBOL_GPL(clk_register_gpio_gate);

-- 
1.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-09-08  8:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-18 15:40 [RFC] Allow for gate and mux control using non-atomic GPIO Michael Allwright
2015-08-23 10:22 ` Michael Allwright
2015-08-23 12:27 ` Jyri Sarha
2015-08-23 13:28   ` Michael Allwright
2015-09-08  8:41 ` Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.