diff mbox series

[OpenWrt-Devel] ath79: use gpio_hog instead of gpio-export

Message ID 1d85f1b0-7cdb-68d6-3535-72666de254c3@birger-koblitz.de
State Changes Requested
Headers show
Series [OpenWrt-Devel] ath79: use gpio_hog instead of gpio-export | expand

Commit Message

Birger Koblitz Aug. 2, 2019, 9:53 a.m. UTC
ath79: use gpio_hog instead of gpio-export

The `gpio-export` functionality is a hack for
missing kernel functionality, which was rejected in upstream kernel long
time
ago, for details see this email
http://lists.infradead.org/pipermail/openwrt-devel/2019-February/015772.html,
discussion in PR#1366 or
https://github.com/openwrt/openwrt/pull/1814#issuecomment-462942022.

This patch converts all remaining ath79 .dts files which were
using export-gpio to using gpio_hog instead

Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>

---

Comments

Adrian Schmutzler Aug. 7, 2019, 3:16 p.m. UTC | #1
Hi,

> +    lna0 {

is there a scheme for proper names already?

While I do not have an opinion for lnaX, I'd prefer "usb_power"/"usb0_power" over just "usb"/"usb0".

> +        gpio-hog;
> +        line-name = "tp-link:ext:lna0";
> +        gpios = <18 GPIO_ACTIVE_HIGH>;

At least for lnaX, so far "0" (e.g. "gpios = <18 0>;") has been used instead of GPIO_ACTIVE_HIGH. Is there a preference for one of the options?

> +        output-high;
> +    };

Best

Adrian
Adrian Schmutzler Aug. 10, 2019, 8:20 p.m. UTC | #2
Hi,

> +    usb {
> +        gpio-hog;
> +        line-name = "tp-link:power:usb";
> +        gpios = <6 GPIO_ACTIVE_HIGH>;
> +        output-high;
>      };
>  };

As stated earlier, I would prefer calling those blocks usb-power, usb1-power, etc..

