[V2] ARM: tegra: add DT binding for Tegra186 GPIO controllers
diff mbox

Message ID 1460483197-5130-1-git-send-email-swarren@wwwdotorg.org
State New
Headers show

Commit Message

Stephen Warren April 12, 2016, 5:46 p.m. UTC
From: Stephen Warren <swarren@nvidia.com>

Tegra186 contains two separate but mostly similar GPIO controllers.
Register layout differs significantly from previous Tegra generations, and
so a new binding is required to describe them in device tree. This patch
adds that binding.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Rob Herring <robh@kernel.org>
---
v2: Increase indentation to make lists more readable.

 .../bindings/gpio/nvidia,tegra186-gpio.txt         | 161 +++++++++++++++++++++
 include/dt-bindings/gpio/tegra186-gpio.h           |  56 +++++++
 2 files changed, 217 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
 create mode 100644 include/dt-bindings/gpio/tegra186-gpio.h

Comments

Linus Walleij April 14, 2016, 12:42 p.m. UTC | #1
On Tue, Apr 12, 2016 at 7:46 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:

> From: Stephen Warren <swarren@nvidia.com>
>
> Tegra186 contains two separate but mostly similar GPIO controllers.
> Register layout differs significantly from previous Tegra generations, and
> so a new binding is required to describe them in device tree. This patch
> adds that binding.
>
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> Acked-by: Rob Herring <robh@kernel.org>
> ---
> v2: Increase indentation to make lists more readable.

Very interesting patch!

> +a) Security registers, which allow configuration of allowed access to the GPIO
> +register set. These registers exist in a single contguous block of physical

^ speling: contiguous?

> +Tegra HW documentation describes a unified naming convention for all GPIOs
> +implemented by the SoC. Each GPIO is assigned to a port, and a port may control
> +a number of GPIOs. Thus, each GPIO is named according to an alphabetical port
> +name and an integer GPIO name within the port. For example, GPIO_PA0, GPIO_PN6,
> +or GPIO_PCC3.

I suspect that the Tegra definition of a "port" is close to what other people
call a "bank" like I try to define in this patch?
http://marc.info/?l=linux-gpio&m=145941547420164&w=2

> +The mapping from port name to the GPIO controller that implements that port, and
> +the mapping from port name to register offset within a controller, are both
> +extremely non-linear.

That actually warrants the concept of gpio-bank = <n>;

> + The header file <dt-bindings/gpio/tegra186-gpio.h>
> +describes the port-level mapping. In that file, the naming convention for ports
> +matches the HW documentation. The values chosen for the names are alphabetically
> +sorted within a particular controller. Drivers need to map between the DT GPIO
> +IDs and HW register offsets using a lookup table.

Again that use case. Can you please enter the mentioned thread
and provide some input on how you see this working?

Neil Armstrong provided a driver using the GPIO ranges for
cross-reference to the pin controller as the basis for finding
what is here the port ID. I don't know if that is such a great
idea.

I noticed that the #defines in that tegra186-gpio.h file are not used
in the example below. Something seems wrong: this mapping must
be important. I don't see which of the required properties it should go
into either.

> +Each GPIO controller in fact generates multiple interrupts signals for each set
> +of ports. Each GPIO may be configured to feed into a specific one of the
> +interrupt signals generated by a set-of-ports. The intent is for each generated
> +signal to be routed to a different CPU, thus allowing different CPUs to each
> +handle subsets of the interrupts within a port.

Clever. Seems like something other hardware engineers should pick
up on.