> diff --git a/target/linux/ath79/dts/qca9531_yuncore_a770.dts
> b/target/linux/ath79/dts/qca9531_yuncore_a770.dts
> index da5b6dc7db..18ad6307a1 100644
> --- a/target/linux/ath79/dts/qca9531_yuncore_a770.dts
> +++ b/target/linux/ath79/dts/qca9531_yuncore_a770.dts
> @@ -8,7 +8,7 @@
> 
>  / {
>      model = "YunCore A770";
> -    compatible = "yuncore,a770", "qca,qca9531";
> +    compatible = "yuncore,a770", "qca,qca9533";

This should be removed.

> diff --git a/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
> b/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
> index 6d32fa3fc4..378c87c9ee 100644
> --- a/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
> +++ b/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
> @@ -54,22 +54,23 @@
>              gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
>          };
>      };
> +};
> 
> -    gpio-export {
> -        compatible = "gpio-export";
> -
> -        gpio_shift_register_oe {
> -            gpio-export,name = "tp-link:oe:sr";
> -            gpio-export,output = <0>;
> -            gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
> -        };
> +&gpio {
> +    status = "okay";
> 
> -        gpio_shift_register_reset {
> -            gpio-export,name = "tp-link:reset:sr";
> -            gpio-export,output = <1>;
> -            gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
> -        };
> +    sr {
> +        gpio-hog;
> +        line-name = "tp-link:oe:sr";
> +        gpios = <16 GPIO_ACTIVE_HIGH>;
> +        output-low;
> +    };
> 
> +    sr {
> +        gpio-hog;
> +        line-name = "tp-link:reset:sr";
> +        gpios = <19 GPIO_ACTIVE_HIGH>;
> +        output-high;
>      };

Those two should have different node names.

> diff --git a/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
> b/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
> index f4add2fe31..d892d0e960 100644
> --- a/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
> +++ b/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
> @@ -41,22 +41,6 @@
>          };
>      };
> 
> -    gpio-export {
> -        compatible = "gpio-export";
> -
> -        gpio_shift_register_oe {
> -            gpio-export,name = "tp-link:oe:sr";
> -            gpio-export,output = <0>;
> -            gpios = <&gpio 1 GPIO_ACTIVE_LOW>;    // 74HC595 /OE (Output
> Enable)
> -        };
> -
> -        gpio_shift_register_reset {
> -            gpio-export,name = "tp-link:reset:sr";
> -            gpio-export,output = <1>;
> -            gpios = <&gpio 21 GPIO_ACTIVE_LOW>;    // 74HC595 /SRCLR (Serial
> Clear)
> -        };
> -    };
> -
>      leds {
>          compatible = "gpio-leds";
> 
> @@ -148,15 +132,29 @@
> 
>  };
> 
> -&pcie {
> +&gpio {
>      status = "okay";
> +
> +    sr {
> +        gpio-hog;
> +        line-name = "tp-link:oe:sr";
> +        gpios = <1 GPIO_ACTIVE_LOW>;
> +        output-low;
> +    };
> +
> +    sr {
> +        gpio-hog;
> +        line-name = "tp-link:reset:sr";
> +        gpios = <21 GPIO_ACTIVE_LOW>;
> +        output-high;
> +    };
>  };

Same here.

Rest looks good, I haven't checked for duplicate &gpio definitions (you seem to have addressed some).

Best

Adrian
Birger Koblitz Aug. 11, 2019, 11:11 a.m. UTC | #3
Dear Adrian,

I'll resubmit a patch taking your comments into account. I am using a
script that parses the DTS and I will use more of the original line-name
to name the node, i.e.

"tp-link:power:usb" -> power-usb
"tp-link:reset:sr"  -> reset-sr

This should also prevent the double naming of the nodes. I am actually
surprised the DTS compiler did not complain... Things like

-    compatible = "yuncore,a770", "qca,qca9531";
+    compatible = "yuncore,a770", "qca,qca9533";

are probably due to trailing white-space in the original, I'll stop the
script from touching that.

Cheers,

  Birger


On 10.08.19 22:20, mail@adrianschmutzler.de wrote:
> Hi,
>
>> +    usb {
>> +        gpio-hog;
>> +        line-name = "tp-link:power:usb";
>> +        gpios = <6 GPIO_ACTIVE_HIGH>;
>> +        output-high;
>>      };
>>  };
> As stated earlier, I would prefer calling those blocks usb-power, usb1-power, etc..
>
>> diff --git a/target/linux/ath79/dts/qca9531_yuncore_a770.dts
>> b/target/linux/ath79/dts/qca9531_yuncore_a770.dts
>> index da5b6dc7db..18ad6307a1 100644
>> --- a/target/linux/ath79/dts/qca9531_yuncore_a770.dts
>> +++ b/target/linux/ath79/dts/qca9531_yuncore_a770.dts
>> @@ -8,7 +8,7 @@
>>
>>  / {
>>      model = "YunCore A770";
>> -    compatible = "yuncore,a770", "qca,qca9531";
>> +    compatible = "yuncore,a770", "qca,qca9533";
> This should be removed.
>
>> diff --git a/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
>> b/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
>> index 6d32fa3fc4..378c87c9ee 100644
>> --- a/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
>> +++ b/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
>> @@ -54,22 +54,23 @@
>>              gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
>>          };
>>      };
>> +};
>>
>> -    gpio-export {
>> -        compatible = "gpio-export";
>> -
>> -        gpio_shift_register_oe {
>> -            gpio-export,name = "tp-link:oe:sr";
>> -            gpio-export,output = <0>;
>> -            gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
>> -        };
>> +&gpio {
>> +    status = "okay";
>>
>> -        gpio_shift_register_reset {
>> -            gpio-export,name = "tp-link:reset:sr";
>> -            gpio-export,output = <1>;
>> -            gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
>> -        };
>> +    sr {
>> +        gpio-hog;
>> +        line-name = "tp-link:oe:sr";
>> +        gpios = <16 GPIO_ACTIVE_HIGH>;
>> +        output-low;
>> +    };
>>
>> +    sr {
>> +        gpio-hog;
>> +        line-name = "tp-link:reset:sr";
>> +        gpios = <19 GPIO_ACTIVE_HIGH>;
>> +        output-high;
>>      };
> Those two should have different node names.
>
>> diff --git a/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
>> b/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
>> index f4add2fe31..d892d0e960 100644
>> --- a/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
>> +++ b/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
>> @@ -41,22 +41,6 @@
>>          };
>>      };
>>
>> -    gpio-export {
>> -        compatible = "gpio-export";
>> -
>> -        gpio_shift_register_oe {
>> -            gpio-export,name = "tp-link:oe:sr";
>> -            gpio-export,output = <0>;
>> -            gpios = <&gpio 1 GPIO_ACTIVE_LOW>;    // 74HC595 /OE (Output
>> Enable)
>> -        };
>> -
>> -        gpio_shift_register_reset {
>> -            gpio-export,name = "tp-link:reset:sr";
>> -            gpio-export,output = <1>;
>> -            gpios = <&gpio 21 GPIO_ACTIVE_LOW>;    // 74HC595 /SRCLR (Serial
>> Clear)
>> -        };
>> -    };
>> -
>>      leds {
>>          compatible = "gpio-leds";
>>
>> @@ -148,15 +132,29 @@
>>
>>  };
>>
>> -&pcie {
>> +&gpio {
>>      status = "okay";
>> +
>> +    sr {
>> +        gpio-hog;
>> +        line-name = "tp-link:oe:sr";
>> +        gpios = <1 GPIO_ACTIVE_LOW>;
>> +        output-low;
>> +    };
>> +
>> +    sr {
>> +        gpio-hog;
>> +        line-name = "tp-link:reset:sr";
>> +        gpios = <21 GPIO_ACTIVE_LOW>;
>> +        output-high;
>> +    };
>>  };
> Same here.
>
> Rest looks good, I haven't checked for duplicate &gpio definitions (you seem to have addressed some).
>
> Best
>
> Adrian
Adrian Schmutzler Aug. 11, 2019, 7:15 p.m. UTC | #4
> -----Original Message-----
> From: openwrt-devel [mailto:openwrt-devel-bounces@lists.openwrt.org]
> On Behalf Of Birger Koblitz
> Sent: Sonntag, 11. August 2019 13:11
> To: mail@adrianschmutzler.de
> Cc: 'OpenWrt Development List' <openwrt-devel@lists.openwrt.org>
> Subject: Re: [OpenWrt-Devel] [PATCH] ath79: use gpio_hog instead of gpio-
> export
> 
> Dear Adrian,
> 
> I'll resubmit a patch taking your comments into account. I am using a script
> that parses the DTS ...

So that means that duplicate &gpio is also treated with automatically (as I've seen with some devices)?

> This should also prevent the double naming of the nodes. I am actually
> surprised the DTS compiler did not complain... Things like
> 
> -    compatible = "yuncore,a770", "qca,qca9531";
> +    compatible = "yuncore,a770", "qca,qca9533";
> 
> are probably due to trailing white-space in the original, I'll stop the script from
> touching that.

Well, in this particular case it was not only whitespace, but the qca changing from 9531 to 9533...

Best

Adrian
Birger Koblitz Aug. 11, 2019, 8:06 p.m. UTC | #5
Hi Adrian,

On 11.08.19 21:15, mail@adrianschmutzler.de wrote:
>> -----Original Message-----
>> From: openwrt-devel [mailto:openwrt-devel-bounces@lists.openwrt.org]
>> On Behalf Of Birger Koblitz
>> Sent: Sonntag, 11. August 2019 13:11
>> To: mail@adrianschmutzler.de
>> Cc: 'OpenWrt Development List' <openwrt-devel@lists.openwrt.org>
>> Subject: Re: [OpenWrt-Devel] [PATCH] ath79: use gpio_hog instead of gpio-
>> export
>>
>> Dear Adrian,
>>
>> I'll resubmit a patch taking your comments into account. I am using a script
>> that parses the DTS ...
> So that means that duplicate &gpio is also treated with automatically (as I've seen with some devices)?

The script is able to catch some cases, others are not so easy. I
believe there is a case where the original .dts already has duplicates.

Also the idea was to keep the sequence of the gpios definitions in the
original .dts.

If the original dts moves from chip 0 to chip 1 and back to chip 0 with
the definition of gpios being exported, then this will give duplicates
for gpio0 at the moment.

I could sort the gpios so that it is guaranteed that there are no
duplicate gpio definitions but this would destroy the original authors
intention as to which gpio belongs to which other one. 

>
>> This should also prevent the double naming of the nodes. I am actually
>> surprised the DTS compiler did not complain... Things like
>>
>> -    compatible = "yuncore,a770", "qca,qca9531";
>> +    compatible = "yuncore,a770", "qca,qca9533";
>>
>> are probably due to trailing white-space in the original, I'll stop the script from
>> touching that.
> Well, in this particular case it was not only whitespace, but the qca changing from 9531 to 9533...

Ouch, this was an accident with commit
5e9086b7b11976ba75014b257139ddc4b2885a8a

don't know how I messed that up...

>
>
> Adrian

Thanks for the comments,

  Birger


As an afterthought, here comes the current script, I know that it is
ugly, but it shows what is done and how:

#!/usr/bin/ruby
unless ARGV.length == 1
  puts "Usage: convertHog.rb <input.dts>"
  exit
end

line_num = 0
in_root = 0
in_export = false
in_node = false
in_comment = false
last_empty = false
in_node_comment = false
node = -1
node_name = Array.new
node_output = Array.new
node_is_output = Array.new
node_chip = Array.new
node_num = Array.new
node_active = Array.new
node_comment = Array.new
node_prefix = Array.new
gpio_found = Array.new
gpio_stack = ""
remove_next_empty = false
DEBUG = false

f = File.open(ARGV[0])
f.each do |line|
  line_num += 1
  if line.match(/\/\s*\{/) then
    print "Found beginning\n" if DEBUG
    in_root += 1
    print "\n" if last_empty
    print "#{line}"
    last_empty = false
    next
  end
 
  if line.match(/{/) then
    in_root +=1
  end
 
  if line.match(/}/) then
    in_root -=1
  end
 
  if line.match(/^\s*$/) then
    print "last empty\n" if DEBUG
    if not remove_next_empty then
      last_empty = true
      next
    end
  end
   
 
  print "#{line_num} root #{in_root} " if DEBUG
 
  if (in_root > 0) and line.match(/gpio[_\-]export\s*\{/) then
    print "Found export\n" if DEBUG
    in_export = true
    next
  end
 
  if in_export then
    last_empty = false
   
    if not in_node then
      if line.match(/^\s*\/\*\s*$/) then
        in_comment = true;
      end
      if line.match(/^\s*\*\/\s*$/) then
        in_comment = false;
        print "#{line}"
        next
      end
    end
   
    if in_comment then
      print "#{line}"
      next
    end
   
    if line.match(/\w+\s*\{/)
      print "Found node\n" if DEBUG
      in_node = true;
      node += 1
    end
 
    if line.match(/\}\s*;/) then
      if in_node
        in_node = false
      else
        in_export = false
      end
    end
   
    if in_node then
      line.match(/gpio\-export,name\s*=\s*"([\w\d\-:]+:)?([\w\d\-]+)"/)
{ |m|
        if m.length == 2 then
          print "Found export #{m[1]}\n" if DEBUG
          node_name[node] = m[1]
        else
          print "Found export #{m[2]}\n"  if DEBUG
          node_name[node] = m[2]
          node_prefix[node] = m[1]
        end
      }
      line.match(/gpio\-export,output\s*=\s*<(\d)>\s*;/) { |m|
        print "Found output #{m[1]}\n" if DEBUG
        node_output[node] = m[1]
        node_is_output[node] = true
      }
     
line.match(/gpios\s*\=\s*\<\&gpio(\d*)\s+(\d+)\s+GPIO_ACTIVE_(\w+)\s*\>\s*;/i)
{ |m|
        print "Found gpio #{m[1]}, #{m[2]}, #{m[3]}\n" if DEBUG
        node_chip[node] = m[1]
        node_num[node] = m[2]
        node_active[node] = m[3]
        gpio_found[m[1].to_i] = true
      }
      line.match(/\/\*(.*)\*\//){ |m|
        print "Found comment #{m[1]}\n"
        node_comment[node] = m[0]
      }
      if line.match(/^\s*\/\*\s*$/) then
        print "In Node COMMENT\n" if DEBUG
        in_node_comment = true;
        node_comment[node] = ""
      end
      if line.match(/^\s*\*\/\s*$/) then
        print "End Node COMMENT\n" if DEBUG
        node_comment[node] += line
        in_node_comment = false;
      end
      node_comment[node] += line if in_node_comment
     
    end
    next
  else
    print "Outside root " if DEBUG
    line.match(/^\&gpio(\d*).*\{/) { |m|
        print "Found gpio #{m[1]}\n" if DEBUG
        if gpio_found[m[1].to_i] then
          gpio_stack = line
          print "stacking\n" if DEBUG
          line = ""
          remove_next_empty = true
          next
        end
    }
    print "Here\n" if DEBUG
    if gpio_stack != "" then
      if line.match(/status\s*=\s*"okay"/) then
        next
      end
      if line.match(/^\};/) then
        line = "\n" + gpio_stack + line
        if not gpio_stack.match(/;/) then
          line = ""
          print "more\n" if DEBUG
        end
        gpio_stack = ""
      else
        gpio_stack += line
        next
      end
    end 
  end
 
  print "#{line_num} " if DEBUG
  print "\n" if last_empty and not remove_next_empty
  print "#{line}"
  last_empty = false
  remove_next_empty = false
 
  if in_root == 0 then
    last_chip = -1
   
    i = 0
    while i <= node
      if node_chip[i] != last_chip then
        print "\n&gpio#{node_chip[i]} {\n"
        print "\tstatus = \"okay\";\n\n"
      else
        print "\n"
      end
      print "\t#{node_name[i]} {\n"
      comment = node_comment[i]
      if node_comment[i] then
        comment.gsub!(/^\/\*/, "\t\t/*")
        comment.gsub!(/\t\t\t/, "\t\t")
        print "#{comment}\n"
      end
      print "\t\tgpio-hog;\n"
      if node_prefix[i] then
        print "\t\tline-name = \"#{node_prefix[i]}#{node_name[i]}\";\n";
      else
        print "\t\tline-name = \"#{node_name[i]}\";\n";
      end
      print "\t\tgpios = <#{node_num[i]} GPIO_ACTIVE_#{node_active[i]}>;\n"
      if node_is_output[i] then
        if node_output[i].to_i == 1 then
          print "\t\toutput-high;\n"
        else
          print "\t\toutput-low;\n"
        end
      else
        print "\t\tinput;\n"
      end
      print "\t};\n"
      if i == node or node_chip[i] != node_chip[i+1] then
        print "};\n"
      end
      last_chip = node_chip[i]
      i = i+1
    end
    node = -1
  end   
end
Adrian Schmutzler Aug. 11, 2019, 8:41 p.m. UTC | #6
> -----Original Message-----
> From: Birger Koblitz [mailto:mail@birger-koblitz.de]
> Sent: Sonntag, 11. August 2019 22:06
> To: mail@adrianschmutzler.de; 'OpenWrt Development List' <openwrt-
> devel@lists.openwrt.org>
> Subject: Re: [OpenWrt-Devel] [PATCH] ath79: use gpio_hog instead of gpio-
> export
> 
> Hi Adrian,
> 
> On 11.08.19 21:15, mail@adrianschmutzler.de wrote:
> >> -----Original Message-----
> >> From: openwrt-devel [mailto:openwrt-devel-
> bounces@lists.openwrt.org]
> >> On Behalf Of Birger Koblitz
> >> Sent: Sonntag, 11. August 2019 13:11
> >> To: mail@adrianschmutzler.de
> >> Cc: 'OpenWrt Development List' <openwrt-devel@lists.openwrt.org>
> >> Subject: Re: [OpenWrt-Devel] [PATCH] ath79: use gpio_hog instead of
> >> gpio- export
> >>
> >> Dear Adrian,
> >>
> >> I'll resubmit a patch taking your comments into account. I am using a
> >> script that parses the DTS ...
> > So that means that duplicate &gpio is also treated with automatically (as
> I've seen with some devices)?
> 
> The script is able to catch some cases, others are not so easy. I believe there
> is a case where the original .dts already has duplicates.
> 
> Also the idea was to keep the sequence of the gpios definitions in the
> original .dts.

Okay.

I don't think that's the most critical topic, as build-testing will sort out all of the relevant possible errors.

I was mostly asking out of curiosity and would not bother with this further...


Best

Adrian
diff mbox series

Patch

diff --git a/target/linux/ath79/dts/ar7161_buffalo_wzr-hp-ag300h.dts
b/target/linux/ath79/dts/ar7161_buffalo_wzr-hp-ag300h.dts
index df22eb8dc4..822858aab7 100644
--- a/target/linux/ath79/dts/ar7161_buffalo_wzr-hp-ag300h.dts
+++ b/target/linux/ath79/dts/ar7161_buffalo_wzr-hp-ag300h.dts
@@ -121,16 +121,6 @@ 
         };
     };
 
-    gpio-export {
-        compatible = "gpio-export";
-
-        gpio_usb_power {
-            gpio-export,name = "buffalo:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
-        };
-    };
-
     flash {
         compatible = "mtd-concat";
 
@@ -173,6 +163,17 @@ 
     };
 };
 
+&gpio {
+    status = "okay";
+
+    usb {
+        gpio-hog;
+        line-name = "buffalo:power:usb";
+        gpios = <2 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
+};
+
 &usb_phy {
     status = "okay";
 };
diff --git a/target/linux/ath79/dts/ar7241_tplink_tl-mr3x20.dtsi
b/target/linux/ath79/dts/ar7241_tplink_tl-mr3x20.dtsi
index 04403637b6..de0deb3f3c 100644
--- a/target/linux/ath79/dts/ar7241_tplink_tl-mr3x20.dtsi
+++ b/target/linux/ath79/dts/ar7241_tplink_tl-mr3x20.dtsi
@@ -3,15 +3,16 @@ 
 #include "ar7241_tplink.dtsi"
 
 / {
-    gpio-export {
-        compatible = "gpio-export";
-        #size-cells = <0>;
-
-        gpio_usb_power {
-            gpio-export,name = "tp-link:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
-        };
+};
+
+&gpio {
+    status = "okay";
+
+    usb {
+        gpio-hog;
+        line-name = "tp-link:power:usb";
+        gpios = <6 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
diff --git a/target/linux/ath79/dts/ar7241_tplink_tl-wr842n-v1.dts
b/target/linux/ath79/dts/ar7241_tplink_tl-wr842n-v1.dts
index 282446b1e1..829f1fe0e7 100644
--- a/target/linux/ath79/dts/ar7241_tplink_tl-wr842n-v1.dts
+++ b/target/linux/ath79/dts/ar7241_tplink_tl-wr842n-v1.dts
@@ -66,15 +66,16 @@ 
             linux,default-trigger = "phy0tpt";
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
+&gpio {
+    status = "okay";
 
-        gpio_usb_power {
-            gpio-export,name = "tp-link:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
-        };
+    usb {
+        gpio-hog;
+        line-name = "tp-link:power:usb";
+        gpios = <6 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -155,10 +156,6 @@ 
     mtd-mac-address-increment = <1>;
 };
 
-&gpio {
-    status = "okay";
-};
-
 &uart {
     status = "okay";
 };
diff --git a/target/linux/ath79/dts/ar7242_buffalo_wzr-bhr.dtsi
b/target/linux/ath79/dts/ar7242_buffalo_wzr-bhr.dtsi
index 70ce41b84d..aee37729b1 100644
--- a/target/linux/ath79/dts/ar7242_buffalo_wzr-bhr.dtsi
+++ b/target/linux/ath79/dts/ar7242_buffalo_wzr-bhr.dtsi
@@ -58,17 +58,6 @@ 
         };
     };
 
-    gpio-export {
-        compatible = "gpio-export";
-        #size-cells = <0>;
-
-        gpio_usb_power {
-            gpio-export,name = "buffalo:usb-power";
-            gpio-export,output = <1>;
-            gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
-        };
-    };
-
     virtual_flash {
         compatible = "mtd-concat";
         devices = <&flash0 &flash1>;
@@ -110,6 +99,17 @@ 
     };
 };
 
+&gpio {
+    status = "okay";
+
+    usb-power {
+        gpio-hog;
+        line-name = "buffalo:usb-power";
+        gpios = <16 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
+};
+
 &spi {
     status = "okay";
     cs-gpios = <0>, <0>;
diff --git a/target/linux/ath79/dts/ar7242_buffalo_wzr-hp-g302h-a1a0.dts
b/target/linux/ath79/dts/ar7242_buffalo_wzr-hp-g302h-a1a0.dts
index 97bfd0f842..9f04025598 100644
--- a/target/linux/ath79/dts/ar7242_buffalo_wzr-hp-g302h-a1a0.dts
+++ b/target/linux/ath79/dts/ar7242_buffalo_wzr-hp-g302h-a1a0.dts
@@ -110,17 +110,6 @@ 
         };
     };
 
-    gpio-export {
-        compatible = "gpio-export";
-        #size-cells = <0>;
-
-        gpio_usb_power {
-            gpio-export,name = "buffalo:usb-power";
-            gpio-export,output = <1>;
-            gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
-        };
-    };
-
     virtual_flash {
         compatible = "mtd-concat";
         devices = <&flash0 &flash1>;
@@ -162,6 +151,17 @@ 
     };
 };
 
+&gpio {
+    status = "okay";
+
+    usb-power {
+        gpio-hog;
+        line-name = "buffalo:usb-power";
+        gpios = <13 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
+};
+
 &spi {
     status = "okay";
     cs-gpios = <0>, <0>;
diff --git a/target/linux/ath79/dts/ar9341_tplink_tl-wr842n-v2.dts
b/target/linux/ath79/dts/ar9341_tplink_tl-wr842n-v2.dts
index c7a251cbf1..f91f092d37 100644
--- a/target/linux/ath79/dts/ar9341_tplink_tl-wr842n-v2.dts
+++ b/target/linux/ath79/dts/ar9341_tplink_tl-wr842n-v2.dts
@@ -92,15 +92,16 @@ 
             linux,default-trigger = "usbport";
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
+&gpio {
+    status = "okay";
 
-        gpio_usb_power {
-            gpio-export,name = "tp-link:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
-        };
+    usb {
+        gpio-hog;
+        line-name = "tp-link:power:usb";
+        gpios = <4 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -112,10 +113,6 @@ 
     status = "okay";
 };
 
-&gpio {
-    status = "okay";
-};
-
 &spi {
     num-cs = <1>;
 
diff --git a/target/linux/ath79/dts/ar9344_tplink_tl-wdr4300.dtsi
b/target/linux/ath79/dts/ar9344_tplink_tl-wdr4300.dtsi
index 6be197c0cf..a4659a9ec1 100644
--- a/target/linux/ath79/dts/ar9344_tplink_tl-wdr4300.dtsi
+++ b/target/linux/ath79/dts/ar9344_tplink_tl-wdr4300.dtsi
@@ -75,33 +75,37 @@ 
             debounce-interval = <60>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
+&gpio {
+    status = "okay";
 
-        gpio_usb1_power {
-            gpio-export,name = "tp-link:power:usb1";
-            gpio-export,output = <1>;
-            gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
-        };
+    usb1 {
+        gpio-hog;
+        line-name = "tp-link:power:usb1";
+        gpios = <22 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
 
-        gpio_usb2_power {
-            gpio-export,name = "tp-link:power:usb2";
-            gpio-export,output = <1>;
-            gpios = <&gpio 21 GPIO_ACTIVE_HIGH>;
-        };
+    usb2 {
+        gpio-hog;
+        line-name = "tp-link:power:usb2";
+        gpios = <21 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
 
-        gpio_ext_lna0 {
-            gpio-export,name = "tp-link:ext:lna0";
-            gpio-export,output = <1>;
-            gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
-        };
+    lna0 {
+        gpio-hog;
+        line-name = "tp-link:ext:lna0";
+        gpios = <18 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
 
-        gpio_ext_lna1 {
-            gpio-export,name = "tp-link:ext:lna1";
-            gpio-export,output = <1>;
-            gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
-        };
+    lna1 {
+        gpio-hog;
+        line-name = "tp-link:ext:lna1";
+        gpios = <19 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -113,10 +117,6 @@ 
     status = "okay";
 };
 
-&gpio {
-    status = "okay";
-};
-
 &spi {
     num-cs = <1>;
 
diff --git a/target/linux/ath79/dts/qca9531_yuncore_a770.dts
b/target/linux/ath79/dts/qca9531_yuncore_a770.dts
index da5b6dc7db..18ad6307a1 100644
--- a/target/linux/ath79/dts/qca9531_yuncore_a770.dts
+++ b/target/linux/ath79/dts/qca9531_yuncore_a770.dts
@@ -8,7 +8,7 @@ 
 
 / {
     model = "YunCore A770";
-    compatible = "yuncore,a770", "qca,qca9531";
+    compatible = "yuncore,a770", "qca,qca9533";
 
     aliases {
         led-boot = &status;
diff --git a/target/linux/ath79/dts/qca9558_devolo_dvl1750e.dts
b/target/linux/ath79/dts/qca9558_devolo_dvl1750e.dts
index 2570eb7cea..0e4c97bd41 100644
--- a/target/linux/ath79/dts/qca9558_devolo_dvl1750e.dts
+++ b/target/linux/ath79/dts/qca9558_devolo_dvl1750e.dts
@@ -53,16 +53,16 @@ 
         compatible = "gpio-beeper";
         gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
     };
+};
 
+&gpio {
+    status = "okay";
 
-    gpio_export {
-        compatible = "gpio-export";
-
-        gpio_usb_power {
-            gpio-export,name = "devolo:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
-        };
+    usb {
+        gpio-hog;
+        line-name = "devolo:power:usb";
+        gpios = <11 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
diff --git a/target/linux/ath79/dts/qca9558_openmesh_om5p-ac-v2.dts
b/target/linux/ath79/dts/qca9558_openmesh_om5p-ac-v2.dts
index b6dc43fbfc..38b2d2750c 100644
--- a/target/linux/ath79/dts/qca9558_openmesh_om5p-ac-v2.dts
+++ b/target/linux/ath79/dts/qca9558_openmesh_om5p-ac-v2.dts
@@ -51,21 +51,23 @@ 
             gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
-        #size-cells = <0>;
+&gpio {
+    status = "okay";
 
-        gpio_pa_dcdc {
-            gpio-export,name = "om5pac:pa_dcdc";
-            gpio-export,output = <1>;
-            gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
-        };
-        gpio_pa_high {
-            gpio-export,name = "om5pac:pa_high";
-            gpio-export,output = <1>;
-            gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
-        };
+    pa_dcdc {
+        gpio-hog;
+        line-name = "om5pac:pa_dcdc";
+        gpios = <2 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
+
+    pa_high {
+        gpio-hog;
+        line-name = "om5pac:pa_high";
+        gpios = <16 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
diff --git a/target/linux/ath79/dts/qca9558_tplink_archer-c7.dtsi
b/target/linux/ath79/dts/qca9558_tplink_archer-c7.dtsi
index 343d318e0b..095d7d759f 100644
--- a/target/linux/ath79/dts/qca9558_tplink_archer-c7.dtsi
+++ b/target/linux/ath79/dts/qca9558_tplink_archer-c7.dtsi
@@ -63,22 +63,23 @@ 
             debounce-interval = <60>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
-
-        gpio_usb1_power {
-            gpio-export,name = "tp-link:power:usb1";
-            gpio-export,output = <1>;
-            gpios = <&gpio 21 GPIO_ACTIVE_HIGH>;
-        };
+&gpio {
+    status = "okay";
 
-        gpio_usb2_power {
-            gpio-export,name = "tp-link:power:usb2";
-            gpio-export,output = <1>;
-            gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
-        };
+    usb1 {
+        gpio-hog;
+        line-name = "tp-link:power:usb1";
+        gpios = <21 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
 
+    usb2 {
+        gpio-hog;
+        line-name = "tp-link:power:usb2";
+        gpios = <22 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -90,10 +91,6 @@ 
     status = "okay";
 };
 
-&gpio {
-    status = "okay";
-};
-
 &usb_phy0 {
     status = "okay";
 };
diff --git a/target/linux/ath79/dts/qca9558_tplink_tl-wdr4900-v2.dts
b/target/linux/ath79/dts/qca9558_tplink_tl-wdr4900-v2.dts
index 3cc2d790d4..e1b6c6036c 100644
--- a/target/linux/ath79/dts/qca9558_tplink_tl-wdr4900-v2.dts
+++ b/target/linux/ath79/dts/qca9558_tplink_tl-wdr4900-v2.dts
@@ -76,21 +76,23 @@ 
             debounce-interval = <60>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
+&gpio {
+    status = "okay";
 
-        gpio_usb1_power {
-            gpio-export,name = "tp-link:power:usb1";
-            gpio-export,output = <1>;
-            gpios = <&gpio 21 GPIO_ACTIVE_HIGH>;
-        };
+    usb1 {
+        gpio-hog;
+        line-name = "tp-link:power:usb1";
+        gpios = <21 GPIO_ACTIVE_HIGH>;
+        output-high;
+    };
 
-        gpio_usb2_power {
-            gpio-export,name = "tp-link:power:usb2";
-            gpio-export,output = <1>;
-            gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
-        };
+    usb2 {
+        gpio-hog;
+        line-name = "tp-link:power:usb2";
+        gpios = <22 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
diff --git a/target/linux/ath79/dts/qca9558_tplink_tl-wr1043nd.dtsi
b/target/linux/ath79/dts/qca9558_tplink_tl-wr1043nd.dtsi
index 61d4aec624..6977869271 100644
--- a/target/linux/ath79/dts/qca9558_tplink_tl-wr1043nd.dtsi
+++ b/target/linux/ath79/dts/qca9558_tplink_tl-wr1043nd.dtsi
@@ -63,16 +63,16 @@ 
             debounce-interval = <60>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
-        #size-cells = <0>;
+&gpio {
+    status = "okay";
 
-        gpio_usb_power {
-            gpio-export,name = "tp-link:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 21 GPIO_ACTIVE_HIGH>;
-        };
+    usb {
+        gpio-hog;
+        line-name = "tp-link:power:usb";
+        gpios = <21 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -80,10 +80,6 @@ 
     status = "okay";
 };
 
-&gpio {
-    status = "okay";
-};
-
 &usb_phy0 {
     status = "okay";
 };
diff --git a/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
b/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
index 6d32fa3fc4..378c87c9ee 100644
--- a/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
+++ b/target/linux/ath79/dts/qca9561_tplink_archer-c5x.dtsi
@@ -54,22 +54,23 @@ 
             gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
-
-        gpio_shift_register_oe {
-            gpio-export,name = "tp-link:oe:sr";
-            gpio-export,output = <0>;
-            gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
-        };
+&gpio {
+    status = "okay";
 
-        gpio_shift_register_reset {
-            gpio-export,name = "tp-link:reset:sr";
-            gpio-export,output = <1>;
-            gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
-        };
+    sr {
+        gpio-hog;
+        line-name = "tp-link:oe:sr";
+        gpios = <16 GPIO_ACTIVE_HIGH>;
+        output-low;
+    };
 
+    sr {
+        gpio-hog;
+        line-name = "tp-link:reset:sr";
+        gpios = <19 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -77,10 +78,6 @@ 
     status = "okay";
 };
 
-&gpio {
-    status = "okay";
-};
-
 &pcie {
     status = "okay";
 };
diff --git a/target/linux/ath79/dts/qca9563_dlink_dir-859-a1.dts
b/target/linux/ath79/dts/qca9563_dlink_dir-859-a1.dts
index 8bd9067afa..43f5b900ff 100644
--- a/target/linux/ath79/dts/qca9563_dlink_dir-859-a1.dts
+++ b/target/linux/ath79/dts/qca9563_dlink_dir-859-a1.dts
@@ -62,16 +62,16 @@ 
             debounce-interval = <60>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
-        #size-cells = <0>;
+&gpio {
+    status = "okay";
 
-        gpio_switch_reset {
-            gpio-export,name = "dir-859-a1:reset:switch";
-            gpio-export,output = <1>;
-            gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
-        };
+    switch {
+        gpio-hog;
+        line-name = "dir-859-a1:reset:switch";
+        gpios = <11 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -79,10 +79,6 @@ 
     status = "okay";
 };
 
-&gpio {
-    status = "okay";
-};
-
 &pcie {
     status = "okay";
 };
diff --git a/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
b/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
index f4add2fe31..d892d0e960 100644
--- a/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
+++ b/target/linux/ath79/dts/qca9563_tplink_archer-c7-v4.dts
@@ -41,22 +41,6 @@ 
         };
     };
 
-    gpio-export {
-        compatible = "gpio-export";
-
-        gpio_shift_register_oe {
-            gpio-export,name = "tp-link:oe:sr";
-            gpio-export,output = <0>;
-            gpios = <&gpio 1 GPIO_ACTIVE_LOW>;    // 74HC595 /OE
(Output Enable)
-        };
-
-        gpio_shift_register_reset {
-            gpio-export,name = "tp-link:reset:sr";
-            gpio-export,output = <1>;
-            gpios = <&gpio 21 GPIO_ACTIVE_LOW>;    // 74HC595 /SRCLR
(Serial Clear)
-        };
-    };
-
     leds {
         compatible = "gpio-leds";
 
@@ -148,15 +132,29 @@ 
 
 };
 
-&pcie {
+&gpio {
     status = "okay";
+
+    sr {
+        gpio-hog;
+        line-name = "tp-link:oe:sr";
+        gpios = <1 GPIO_ACTIVE_LOW>;
+        output-low;
+    };
+
+    sr {
+        gpio-hog;
+        line-name = "tp-link:reset:sr";
+        gpios = <21 GPIO_ACTIVE_LOW>;
+        output-high;
+    };
 };
 
-&uart {
+&pcie {
     status = "okay";
 };
 
-&gpio {
+&uart {
     status = "okay";
 };
 
diff --git a/target/linux/ath79/dts/qca9563_tplink_archer-x7-v5.dtsi
b/target/linux/ath79/dts/qca9563_tplink_archer-x7-v5.dtsi
index 324d831249..70313d7ce8 100644
--- a/target/linux/ath79/dts/qca9563_tplink_archer-x7-v5.dtsi
+++ b/target/linux/ath79/dts/qca9563_tplink_archer-x7-v5.dtsi
@@ -92,15 +92,16 @@ 
             debounce-interval = <60>;
         };
     };
+};
 
-    gpio-export {
-        compatible = "gpio-export";
+&gpio {
+    status = "okay";
 
-        gpio_usb_power {
-            gpio-export,name = "tp-link:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 19 GPIO_ACTIVE_HIGH>;
-        };
+    usb {
+        gpio-hog;
+        line-name = "tp-link:power:usb";
+        gpios = <19 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };
 
@@ -112,10 +113,6 @@ 
     status = "okay";
 };
 
-&gpio {
-    status = "okay";
-};
-
 &usb_phy0 {
     status = "okay";
 };
diff --git a/target/linux/ath79/dts/qca9563_tplink_tl-wr1043nd-v4.dts
b/target/linux/ath79/dts/qca9563_tplink_tl-wr1043nd-v4.dts
index 07a7409886..bd7299362c 100644
--- a/target/linux/ath79/dts/qca9563_tplink_tl-wr1043nd-v4.dts
+++ b/target/linux/ath79/dts/qca9563_tplink_tl-wr1043nd-v4.dts
@@ -6,16 +6,16 @@ 
 / {
     compatible = "tplink,tl-wr1043nd-v4", "qca,qca9563";
     model = "TP-Link TL-WR1043ND v4";
+};
 
-    gpio-export {
-        compatible = "gpio-export";
-        #size-cells = <0>;
+&gpio {
+    status = "okay";
 
-        gpio_usb_power {
-            gpio-export,name = "tp-link:power:usb";
-            gpio-export,output = <1>;
-            gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
-        };
+    usb {
+        gpio-hog;
+        line-name = "tp-link:power:usb";
+        gpios = <8 GPIO_ACTIVE_HIGH>;
+        output-high;
     };
 };