> +/* GPIOs implemented by main GPIO controller */
> +#define TEGRA_MAIN_GPIO_PORT_A 0
> +#define TEGRA_MAIN_GPIO_PORT_B 1
> +#define TEGRA_MAIN_GPIO_PORT_C 2
> +#define TEGRA_MAIN_GPIO_PORT_D 3
> +#define TEGRA_MAIN_GPIO_PORT_E 4
> +#define TEGRA_MAIN_GPIO_PORT_F 5
> +#define TEGRA_MAIN_GPIO_PORT_G 6
> +#define TEGRA_MAIN_GPIO_PORT_H 7
> +#define TEGRA_MAIN_GPIO_PORT_I 8
> +#define TEGRA_MAIN_GPIO_PORT_J 9
> +#define TEGRA_MAIN_GPIO_PORT_K 10
> +#define TEGRA_MAIN_GPIO_PORT_L 11
> +#define TEGRA_MAIN_GPIO_PORT_M 12
> +#define TEGRA_MAIN_GPIO_PORT_N 13
> +#define TEGRA_MAIN_GPIO_PORT_O 14
> +#define TEGRA_MAIN_GPIO_PORT_P 15
> +#define TEGRA_MAIN_GPIO_PORT_Q 16
> +#define TEGRA_MAIN_GPIO_PORT_R 17
> +#define TEGRA_MAIN_GPIO_PORT_T 18
> +#define TEGRA_MAIN_GPIO_PORT_X 19
> +#define TEGRA_MAIN_GPIO_PORT_Y 20
> +#define TEGRA_MAIN_GPIO_PORT_BB 21
> +#define TEGRA_MAIN_GPIO_PORT_CC 22
> +
> +#define TEGRA_MAIN_GPIO(port, offset) \
> +       ((TEGRA_MAIN_GPIO_PORT_##port * 8) + offset)
> +
> +/* GPIOs implemented by AON GPIO controller */
> +#define TEGRA_AON_GPIO_PORT_S 0
> +#define TEGRA_AON_GPIO_PORT_U 1
> +#define TEGRA_AON_GPIO_PORT_V 2
> +#define TEGRA_AON_GPIO_PORT_W 3
> +#define TEGRA_AON_GPIO_PORT_Z 4
> +#define TEGRA_AON_GPIO_PORT_AA 5
> +#define TEGRA_AON_GPIO_PORT_EE 6
> +#define TEGRA_AON_GPIO_PORT_FF 7
> +
> +#define TEGRA_AON_GPIO(port, offset) \
> +       ((TEGRA_AON_GPIO_PORT_##port * 8) + offset)

So we definately need this stuff used in the example.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Stephen Warren April 14, 2016, 3:16 p.m. UTC | #2
On 04/14/2016 06:42 AM, Linus Walleij wrote:
> On Tue, Apr 12, 2016 at 7:46 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>
>> From: Stephen Warren <swarren@nvidia.com>
>>
>> Tegra186 contains two separate but mostly similar GPIO controllers.
>> Register layout differs significantly from previous Tegra generations, and
>> so a new binding is required to describe them in device tree. This patch
>> adds that binding.
>>
>> Signed-off-by: Stephen Warren <swarren@nvidia.com>
>> Acked-by: Rob Herring <robh@kernel.org>
>> ---
>> v2: Increase indentation to make lists more readable.
>
> Very interesting patch!
>
>> +a) Security registers, which allow configuration of allowed access to the GPIO
>> +register set. These registers exist in a single contguous block of physical
>
> ^ speling: contiguous?
>
>> +Tegra HW documentation describes a unified naming convention for all GPIOs
>> +implemented by the SoC. Each GPIO is assigned to a port, and a port may control
>> +a number of GPIOs. Thus, each GPIO is named according to an alphabetical port
>> +name and an integer GPIO name within the port. For example, GPIO_PA0, GPIO_PN6,
>> +or GPIO_PCC3.
>
> I suspect that the Tegra definition of a "port" is close to what other people
> call a "bank" like I try to define in this patch?
> http://marc.info/?l=linux-gpio&m=145941547420164&w=2

There are similarities, but the concepts are quite different. In that 
thread, the term "bank" actually refers to an instance of a standalone 
HW IP block. Here, "port" is definitely something internal to a single 
HW block.

>> +The mapping from port name to the GPIO controller that implements that port, and
>> +the mapping from port name to register offset within a controller, are both
>> +extremely non-linear.
>
> That actually warrants the concept of gpio-bank = <n>;

The DT node itself represents a HW block that contains a set of ports. 
There's no DT node per port, just one per GPIO controller. There's no 
concept of numbered ID for the two GPIO controllers on Tegra, so I don't 
think gpio-bank is appropriate.

>> + The header file <dt-bindings/gpio/tegra186-gpio.h>
>> +describes the port-level mapping. In that file, the naming convention for ports
>> +matches the HW documentation. The values chosen for the names are alphabetically
>> +sorted within a particular controller. Drivers need to map between the DT GPIO
>> +IDs and HW register offsets using a lookup table.
>
> Again that use case. Can you please enter the mentioned thread
> and provide some input on how you see this working?

I don't believe that thread applies to the Tegra GPIO controller.

> Neil Armstrong provided a driver using the GPIO ranges for
> cross-reference to the pin controller as the basis for finding
> what is here the port ID. I don't know if that is such a great
> idea.
>
> I noticed that the #defines in that tegra186-gpio.h file are not used
> in the example below. Something seems wrong: this mapping must
> be important. I don't see which of the required properties it should go
> into either.

The defines would be used to calculate the GPIO ID cell of the GPIO 
specifier in DT. They work in exactly the same way as other headers in 
include/dt-bindings/gpio, in particular tegra-gpio.h is very similar in 
structure.

At present, there is no upstream-targeted Linux driver for this HW, and 
the upstream DT has not been written. I'm working on a U-Boot driver, so 
need the binding defined for that. You can find the U-Boot driver in 
this commit list:

https://github.com/swarren/u-boot/commits/tegra_dev

Search for "gpio: add Tegra186 GPIO driver". I don't want to link to a 
specific commit hash since that's my local development branch and it 
gets rebased all the time. The most relevant parts are likely 
tegra186_gpio_main_ports[], tegra186_gpio_aon_ports[], and 
tegra186_gpio_ids[]. I'd expect those tables to appear almost 
identically in any Linux driver.

>> +Each GPIO controller in fact generates multiple interrupts signals for each set
>> +of ports. Each GPIO may be configured to feed into a specific one of the
>> +interrupt signals generated by a set-of-ports. The intent is for each generated
>> +signal to be routed to a different CPU, thus allowing different CPUs to each
>> +handle subsets of the interrupts within a port.
>
> Clever. Seems like something other hardware engineers should pick
> up on.
>
>> +/* GPIOs implemented by main GPIO controller */
>> +#define TEGRA_MAIN_GPIO_PORT_A 0
...
>> +#define TEGRA_AON_GPIO(port, offset) \
>> +       ((TEGRA_AON_GPIO_PORT_##port * 8) + offset)
>
> So we definately need this stuff used in the example.

Hmm. I really hope not. That would prevent getting DT bindings defined 
early on for the HW, before drivers and DT are written for a platform. 
Any existing Tegra DT file is a good example though; the structure of 
this binding is essentially identical to the previous Tegra GPIO 
controller binding. The only thing different is the exact values that go 
into the properties, and the non-linear mapping of GPIO IDs.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij April 15, 2016, 9:17 a.m. UTC | #3
On Thu, Apr 14, 2016 at 5:16 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/14/2016 06:42 AM, Linus Walleij wrote:
>> On Tue, Apr 12, 2016 at 7:46 PM, Stephen Warren <swarren@wwwdotorg.org>
>> wrote:

>> I suspect that the Tegra definition of a "port" is close to what other
>> people
>> call a "bank" like I try to define in this patch?
>> http://marc.info/?l=linux-gpio&m=145941547420164&w=2
>
> There are similarities, but the concepts are quite different. In that
> thread, the term "bank" actually refers to an instance of a standalone HW IP
> block. Here, "port" is definitely something internal to a single HW block.

OK I get it. I wonder if we can make that common terminology as well.

GPIO bank := unique instance of a common IP block
GPIO port := unique line range inside an IP block

>> Again that use case. Can you please enter the mentioned thread
>> and provide some input on how you see this working?
>
> I don't believe that thread applies to the Tegra GPIO controller.

OK

>> I noticed that the #defines in that tegra186-gpio.h file are not used
>> in the example below. Something seems wrong: this mapping must
>> be important. I don't see which of the required properties it should go
>> into either.
>
> The defines would be used to calculate the GPIO ID cell of the GPIO
> specifier in DT. They work in exactly the same way as other headers in
> include/dt-bindings/gpio, in particular tegra-gpio.h is very similar in
> structure.
>
> At present, there is no upstream-targeted Linux driver for this HW, and the
> upstream DT has not been written. I'm working on a U-Boot driver, so need
> the binding defined for that. You can find the U-Boot driver in this commit
> list:

OK I am ACKing this, your effort to use the Linux DTS as point of
reference should be encouraged.

>> So we definately need this stuff used in the example.
>
> Hmm. I really hope not. That would prevent getting DT bindings defined early
> on for the HW, before drivers and DT are written for a platform. Any
> existing Tegra DT file is a good example though; the structure of this
> binding is essentially identical to the previous Tegra GPIO controller
> binding. The only thing different is the exact values that go into the
> properties, and the non-linear mapping of GPIO IDs.

It's cool.
Acked-by: Linus Walleij <linus.walleij@linaro.org>

I assume you want to merge this through the Tegra tree, or
should I apply it to the GPIO tree?

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Stephen Warren April 15, 2016, 4:04 p.m. UTC | #4
On 04/15/2016 03:17 AM, Linus Walleij wrote:
> On Thu, Apr 14, 2016 at 5:16 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 04/14/2016 06:42 AM, Linus Walleij wrote:
>>> On Tue, Apr 12, 2016 at 7:46 PM, Stephen Warren <swarren@wwwdotorg.org>
>>> wrote:
>
>>> I suspect that the Tegra definition of a "port" is close to what other
>>> people
>>> call a "bank" like I try to define in this patch?
>>> http://marc.info/?l=linux-gpio&m=145941547420164&w=2
>>
>> There are similarities, but the concepts are quite different. In that
>> thread, the term "bank" actually refers to an instance of a standalone HW IP
>> block. Here, "port" is definitely something internal to a single HW block.
>
> OK I get it. I wonder if we can make that common terminology as well.
>
> GPIO bank := unique instance of a common IP block
> GPIO port := unique line range inside an IP block

I think this would be hard, and in some places potentially confusing.

Various HW documentation likely uses the terms bank and port, without 
regard to how those terms are used in documentation for other chips. I'd 
like the binding for any particular chip to use the same terminology as 
the HW documentation for that chip, even if it's inconsistent with other 
bindings (or at least contain an explicit terminology translation 
table). That's because the binding is intended as HW documentation.

Within the Linux code, we could certainly attempt to use consistent 
terminology. If so, I suggest we use terms that are quite unlikely to be 
used by any HW documentation, or could only realistically be used to 
mean the same thing. If we decided to use "GPIO bank" and "GPIO port" as 
you defined above, yet some HW documentation already used "GPIO bank" to 
mean a subset of GPIOs within a single IP block, and "GPIO port" to mean 
a single GPIO (both of which I think are quite likely/possible), then 
that's going to make matters worse not better.

Perhaps "HW module"m "IP block" or perhaps "device" would be a 
reasonable term for "GPIO bank" as you defined that above. Of course, 
bikeshedding:-)

I'm not sure of a reasonable term for "GPIO port" as you defined it.

...
> It's cool.
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
>
> I assume you want to merge this through the Tegra tree, or
> should I apply it to the GPIO tree?

I'm happy either way. If through the Tegra tree, Thierry would be 
applying it so I'll let him make the call.

I suspect that both this patch and my earlier "ARM: tegra: fix naming in 
GPIO DT binding header" should be applied through the same tree for 
consistency.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thierry Reding April 22, 2016, 11:41 a.m. UTC | #5
On Fri, Apr 15, 2016 at 10:04:23AM -0600, Stephen Warren wrote:
> On 04/15/2016 03:17 AM, Linus Walleij wrote:
> > On Thu, Apr 14, 2016 at 5:16 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> > > On 04/14/2016 06:42 AM, Linus Walleij wrote:
> > > > On Tue, Apr 12, 2016 at 7:46 PM, Stephen Warren <swarren@wwwdotorg.org>
> > > > wrote:
> > 
> > > > I suspect that the Tegra definition of a "port" is close to what other
> > > > people
> > > > call a "bank" like I try to define in this patch?
> > > > http://marc.info/?l=linux-gpio&m=145941547420164&w=2
> > > 
> > > There are similarities, but the concepts are quite different. In that
> > > thread, the term "bank" actually refers to an instance of a standalone HW IP
> > > block. Here, "port" is definitely something internal to a single HW block.
> > 
> > OK I get it. I wonder if we can make that common terminology as well.
> > 
> > GPIO bank := unique instance of a common IP block
> > GPIO port := unique line range inside an IP block
> 
> I think this would be hard, and in some places potentially confusing.
> 
> Various HW documentation likely uses the terms bank and port, without regard
> to how those terms are used in documentation for other chips. I'd like the
> binding for any particular chip to use the same terminology as the HW
> documentation for that chip, even if it's inconsistent with other bindings
> (or at least contain an explicit terminology translation table). That's
> because the binding is intended as HW documentation.
> 
> Within the Linux code, we could certainly attempt to use consistent
> terminology. If so, I suggest we use terms that are quite unlikely to be
> used by any HW documentation, or could only realistically be used to mean
> the same thing. If we decided to use "GPIO bank" and "GPIO port" as you
> defined above, yet some HW documentation already used "GPIO bank" to mean a
> subset of GPIOs within a single IP block, and "GPIO port" to mean a single
> GPIO (both of which I think are quite likely/possible), then that's going to
> make matters worse not better.
> 
> Perhaps "HW module"m "IP block" or perhaps "device" would be a reasonable
> term for "GPIO bank" as you defined that above. Of course, bikeshedding:-)
> 
> I'm not sure of a reasonable term for "GPIO port" as you defined it.
> 
> ...
> > It's cool.
> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
> > 
> > I assume you want to merge this through the Tegra tree, or
> > should I apply it to the GPIO tree?
> 
> I'm happy either way. If through the Tegra tree, Thierry would be applying
> it so I'll let him make the call.
> 
> I suspect that both this patch and my earlier "ARM: tegra: fix naming in
> GPIO DT binding header" should be applied through the same tree for
> consistency.

Applied (to the same tree as that other patch), thanks.

Thierry

Patch
diff mbox

diff --git a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
new file mode 100644
index 000000000000..34f111f79252
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
@@ -0,0 +1,161 @@ 
+NVIDIA Tegra186 GPIO controllers
+
+Tegra186 contains two GPIO controllers; a main controller and an "AON"
+controller. This binding document applies to both controllers. The register
+layouts for the controllers share many similarities, but also some significant
+differences. Hence, this document describes closely related but different
+bindings and compatible values.
+
+The Tegra186 GPIO controller allows software to set the IO direction of, and
+read/write the value of, numerous GPIO signals. Routing of GPIO signals to
+package balls is under the control of a separate pin controller HW block. Two
+major sets of registers exist:
+
+a) Security registers, which allow configuration of allowed access to the GPIO
+register set. These registers exist in a single contguous block of physical
+address space. The size of this block, and the security features available,
+varies between the different GPIO controllers.
+
+Access to this set of registers is not necessary in all circumstances. Code
+that wishes to configure access to the GPIO registers needs access to these
+registers to do so. Code which simply wishes to read or write GPIO data does not
+need access to these registers.
+
+b) GPIO registers, which allow manipulation of the GPIO signals. In some GPIO
+controllers, these registers are exposed via multiple "physical aliases" in
+address space, each of which access the same underlying state. See the hardware
+documentation for rationale. Any particular GPIO client is expected to access
+just one of these physical aliases.
+
+Tegra HW documentation describes a unified naming convention for all GPIOs
+implemented by the SoC. Each GPIO is assigned to a port, and a port may control
+a number of GPIOs. Thus, each GPIO is named according to an alphabetical port
+name and an integer GPIO name within the port. For example, GPIO_PA0, GPIO_PN6,
+or GPIO_PCC3.
+
+The number of ports implemented by each GPIO controller varies. The number of
+implemented GPIOs within each port varies. GPIO registers within a controller
+are grouped and laid out according to the port they affect.
+
+The mapping from port name to the GPIO controller that implements that port, and
+the mapping from port name to register offset within a controller, are both
+extremely non-linear. The header file <dt-bindings/gpio/tegra186-gpio.h>
+describes the port-level mapping. In that file, the naming convention for ports
+matches the HW documentation. The values chosen for the names are alphabetically
+sorted within a particular controller. Drivers need to map between the DT GPIO
+IDs and HW register offsets using a lookup table.
+
+Each GPIO controller can generate a number of interrupt signals. Each signal
+represents the aggregate status for all GPIOs within a set of ports. Thus, the
+number of interrupt signals generated by a controller varies as a rough function
+of the number of ports it implements. Note that the HW documentation refers to
+both the overall controller HW module and the sets-of-ports as "controllers".
+
+Each GPIO controller in fact generates multiple interrupts signals for each set
+of ports. Each GPIO may be configured to feed into a specific one of the
+interrupt signals generated by a set-of-ports. The intent is for each generated
+signal to be routed to a different CPU, thus allowing different CPUs to each
+handle subsets of the interrupts within a port. The status of each of these
+per-port-set signals is reported via a separate register. Thus, a driver needs
+to know which status register to observe. This binding currently defines no
+configuration mechanism for this. By default, drivers should use register
+GPIO_${port}_INTERRUPT_STATUS_G1_0. Future revisions to the binding could
+define a property to configure this.
+
+Required properties:
+- compatible
+    Array of strings.
+    One of:
+    - "nvidia,tegra186-gpio".
+    - "nvidia,tegra186-gpio-aon".
+- reg-names
+    Array of strings.
+    Contains a list of names for the register spaces described by the reg
+    property. May contain the following entries, in any order:
+    - "gpio": Mandatory. GPIO control registers. This may cover either:
+        a) The single physical alias that this OS should use.
+        b) All physical aliases that exist in the controller. This is
+           appropriate when the OS is responsible for managing assignment of
+           the physical aliass.
+    - "security": Optional. Security configuration registers.
+    Users of this binding MUST look up entries in the reg property by name,
+    using this reg-names property to do so.
+- reg
+    Array of (physical base address, length) tuples.
+    Must contain one entry per entry in the reg-names property, in a matching
+    order.
+- interrupts
+    Array of interrupt specifiers.
+    The interrupt outputs from the HW block, one per set of ports, in the
+    order the HW manual describes them. The number of entries required varies
+    depending on compatible value:
+    - "nvidia,tegra186-gpio": 6 entries.
+    - "nvidia,tegra186-gpio-aon": 1 entry.
+- gpio-controller
+    Boolean.
+    Marks the device node as a GPIO controller/provider.
+- #gpio-cells
+    Single-cell integer.
+    Must be <2>.
+    Indicates how many cells are used in a consumer's GPIO specifier.
+    In the specifier:
+    - The first cell is the pin number.
+        See <dt-bindings/gpio/tegra186-gpio.h>.
+    - The second cell contains flags:
+        - Bit 0 specifies polarity
+            - 0: Active-high (normal).
+            - 1: Active-low (inverted).
+- interrupt-controller
+    Boolean.
+    Marks the device node as an interrupt controller/provider.
+- #interrupt-cells
+    Single-cell integer.
+    Must be <2>.
+    Indicates how many cells are used in a consumer's interrupt specifier.
+    In the specifier:
+    - The first cell is the GPIO number.
+        See <dt-bindings/gpio/tegra186-gpio.h>.
+    - The second cell is contains flags:
+        - Bits [3:0] indicate trigger type and level:
+            - 1: Low-to-high edge triggered.
+            - 2: High-to-low edge triggered.
+            - 4: Active high level-sensitive.
+            - 8: Active low level-sensitive.
+            Valid combinations are 1, 2, 3, 4, 8.
+
+Example:
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+gpio@2200000 {
+	compatible = "nvidia,tegra186-gpio";
+	reg-names = "security", "gpio";
+	reg =
+		<0x0 0x2200000 0x0 0x10000>,
+		<0x0 0x2210000 0x0 0x10000>;
+	interrupts =
+		<0 47 IRQ_TYPE_LEVEL_HIGH>,
+		<0 50 IRQ_TYPE_LEVEL_HIGH>,
+		<0 53 IRQ_TYPE_LEVEL_HIGH>,
+		<0 56 IRQ_TYPE_LEVEL_HIGH>,
+		<0 59 IRQ_TYPE_LEVEL_HIGH>,
+		<0 180 IRQ_TYPE_LEVEL_HIGH>;
+	gpio-controller;
+	#gpio-cells = <2>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+};
+
+gpio@c2f0000 {
+	compatible = "nvidia,tegra186-gpio-aon";
+	reg-names = "security", "gpio";
+	reg =
+		<0x0 0xc2f0000 0x0 0x1000>,
+		<0x0 0xc2f1000 0x0 0x1000>;
+	interrupts =
+		<0 60 IRQ_TYPE_LEVEL_HIGH>;
+	gpio-controller;
+	#gpio-cells = <2>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+};
diff --git a/include/dt-bindings/gpio/tegra186-gpio.h b/include/dt-bindings/gpio/tegra186-gpio.h
new file mode 100644
index 000000000000..38001c7023f1
--- /dev/null
+++ b/include/dt-bindings/gpio/tegra186-gpio.h
@@ -0,0 +1,56 @@ 
+/*
+ * This header provides constants for binding nvidia,tegra186-gpio*.
+ *
+ * The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below
+ * provide names for this.
+ *
+ * The second cell contains standard flag values specified in gpio.h.
+ */
+
+#ifndef _DT_BINDINGS_GPIO_TEGRA_GPIO_H
+#define _DT_BINDINGS_GPIO_TEGRA_GPIO_H
+
+#include <dt-bindings/gpio/gpio.h>
+
+/* GPIOs implemented by main GPIO controller */
+#define TEGRA_MAIN_GPIO_PORT_A 0
+#define TEGRA_MAIN_GPIO_PORT_B 1
+#define TEGRA_MAIN_GPIO_PORT_C 2
+#define TEGRA_MAIN_GPIO_PORT_D 3
+#define TEGRA_MAIN_GPIO_PORT_E 4
+#define TEGRA_MAIN_GPIO_PORT_F 5
+#define TEGRA_MAIN_GPIO_PORT_G 6
+#define TEGRA_MAIN_GPIO_PORT_H 7
+#define TEGRA_MAIN_GPIO_PORT_I 8
+#define TEGRA_MAIN_GPIO_PORT_J 9
+#define TEGRA_MAIN_GPIO_PORT_K 10
+#define TEGRA_MAIN_GPIO_PORT_L 11
+#define TEGRA_MAIN_GPIO_PORT_M 12
+#define TEGRA_MAIN_GPIO_PORT_N 13
+#define TEGRA_MAIN_GPIO_PORT_O 14
+#define TEGRA_MAIN_GPIO_PORT_P 15
+#define TEGRA_MAIN_GPIO_PORT_Q 16
+#define TEGRA_MAIN_GPIO_PORT_R 17
+#define TEGRA_MAIN_GPIO_PORT_T 18
+#define TEGRA_MAIN_GPIO_PORT_X 19
+#define TEGRA_MAIN_GPIO_PORT_Y 20
+#define TEGRA_MAIN_GPIO_PORT_BB 21
+#define TEGRA_MAIN_GPIO_PORT_CC 22
+
+#define TEGRA_MAIN_GPIO(port, offset) \
+	((TEGRA_MAIN_GPIO_PORT_##port * 8) + offset)
+
+/* GPIOs implemented by AON GPIO controller */
+#define TEGRA_AON_GPIO_PORT_S 0
+#define TEGRA_AON_GPIO_PORT_U 1
+#define TEGRA_AON_GPIO_PORT_V 2
+#define TEGRA_AON_GPIO_PORT_W 3
+#define TEGRA_AON_GPIO_PORT_Z 4
+#define TEGRA_AON_GPIO_PORT_AA 5
+#define TEGRA_AON_GPIO_PORT_EE 6
+#define TEGRA_AON_GPIO_PORT_FF 7
+
+#define TEGRA_AON_GPIO(port, offset) \
+	((TEGRA_AON_GPIO_PORT_##port * 8) + offset)
+
+#endif