All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
@ 2012-10-08  8:39 ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

This patch series is a work on improving usability and extensibiltiy of the
pinctrl-samsung driver. It consists of three main parts:
 - moving SoC-specific data to device tree
 - converting the driver to use one GPIO chip and one IRQ domain per pin bank
 - introducing generic wake-up interrupt capability description

What the first part does is replacing static platform-specific data in
pinctrl-samsung driver with data dynamically parsed from device tree.

It aims at reducing the SoC-specific part of the driver and thus the
amount of modifications to driver sources when adding support for next
SoCs (like Exynos4x12).

In addition, it extends the description of SoC-specific attributes to cover all
mainlined Samsung SoCs, starting from s3c24xx and ending on latest Exynos5
series, with the exception of 4-bit banks with more than 8 pins on S3C64xx,
which will be covered by futher patch(es).

The second part attempts to simplify usage of the driver and fix several
problems of current implementation, in particular:

  - Simplifies GPIO pin specification in device tree by using pin
    namespace local to pin bank instead of local to pin controller, e.g.

        gpios = <&gpj0 3 0>;

    instead of

        gpios = <&pinctrl0 115 0>;

  - Simplifies GPIO interrupt specification in device tree by using
    namespace local to pin bank (and equal to GPIO namespace), e.g.

        interrupt-parent = <&gpj0>;
        interrupts = <3 0>;

    instead of

        interrupt-parent = <&pinctrl0>;
        interrupts = <115 0>;

  - Simplifies internal GPIO pin to bank translation thanks to
    correspondence of particular GPIO chips to pin banks. This allows
    to remove the (costly in case of GPIO bit-banging drivers) lookup
    over all banks to find the one that the pin is from.

Third part is focused on removing the static, hard-coded description of wake-up
interrupt controller and wake-up interrupt layout.

It defines a (mostly) generic (in scope of targetted SoCs) wake-up interrupt
layout specification format that allows to specify which pin banks support
wake-up interrupts and how they are handled (direct or multiplexed/chained).

See particular patches for more detailed descriptions and the last patch for
updated device tree bindings.

Tomasz Figa (16):
  ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl
    bank nodes
  pinctrl: exynos: Parse wakeup-eint parameters from DT
  pinctrl: samsung: Detect and handle unsupported configuration types
  pinctrl: samsung: Parse pin banks from DT
  pinctrl: exynos: Remove static SoC-specific data
  pinctrl: samsung: Parse bank-specific eint offset from DT
  pinctrl: samsung: Hold OF node of pin bank in bank struct
  pinctrl: samsung: Hold pointer to driver data in bank struct
  pinctrl: exynos: Use one IRQ domain per pin bank
  pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
  pinctrl: samsung: Use one GPIO chip per pin bank
  pinctrl: samsung: Use per-bank IRQ domain for wake-up interrupts
  pinctrl: exynos: Set pin function to EINT in irq_set_type of wake-up
    EINT
  pinctrl: samsung: Parse offsets of particular registers from DT
  pinctrl: samsung: Add GPIO to IRQ translation
  Documentation: Update samsung-pinctrl device tree bindings
    documentation

 .../bindings/pinctrl/samsung-pinctrl.txt           | 212 ++++++++--
 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi    | 459 +++++++++++++++++++++
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi          |   2 +
 arch/arm/boot/dts/exynos4210.dtsi                  | 254 +-----------
 drivers/pinctrl/pinctrl-exynos.c                   | 399 ++++++++----------
 drivers/pinctrl/pinctrl-exynos.h                   | 184 +--------
 drivers/pinctrl/pinctrl-samsung.c                  | 392 ++++++++++++++----
 drivers/pinctrl/pinctrl-samsung.h                  |  87 ++--
 8 files changed, 1205 insertions(+), 784 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi

-- 
1.7.12

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

* [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
@ 2012-10-08  8:39 ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series is a work on improving usability and extensibiltiy of the
pinctrl-samsung driver. It consists of three main parts:
 - moving SoC-specific data to device tree
 - converting the driver to use one GPIO chip and one IRQ domain per pin bank
 - introducing generic wake-up interrupt capability description

What the first part does is replacing static platform-specific data in
pinctrl-samsung driver with data dynamically parsed from device tree.

It aims at reducing the SoC-specific part of the driver and thus the
amount of modifications to driver sources when adding support for next
SoCs (like Exynos4x12).

In addition, it extends the description of SoC-specific attributes to cover all
mainlined Samsung SoCs, starting from s3c24xx and ending on latest Exynos5
series, with the exception of 4-bit banks with more than 8 pins on S3C64xx,
which will be covered by futher patch(es).

The second part attempts to simplify usage of the driver and fix several
problems of current implementation, in particular:

  - Simplifies GPIO pin specification in device tree by using pin
    namespace local to pin bank instead of local to pin controller, e.g.

        gpios = <&gpj0 3 0>;

    instead of

        gpios = <&pinctrl0 115 0>;

  - Simplifies GPIO interrupt specification in device tree by using
    namespace local to pin bank (and equal to GPIO namespace), e.g.

        interrupt-parent = <&gpj0>;
        interrupts = <3 0>;

    instead of

        interrupt-parent = <&pinctrl0>;
        interrupts = <115 0>;

  - Simplifies internal GPIO pin to bank translation thanks to
    correspondence of particular GPIO chips to pin banks. This allows
    to remove the (costly in case of GPIO bit-banging drivers) lookup
    over all banks to find the one that the pin is from.

Third part is focused on removing the static, hard-coded description of wake-up
interrupt controller and wake-up interrupt layout.

It defines a (mostly) generic (in scope of targetted SoCs) wake-up interrupt
layout specification format that allows to specify which pin banks support
wake-up interrupts and how they are handled (direct or multiplexed/chained).

See particular patches for more detailed descriptions and the last patch for
updated device tree bindings.

Tomasz Figa (16):
  ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl
    bank nodes
  pinctrl: exynos: Parse wakeup-eint parameters from DT
  pinctrl: samsung: Detect and handle unsupported configuration types
  pinctrl: samsung: Parse pin banks from DT
  pinctrl: exynos: Remove static SoC-specific data
  pinctrl: samsung: Parse bank-specific eint offset from DT
  pinctrl: samsung: Hold OF node of pin bank in bank struct
  pinctrl: samsung: Hold pointer to driver data in bank struct
  pinctrl: exynos: Use one IRQ domain per pin bank
  pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
  pinctrl: samsung: Use one GPIO chip per pin bank
  pinctrl: samsung: Use per-bank IRQ domain for wake-up interrupts
  pinctrl: exynos: Set pin function to EINT in irq_set_type of wake-up
    EINT
  pinctrl: samsung: Parse offsets of particular registers from DT
  pinctrl: samsung: Add GPIO to IRQ translation
  Documentation: Update samsung-pinctrl device tree bindings
    documentation

 .../bindings/pinctrl/samsung-pinctrl.txt           | 212 ++++++++--
 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi    | 459 +++++++++++++++++++++
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi          |   2 +
 arch/arm/boot/dts/exynos4210.dtsi                  | 254 +-----------
 drivers/pinctrl/pinctrl-exynos.c                   | 399 ++++++++----------
 drivers/pinctrl/pinctrl-exynos.h                   | 184 +--------
 drivers/pinctrl/pinctrl-samsung.c                  | 392 ++++++++++++++----
 drivers/pinctrl/pinctrl-samsung.h                  |  87 ++--
 8 files changed, 1205 insertions(+), 784 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi

-- 
1.7.12

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

Seuqential patches from this series introduce SoC-specific data parsing
from device tree.

This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
replaces them with nodes and properties required for these patches.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi | 459 ++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi       |   2 +
 arch/arm/boot/dts/exynos4210.dtsi               | 254 +------------
 3 files changed, 474 insertions(+), 241 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi

diff --git a/arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi
new file mode 100644
index 0000000..ec91f40
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi
@@ -0,0 +1,459 @@
+/*
+ * Samsung's Exynos4210 SoC pinctrl banks device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos4210 SoC pin banks are listed as device tree nodes
+ * in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+	pinctrl-bank-types {
+		bank_off: bank-off {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv", "conpdn", "pudpdn";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>, <0x10 2>, <0x14 2>;
+		};
+
+		bank_alive: bank-alive {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>;
+		};
+	};
+
+	pinctrl@11400000 {
+		gpa0: gpa0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		gpa1: gpa1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x020>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x04>;
+			#interrupt-cells = <2>;
+		};
+
+		gpb: gpb {
+			gpio-controller;
+			samsung,pctl-offset = <0x040>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		gpc0: gpc0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x060>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x0C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpc1: gpc1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x080>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x10>;
+			#interrupt-cells = <2>;
+		};
+
+		gpd0: gpd0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0A0>;
+			samsung,pin-count = <4>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x14>;
+			#interrupt-cells = <2>;
+		};
+
+		gpd1: gpd1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0C0>;
+			samsung,pin-count = <4>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x18>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe0: gpe0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0E0>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x1C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe1: gpe1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x100>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x20>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe2: gpe2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x120>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x24>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe3: gpe3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x140>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x28>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe4: gpe4 {
+			gpio-controller;
+			samsung,pctl-offset = <0x160>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x2C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf0: gpf0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x180>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x30>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf1: gpf1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1A0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x34>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf2: gpf2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1C0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x38>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf3: gpf3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1E0>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x3C>;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pinctrl@11000000 {
+		gpj0: gpj0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		gpj1: gpj1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x020>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x04>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk0: gpk0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x040>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk1: gpk1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x060>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x0C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk2: gpk2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x080>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x10>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk3: gpk3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0A0>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x14>;
+			#interrupt-cells = <2>;
+		};
+
+		gpl0: gpl0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0C0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x18>;
+			#interrupt-cells = <2>;
+		};
+
+		gpl1: gpl1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0E0>;
+			samsung,pin-count = <3>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x1C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpl2: gpl2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x100>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x20>;
+			#interrupt-cells = <2>;
+		};
+
+		gpy0: gpy0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x120>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy1: gpy1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x140>;
+			samsung,pin-count = <4>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy2: gpy2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x160>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy3: gpy3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x180>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy4: gpy4 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1A0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy5: gpy5 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1C0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy6: gpy6 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1E0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpx0: gpx0 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC00>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx1: gpx1 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC20>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			interrupt-parent = <&gic>;
+			interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+				     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+			samsung,eint-offset = <0x04>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx2: gpx2 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC40>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx3: gpx3 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC60>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			samsung,eint-offset = <0x0C>;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pinctrl@03860000 {
+		gpz: gpz {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index b12cf27..94846d5 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -14,6 +14,8 @@
  * published by the Free Software Foundation.
 */
 
+/include/ "exynos4210-pinctrl-banks.dtsi"
+
 / {
 	pinctrl@11400000 {
 		uart0_data: uart0-data {
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 214c557..7f32a51 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -46,27 +46,28 @@
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11400000 0x1000>;
 		interrupts = <0 47 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
 	};
 
 	pinctrl_1: pinctrl@11000000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11000000 0x1000>;
 		interrupts = <0 46 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
 
-		wakup_eint: wakeup-interrupt-controller {
+		wakeup-interrupt-controller {
 			compatible = "samsung,exynos4210-wakeup-eint";
 			interrupt-parent = <&gic>;
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
-				     <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
-				     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>,
-				     <0 32 0>;
+			interrupts = <0 32 0>;
+			samsung,weint-con = <0xE00>;
+			samsung,weint-mask = <0xF00>;
+			samsung,weint-pend = <0xF40>;
 		};
 	};
 
@@ -74,233 +75,4 @@
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x03860000 0x1000>;
 	};
-
-	gpio-controllers {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		gpio-controller;
-		ranges;
-
-		gpa0: gpio-controller@11400000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400000 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpa1: gpio-controller@11400020 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400020 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpb: gpio-controller@11400040 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400040 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpc0: gpio-controller@11400060 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400060 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpc1: gpio-controller@11400080 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400080 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpd0: gpio-controller@114000A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpd1: gpio-controller@114000C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe0: gpio-controller@114000E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe1: gpio-controller@11400100 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400100 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe2: gpio-controller@11400120 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400120 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe3: gpio-controller@11400140 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400140 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe4: gpio-controller@11400160 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400160 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf0: gpio-controller@11400180 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400180 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf1: gpio-controller@114001A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf2: gpio-controller@114001C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf3: gpio-controller@114001E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpj0: gpio-controller@11000000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000000 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpj1: gpio-controller@11000020 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000020 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk0: gpio-controller@11000040 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000040 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk1: gpio-controller@11000060 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000060 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk2: gpio-controller@11000080 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000080 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk3: gpio-controller@110000A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl0: gpio-controller@110000C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl1: gpio-controller@110000E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl2: gpio-controller@11000100 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000100 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy0: gpio-controller@11000120 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000120 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy1: gpio-controller@11000140 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000140 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy2: gpio-controller@11000160 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000160 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy3: gpio-controller@11000180 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000180 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy4: gpio-controller@110001A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy5: gpio-controller@110001C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy6: gpio-controller@110001E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx0: gpio-controller@11000C00 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C00 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx1: gpio-controller@11000C20 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C20 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx2: gpio-controller@11000C40 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C40 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx3: gpio-controller@11000C60 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C60 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpz: gpio-controller@03860000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x03860000 0x20>;
-			#gpio-cells = <4>;
-		};
-	};
 };
-- 
1.7.12

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Seuqential patches from this series introduce SoC-specific data parsing
from device tree.

This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
replaces them with nodes and properties required for these patches.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi | 459 ++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi       |   2 +
 arch/arm/boot/dts/exynos4210.dtsi               | 254 +------------
 3 files changed, 474 insertions(+), 241 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi

diff --git a/arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi
new file mode 100644
index 0000000..ec91f40
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-pinctrl-banks.dtsi
@@ -0,0 +1,459 @@
+/*
+ * Samsung's Exynos4210 SoC pinctrl banks device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos4210 SoC pin banks are listed as device tree nodes
+ * in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+	pinctrl-bank-types {
+		bank_off: bank-off {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv", "conpdn", "pudpdn";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>, <0x10 2>, <0x14 2>;
+		};
+
+		bank_alive: bank-alive {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>;
+		};
+	};
+
+	pinctrl at 11400000 {
+		gpa0: gpa0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		gpa1: gpa1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x020>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x04>;
+			#interrupt-cells = <2>;
+		};
+
+		gpb: gpb {
+			gpio-controller;
+			samsung,pctl-offset = <0x040>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		gpc0: gpc0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x060>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x0C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpc1: gpc1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x080>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x10>;
+			#interrupt-cells = <2>;
+		};
+
+		gpd0: gpd0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0A0>;
+			samsung,pin-count = <4>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x14>;
+			#interrupt-cells = <2>;
+		};
+
+		gpd1: gpd1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0C0>;
+			samsung,pin-count = <4>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x18>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe0: gpe0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0E0>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x1C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe1: gpe1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x100>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x20>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe2: gpe2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x120>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x24>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe3: gpe3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x140>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x28>;
+			#interrupt-cells = <2>;
+		};
+
+		gpe4: gpe4 {
+			gpio-controller;
+			samsung,pctl-offset = <0x160>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x2C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf0: gpf0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x180>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x30>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf1: gpf1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1A0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x34>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf2: gpf2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1C0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x38>;
+			#interrupt-cells = <2>;
+		};
+
+		gpf3: gpf3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1E0>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x3C>;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pinctrl at 11000000 {
+		gpj0: gpj0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		gpj1: gpj1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x020>;
+			samsung,pin-count = <5>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x04>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk0: gpk0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x040>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk1: gpk1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x060>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x0C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk2: gpk2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x080>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x10>;
+			#interrupt-cells = <2>;
+		};
+
+		gpk3: gpk3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0A0>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x14>;
+			#interrupt-cells = <2>;
+		};
+
+		gpl0: gpl0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0C0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x18>;
+			#interrupt-cells = <2>;
+		};
+
+		gpl1: gpl1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x0E0>;
+			samsung,pin-count = <3>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x1C>;
+			#interrupt-cells = <2>;
+		};
+
+		gpl2: gpl2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x100>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x20>;
+			#interrupt-cells = <2>;
+		};
+
+		gpy0: gpy0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x120>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy1: gpy1 {
+			gpio-controller;
+			samsung,pctl-offset = <0x140>;
+			samsung,pin-count = <4>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy2: gpy2 {
+			gpio-controller;
+			samsung,pctl-offset = <0x160>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy3: gpy3 {
+			gpio-controller;
+			samsung,pctl-offset = <0x180>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy4: gpy4 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1A0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy5: gpy5 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1C0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpy6: gpy6 {
+			gpio-controller;
+			samsung,pctl-offset = <0x1E0>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		gpx0: gpx0 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC00>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx1: gpx1 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC20>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			interrupt-parent = <&gic>;
+			interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+				     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+			samsung,eint-offset = <0x04>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx2: gpx2 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC40>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx3: gpx3 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC60>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			samsung,eint-offset = <0x0C>;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pinctrl at 03860000 {
+		gpz: gpz {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <7>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index b12cf27..94846d5 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -14,6 +14,8 @@
  * published by the Free Software Foundation.
 */
 
+/include/ "exynos4210-pinctrl-banks.dtsi"
+
 / {
 	pinctrl at 11400000 {
 		uart0_data: uart0-data {
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 214c557..7f32a51 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -46,27 +46,28 @@
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11400000 0x1000>;
 		interrupts = <0 47 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
 	};
 
 	pinctrl_1: pinctrl at 11000000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11000000 0x1000>;
 		interrupts = <0 46 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
 
-		wakup_eint: wakeup-interrupt-controller {
+		wakeup-interrupt-controller {
 			compatible = "samsung,exynos4210-wakeup-eint";
 			interrupt-parent = <&gic>;
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
-				     <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
-				     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>,
-				     <0 32 0>;
+			interrupts = <0 32 0>;
+			samsung,weint-con = <0xE00>;
+			samsung,weint-mask = <0xF00>;
+			samsung,weint-pend = <0xF40>;
 		};
 	};
 
@@ -74,233 +75,4 @@
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x03860000 0x1000>;
 	};
-
-	gpio-controllers {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		gpio-controller;
-		ranges;
-
-		gpa0: gpio-controller at 11400000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400000 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpa1: gpio-controller at 11400020 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400020 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpb: gpio-controller at 11400040 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400040 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpc0: gpio-controller at 11400060 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400060 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpc1: gpio-controller at 11400080 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400080 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpd0: gpio-controller at 114000A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpd1: gpio-controller at 114000C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe0: gpio-controller at 114000E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe1: gpio-controller at 11400100 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400100 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe2: gpio-controller at 11400120 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400120 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe3: gpio-controller at 11400140 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400140 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe4: gpio-controller at 11400160 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400160 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf0: gpio-controller at 11400180 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400180 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf1: gpio-controller at 114001A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf2: gpio-controller at 114001C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf3: gpio-controller at 114001E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpj0: gpio-controller at 11000000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000000 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpj1: gpio-controller at 11000020 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000020 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk0: gpio-controller at 11000040 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000040 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk1: gpio-controller at 11000060 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000060 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk2: gpio-controller at 11000080 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000080 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk3: gpio-controller at 110000A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl0: gpio-controller at 110000C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl1: gpio-controller at 110000E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl2: gpio-controller at 11000100 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000100 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy0: gpio-controller at 11000120 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000120 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy1: gpio-controller at 11000140 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000140 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy2: gpio-controller at 11000160 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000160 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy3: gpio-controller at 11000180 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000180 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy4: gpio-controller at 110001A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy5: gpio-controller at 110001C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy6: gpio-controller at 110001E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx0: gpio-controller at 11000C00 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C00 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx1: gpio-controller at 11000C20 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C20 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx2: gpio-controller at 11000C40 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C40 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx3: gpio-controller at 11000C60 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C60 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpz: gpio-controller at 03860000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x03860000 0x20>;
-			#gpio-cells = <4>;
-		};
-	};
 };
-- 
1.7.12

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

* [PATCH 02/16] pinctrl: exynos: Parse wakeup-eint parameters from DT
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

This patch converts the pinctrl-exynos driver to parse wakeup interrupt
count and register offsets from device tree. It reduces the amount of
static platform-specific data and facilitates adding further SoC
variants to pinctrl-samsung driver.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 21362f4..b4b58d4 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -435,6 +435,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	struct device_node *np;
 	struct exynos_weint_data *weint_data;
 	int idx, irq;
+	u32 val;
+	int ret;
 
 	for_each_child_of_node(dev->of_node, np) {
 		if (of_match_node(exynos_wkup_irq_ids, np)) {
@@ -445,6 +447,26 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	if (!wkup_np)
 		return -ENODEV;
 
+	ret = of_property_read_u32(wkup_np, "samsung,weint-count", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->nr_wint = val;
+
+	ret = of_property_read_u32(wkup_np, "samsung,weint-con", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->weint_con = val;
+
+	ret = of_property_read_u32(wkup_np, "samsung,weint-mask", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->weint_mask = val;
+
+	ret = of_property_read_u32(wkup_np, "samsung,weint-pend", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->weint_pend = val;
+
 	d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint,
 				&exynos_wkup_irqd_ops, d);
 	if (!d->wkup_irqd) {
-- 
1.7.12

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

* [PATCH 02/16] pinctrl: exynos: Parse wakeup-eint parameters from DT
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

This patch converts the pinctrl-exynos driver to parse wakeup interrupt
count and register offsets from device tree. It reduces the amount of
static platform-specific data and facilitates adding further SoC
variants to pinctrl-samsung driver.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 21362f4..b4b58d4 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -435,6 +435,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	struct device_node *np;
 	struct exynos_weint_data *weint_data;
 	int idx, irq;
+	u32 val;
+	int ret;
 
 	for_each_child_of_node(dev->of_node, np) {
 		if (of_match_node(exynos_wkup_irq_ids, np)) {
@@ -445,6 +447,26 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	if (!wkup_np)
 		return -ENODEV;
 
+	ret = of_property_read_u32(wkup_np, "samsung,weint-count", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->nr_wint = val;
+
+	ret = of_property_read_u32(wkup_np, "samsung,weint-con", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->weint_con = val;
+
+	ret = of_property_read_u32(wkup_np, "samsung,weint-mask", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->weint_mask = val;
+
+	ret = of_property_read_u32(wkup_np, "samsung,weint-pend", &val);
+	if (ret)
+		return -EINVAL;
+	d->ctrl->weint_pend = val;
+
 	d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint,
 				&exynos_wkup_irqd_ops, d);
 	if (!d->wkup_irqd) {
-- 
1.7.12

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

* [PATCH 03/16] pinctrl: samsung: Detect and handle unsupported configuration types
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

This patch modifies the pinctrl-samsung driver to detect when width of a
bit field is set to zero (which means that such configuraton type is not
supported) and return an error instead of trying to modify an inexistent
register.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index dd108a9..c660fa5 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -391,6 +391,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 		return -EINVAL;
 	}
 
+	if (!width)
+		return -EINVAL;
+
 	mask = (1 << width) - 1;
 	shift = pin_offset * width;
 	data = readl(reg_base + cfg_reg);
-- 
1.7.12

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

* [PATCH 03/16] pinctrl: samsung: Detect and handle unsupported configuration types
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modifies the pinctrl-samsung driver to detect when width of a
bit field is set to zero (which means that such configuraton type is not
supported) and return an error instead of trying to modify an inexistent
register.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index dd108a9..c660fa5 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -391,6 +391,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 		return -EINVAL;
 	}
 
+	if (!width)
+		return -EINVAL;
+
 	mask = (1 << width) - 1;
 	shift = pin_offset * width;
 	data = readl(reg_base + cfg_reg);
-- 
1.7.12

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

* [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

Currently SoC-specific properties such as list of pin banks, register
offsets and bitfield sizes are being taken from static data structures
residing in pinctrl-exynos.c.

This patch modifies the pinctrl-samsung driver to parse all SoC-specific
data from device tree, which will allow to remove the static data
structures and facilitate adding of further SoC variants to the
pinctrl-samsung driver.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  |   5 ++
 drivers/pinctrl/pinctrl-samsung.c | 169 +++++++++++++++++++++++++++++++++++++-
 drivers/pinctrl/pinctrl-samsung.h |  17 +++-
 3 files changed, 187 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index b4b58d4..e3fa263 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -599,3 +599,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
 		.label		= "exynos4210-gpio-ctrl2",
 	},
 };
+
+struct samsung_pin_ctrl_variant exynos4_pin_ctrl = {
+	.eint_gpio_init = exynos_eint_gpio_init,
+	.eint_wkup_init = exynos_eint_wkup_init,
+};
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index c660fa5..e828a0e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -46,6 +46,8 @@ struct pin_config {
 	{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
 };
 
+static unsigned int pin_base = 0;
+
 /* check if the selector is a valid pin group selector */
 static int samsung_get_group_count(struct pinctrl_dev *pctldev)
 {
@@ -602,6 +604,8 @@ static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
 		u32 function;
 		if (of_find_property(cfg_np, "interrupt-controller", NULL))
 			continue;
+		if (of_find_property(cfg_np, "gpio-controller", NULL))
+			continue;
 
 		ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
 					&drvdata->pctl,	&pin_list, &npins);
@@ -778,6 +782,86 @@ static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
 
 static const struct of_device_id samsung_pinctrl_dt_match[];
 
+static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
+							struct device_node *np)
+{
+	struct samsung_pin_bank *type = np->data;
+	int ret;
+	u32 val;
+
+	if (type) {
+		*bank = *type;
+		return 0;
+	}
+
+	type = kzalloc(sizeof(*type), GFP_KERNEL);
+	if (!type)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(np, "samsung,func-width", &val);
+	if (ret)
+		return ret;
+	type->func_width = val;
+
+	ret = of_property_read_u32(np, "samsung,pud-width", &val);
+	if (!ret)
+		type->pud_width = val;
+
+	ret = of_property_read_u32(np, "samsung,drv-width", &val);
+	if (!ret)
+		type->drv_width = val;
+
+	ret = of_property_read_u32(np, "samsung,conpdn-width", &val);
+	if (!ret)
+		type->conpdn_width = val;
+
+	ret = of_property_read_u32(np, "samsung,pudpdn-width", &val);
+	if (!ret)
+		type->pudpdn_width = val;
+
+	*bank = *type;
+	np->data = type;
+
+	return 0;
+}
+
+static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
+							struct device_node *np)
+{
+	int ret;
+	u32 val;
+	struct device_node *type_np;
+
+	type_np = of_parse_phandle(np, "samsung,bank-type", 0);
+	if (!type_np)
+		return -EINVAL;
+
+	ret = samsung_pinctrl_parse_dt_bank_type(bank, type_np);
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32(np, "samsung,pctl-offset", &val);
+	if (ret)
+		return ret;
+	bank->pctl_offset = val;
+
+	ret = of_property_read_u32(np, "samsung,pin-count", &val);
+	if (ret)
+		return ret;
+	bank->nr_pins = val;
+
+	bank->name = np->name;
+
+	if (!of_find_property(np, "interrupt-controller", NULL)) {
+		bank->eint_type = EINT_TYPE_NONE;
+		return 0;
+	}
+
+	bank->eint_type = EINT_TYPE_GPIO;
+
+	return 0;
+}
+
 /* retrieve the soc specific data */
 static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 				struct platform_device *pdev)
@@ -785,6 +869,14 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 	int id;
 	const struct of_device_id *match;
 	const struct device_node *node = pdev->dev.of_node;
+	struct device_node *bank_np;
+	struct samsung_pin_ctrl *ctrl;
+	struct samsung_pin_bank *banks, *b;
+	struct samsung_pin_ctrl_variant *variant;
+	unsigned int bank_cnt = 0;
+	unsigned int eint_cnt = 0;
+	u32 val;
+	int ret;
 
 	id = of_alias_get_id(pdev->dev.of_node, "pinctrl");
 	if (id < 0) {
@@ -792,7 +884,80 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 		return NULL;
 	}
 	match = of_match_node(samsung_pinctrl_dt_match, node);
-	return (struct samsung_pin_ctrl *)match->data + id;
+	variant = match->data;
+
+	for_each_child_of_node(node, bank_np) {
+		if (!of_find_property(bank_np, "gpio-controller", NULL))
+			continue;
+		++bank_cnt;
+	}
+
+	if (!bank_cnt) {
+		dev_err(&pdev->dev, "no pin banks specified\n");
+		return NULL;
+	}
+
+	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "failed to allocate soc data\n");
+		return NULL;
+	}
+
+	banks = devm_kzalloc(&pdev->dev,
+			bank_cnt * sizeof(*ctrl->pin_banks), GFP_KERNEL);
+	if (!banks) {
+		dev_err(&pdev->dev, "failed to allocate pin banks\n");
+		return NULL;
+	}
+
+	b = banks;
+	for_each_child_of_node(node, bank_np) {
+		if (!of_find_property(bank_np, "gpio-controller", NULL))
+			continue;
+		if (samsung_pinctrl_parse_dt_bank(b, bank_np))
+			return NULL;
+		b->pin_base = ctrl->nr_pins;
+		ctrl->nr_pins += b->nr_pins;
+		if (b->eint_type == EINT_TYPE_GPIO) {
+			b->irq_base = eint_cnt;
+			eint_cnt += b->nr_pins;
+		}
+		++b;
+	}
+
+	if (eint_cnt) {
+		ret = of_property_read_u32(node, "samsung,geint-con", &val);
+		if (ret)
+			return NULL;
+		ctrl->geint_con = val;
+
+		ret = of_property_read_u32(node, "samsung,geint-mask", &val);
+		if (ret)
+			return NULL;
+		ctrl->geint_mask = val;
+
+		ret = of_property_read_u32(node, "samsung,geint-pend", &val);
+		if (ret)
+			return NULL;
+		ctrl->geint_pend = val;
+
+		ret = of_property_read_u32(node, "samsung,svc", &val);
+		if (ret)
+			return NULL;
+		ctrl->svc = val;
+
+		ctrl->eint_gpio_init = variant->eint_gpio_init;
+	}
+
+	ctrl->pin_banks = banks;
+	ctrl->nr_banks = bank_cnt;
+	ctrl->nr_gint = eint_cnt;
+	ctrl->label = node->name;
+	ctrl->eint_wkup_init = variant->eint_wkup_init;
+	ctrl->base = pin_base;
+	pin_base += ctrl->nr_pins;
+
+	return ctrl;
 }
 
 static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
@@ -860,7 +1025,7 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
 
 static const struct of_device_id samsung_pinctrl_dt_match[] = {
 	{ .compatible = "samsung,pinctrl-exynos4210",
-		.data = (void *)exynos4210_pin_ctrl },
+		.data = &exynos4_pin_ctrl },
 	{},
 };
 MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index b895693..5d59ce6 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -123,7 +123,19 @@ struct samsung_pin_bank {
 	u8		pudpdn_width;
 	enum eint_type	eint_type;
 	u32		irq_base;
-	char		*name;
+	const char	*name;
+};
+
+/**
+ * struct samsung_pin_ctrl_variant: represents a pin controller variant.
+ * @eint_gpio_init: platform specific callback to setup the external gpio
+ *	interrupts for the controller.
+ * @eint_wkup_init: platform specific callback to setup the external wakeup
+ *	interrupts for the controller.
+ */
+struct samsung_pin_ctrl_variant {
+	int		(*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
+	int		(*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
 };
 
 /**
@@ -168,7 +180,7 @@ struct samsung_pin_ctrl {
 
 	int		(*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
 	int		(*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
-	char		*label;
+	const char	*label;
 };
 
 /**
@@ -235,5 +247,6 @@ struct samsung_pmx_func {
 
 /* list of all exported SoC specific data */
 extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
+extern struct samsung_pin_ctrl_variant exynos4_pin_ctrl;
 
 #endif /* __PINCTRL_SAMSUNG_H */
-- 
1.7.12

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

* [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Currently SoC-specific properties such as list of pin banks, register
offsets and bitfield sizes are being taken from static data structures
residing in pinctrl-exynos.c.

This patch modifies the pinctrl-samsung driver to parse all SoC-specific
data from device tree, which will allow to remove the static data
structures and facilitate adding of further SoC variants to the
pinctrl-samsung driver.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  |   5 ++
 drivers/pinctrl/pinctrl-samsung.c | 169 +++++++++++++++++++++++++++++++++++++-
 drivers/pinctrl/pinctrl-samsung.h |  17 +++-
 3 files changed, 187 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index b4b58d4..e3fa263 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -599,3 +599,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
 		.label		= "exynos4210-gpio-ctrl2",
 	},
 };
+
+struct samsung_pin_ctrl_variant exynos4_pin_ctrl = {
+	.eint_gpio_init = exynos_eint_gpio_init,
+	.eint_wkup_init = exynos_eint_wkup_init,
+};
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index c660fa5..e828a0e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -46,6 +46,8 @@ struct pin_config {
 	{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
 };
 
+static unsigned int pin_base = 0;
+
 /* check if the selector is a valid pin group selector */
 static int samsung_get_group_count(struct pinctrl_dev *pctldev)
 {
@@ -602,6 +604,8 @@ static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
 		u32 function;
 		if (of_find_property(cfg_np, "interrupt-controller", NULL))
 			continue;
+		if (of_find_property(cfg_np, "gpio-controller", NULL))
+			continue;
 
 		ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
 					&drvdata->pctl,	&pin_list, &npins);
@@ -778,6 +782,86 @@ static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
 
 static const struct of_device_id samsung_pinctrl_dt_match[];
 
+static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
+							struct device_node *np)
+{
+	struct samsung_pin_bank *type = np->data;
+	int ret;
+	u32 val;
+
+	if (type) {
+		*bank = *type;
+		return 0;
+	}
+
+	type = kzalloc(sizeof(*type), GFP_KERNEL);
+	if (!type)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(np, "samsung,func-width", &val);
+	if (ret)
+		return ret;
+	type->func_width = val;
+
+	ret = of_property_read_u32(np, "samsung,pud-width", &val);
+	if (!ret)
+		type->pud_width = val;
+
+	ret = of_property_read_u32(np, "samsung,drv-width", &val);
+	if (!ret)
+		type->drv_width = val;
+
+	ret = of_property_read_u32(np, "samsung,conpdn-width", &val);
+	if (!ret)
+		type->conpdn_width = val;
+
+	ret = of_property_read_u32(np, "samsung,pudpdn-width", &val);
+	if (!ret)
+		type->pudpdn_width = val;
+
+	*bank = *type;
+	np->data = type;
+
+	return 0;
+}
+
+static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
+							struct device_node *np)
+{
+	int ret;
+	u32 val;
+	struct device_node *type_np;
+
+	type_np = of_parse_phandle(np, "samsung,bank-type", 0);
+	if (!type_np)
+		return -EINVAL;
+
+	ret = samsung_pinctrl_parse_dt_bank_type(bank, type_np);
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32(np, "samsung,pctl-offset", &val);
+	if (ret)
+		return ret;
+	bank->pctl_offset = val;
+
+	ret = of_property_read_u32(np, "samsung,pin-count", &val);
+	if (ret)
+		return ret;
+	bank->nr_pins = val;
+
+	bank->name = np->name;
+
+	if (!of_find_property(np, "interrupt-controller", NULL)) {
+		bank->eint_type = EINT_TYPE_NONE;
+		return 0;
+	}
+
+	bank->eint_type = EINT_TYPE_GPIO;
+
+	return 0;
+}
+
 /* retrieve the soc specific data */
 static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 				struct platform_device *pdev)
@@ -785,6 +869,14 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 	int id;
 	const struct of_device_id *match;
 	const struct device_node *node = pdev->dev.of_node;
+	struct device_node *bank_np;
+	struct samsung_pin_ctrl *ctrl;
+	struct samsung_pin_bank *banks, *b;
+	struct samsung_pin_ctrl_variant *variant;
+	unsigned int bank_cnt = 0;
+	unsigned int eint_cnt = 0;
+	u32 val;
+	int ret;
 
 	id = of_alias_get_id(pdev->dev.of_node, "pinctrl");
 	if (id < 0) {
@@ -792,7 +884,80 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 		return NULL;
 	}
 	match = of_match_node(samsung_pinctrl_dt_match, node);
-	return (struct samsung_pin_ctrl *)match->data + id;
+	variant = match->data;
+
+	for_each_child_of_node(node, bank_np) {
+		if (!of_find_property(bank_np, "gpio-controller", NULL))
+			continue;
+		++bank_cnt;
+	}
+
+	if (!bank_cnt) {
+		dev_err(&pdev->dev, "no pin banks specified\n");
+		return NULL;
+	}
+
+	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "failed to allocate soc data\n");
+		return NULL;
+	}
+
+	banks = devm_kzalloc(&pdev->dev,
+			bank_cnt * sizeof(*ctrl->pin_banks), GFP_KERNEL);
+	if (!banks) {
+		dev_err(&pdev->dev, "failed to allocate pin banks\n");
+		return NULL;
+	}
+
+	b = banks;
+	for_each_child_of_node(node, bank_np) {
+		if (!of_find_property(bank_np, "gpio-controller", NULL))
+			continue;
+		if (samsung_pinctrl_parse_dt_bank(b, bank_np))
+			return NULL;
+		b->pin_base = ctrl->nr_pins;
+		ctrl->nr_pins += b->nr_pins;
+		if (b->eint_type == EINT_TYPE_GPIO) {
+			b->irq_base = eint_cnt;
+			eint_cnt += b->nr_pins;
+		}
+		++b;
+	}
+
+	if (eint_cnt) {
+		ret = of_property_read_u32(node, "samsung,geint-con", &val);
+		if (ret)
+			return NULL;
+		ctrl->geint_con = val;
+
+		ret = of_property_read_u32(node, "samsung,geint-mask", &val);
+		if (ret)
+			return NULL;
+		ctrl->geint_mask = val;
+
+		ret = of_property_read_u32(node, "samsung,geint-pend", &val);
+		if (ret)
+			return NULL;
+		ctrl->geint_pend = val;
+
+		ret = of_property_read_u32(node, "samsung,svc", &val);
+		if (ret)
+			return NULL;
+		ctrl->svc = val;
+
+		ctrl->eint_gpio_init = variant->eint_gpio_init;
+	}
+
+	ctrl->pin_banks = banks;
+	ctrl->nr_banks = bank_cnt;
+	ctrl->nr_gint = eint_cnt;
+	ctrl->label = node->name;
+	ctrl->eint_wkup_init = variant->eint_wkup_init;
+	ctrl->base = pin_base;
+	pin_base += ctrl->nr_pins;
+
+	return ctrl;
 }
 
 static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
@@ -860,7 +1025,7 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
 
 static const struct of_device_id samsung_pinctrl_dt_match[] = {
 	{ .compatible = "samsung,pinctrl-exynos4210",
-		.data = (void *)exynos4210_pin_ctrl },
+		.data = &exynos4_pin_ctrl },
 	{},
 };
 MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index b895693..5d59ce6 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -123,7 +123,19 @@ struct samsung_pin_bank {
 	u8		pudpdn_width;
 	enum eint_type	eint_type;
 	u32		irq_base;
-	char		*name;
+	const char	*name;
+};
+
+/**
+ * struct samsung_pin_ctrl_variant: represents a pin controller variant.
+ * @eint_gpio_init: platform specific callback to setup the external gpio
+ *	interrupts for the controller.
+ * @eint_wkup_init: platform specific callback to setup the external wakeup
+ *	interrupts for the controller.
+ */
+struct samsung_pin_ctrl_variant {
+	int		(*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
+	int		(*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
 };
 
 /**
@@ -168,7 +180,7 @@ struct samsung_pin_ctrl {
 
 	int		(*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
 	int		(*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
-	char		*label;
+	const char	*label;
 };
 
 /**
@@ -235,5 +247,6 @@ struct samsung_pmx_func {
 
 /* list of all exported SoC specific data */
 extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
+extern struct samsung_pin_ctrl_variant exynos4_pin_ctrl;
 
 #endif /* __PINCTRL_SAMSUNG_H */
-- 
1.7.12

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

* [PATCH 05/16] pinctrl: exynos: Remove static SoC-specific data
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

The patch "pinctrl: samsung: Parse pin banks from DT" introduced parsing
SoC-specific data from device tree, so there is no need to keep the
previously used definitions in headers and source files.

This patch cleans up the pinctrl-exynos driver from unused
SoC-specific data.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  |  96 -----------------------
 drivers/pinctrl/pinctrl-exynos.h  | 157 --------------------------------------
 drivers/pinctrl/pinctrl-samsung.h |   1 -
 3 files changed, 254 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index e3fa263..134fecf 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -504,102 +504,6 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	return 0;
 }
 
-/* pin banks of exynos4210 pin-controller 0 */
-static struct samsung_pin_bank exynos4210_pin_banks0[] = {
-	EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_A0, "gpa0"),
-	EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_A1, "gpa1"),
-	EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_B, "gpb"),
-	EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_C0, "gpc0"),
-	EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_C1, "gpc1"),
-	EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_D0, "gpd0"),
-	EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_D1, "gpd1"),
-	EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_E0, "gpe0"),
-	EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_E1, "gpe1"),
-	EXYNOS_PIN_BANK_EINTG(0x120, EXYNOS4210_GPIO_E2, "gpe2"),
-	EXYNOS_PIN_BANK_EINTG(0x140, EXYNOS4210_GPIO_E3, "gpe3"),
-	EXYNOS_PIN_BANK_EINTG(0x160, EXYNOS4210_GPIO_E4, "gpe4"),
-	EXYNOS_PIN_BANK_EINTG(0x180, EXYNOS4210_GPIO_F0, "gpf0"),
-	EXYNOS_PIN_BANK_EINTG(0x1A0, EXYNOS4210_GPIO_F1, "gpf1"),
-	EXYNOS_PIN_BANK_EINTG(0x1C0, EXYNOS4210_GPIO_F2, "gpf2"),
-	EXYNOS_PIN_BANK_EINTG(0x1E0, EXYNOS4210_GPIO_F3, "gpf3"),
-};
-
-/* pin banks of exynos4210 pin-controller 1 */
-static struct samsung_pin_bank exynos4210_pin_banks1[] = {
-	EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_J0, "gpj0"),
-	EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_J1, "gpj1"),
-	EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_K0, "gpk0"),
-	EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_K1, "gpk1"),
-	EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_K2, "gpk2"),
-	EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_K3, "gpk3"),
-	EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_L0, "gpl0"),
-	EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_L1, "gpl1"),
-	EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_L2, "gpl2"),
-	EXYNOS_PIN_BANK_EINTN(0x120, EXYNOS4210_GPIO_Y0, "gpy0"),
-	EXYNOS_PIN_BANK_EINTN(0x140, EXYNOS4210_GPIO_Y1, "gpy1"),
-	EXYNOS_PIN_BANK_EINTN(0x160, EXYNOS4210_GPIO_Y2, "gpy2"),
-	EXYNOS_PIN_BANK_EINTN(0x180, EXYNOS4210_GPIO_Y3, "gpy3"),
-	EXYNOS_PIN_BANK_EINTN(0x1A0, EXYNOS4210_GPIO_Y4, "gpy4"),
-	EXYNOS_PIN_BANK_EINTN(0x1C0, EXYNOS4210_GPIO_Y5, "gpy5"),
-	EXYNOS_PIN_BANK_EINTN(0x1E0, EXYNOS4210_GPIO_Y6, "gpy6"),
-	EXYNOS_PIN_BANK_EINTN(0xC00, EXYNOS4210_GPIO_X0, "gpx0"),
-	EXYNOS_PIN_BANK_EINTN(0xC20, EXYNOS4210_GPIO_X1, "gpx1"),
-	EXYNOS_PIN_BANK_EINTN(0xC40, EXYNOS4210_GPIO_X2, "gpx2"),
-	EXYNOS_PIN_BANK_EINTN(0xC60, EXYNOS4210_GPIO_X3, "gpx3"),
-};
-
-/* pin banks of exynos4210 pin-controller 2 */
-static struct samsung_pin_bank exynos4210_pin_banks2[] = {
-	EXYNOS_PIN_BANK_EINTN(0x000, EXYNOS4210_GPIO_Z, "gpz"),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
- * three gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
-	{
-		/* pin-controller instance 0 data */
-		.pin_banks	= exynos4210_pin_banks0,
-		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks0),
-		.base		= EXYNOS4210_GPIO_A0_START,
-		.nr_pins	= EXYNOS4210_GPIOA_NR_PINS,
-		.nr_gint	= EXYNOS4210_GPIOA_NR_GINT,
-		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
-		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
-		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
-		.svc		= EXYNOS_SVC_OFFSET,
-		.eint_gpio_init = exynos_eint_gpio_init,
-		.label		= "exynos4210-gpio-ctrl0",
-	}, {
-		/* pin-controller instance 1 data */
-		.pin_banks	= exynos4210_pin_banks1,
-		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks1),
-		.base		= EXYNOS4210_GPIOA_NR_PINS,
-		.nr_pins	= EXYNOS4210_GPIOB_NR_PINS,
-		.nr_gint	= EXYNOS4210_GPIOB_NR_GINT,
-		.nr_wint	= 32,
-		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
-		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
-		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
-		.weint_con	= EXYNOS_WKUP_ECON_OFFSET,
-		.weint_mask	= EXYNOS_WKUP_EMASK_OFFSET,
-		.weint_pend	= EXYNOS_WKUP_EPEND_OFFSET,
-		.svc		= EXYNOS_SVC_OFFSET,
-		.eint_gpio_init = exynos_eint_gpio_init,
-		.eint_wkup_init = exynos_eint_wkup_init,
-		.label		= "exynos4210-gpio-ctrl1",
-	}, {
-		/* pin-controller instance 2 data */
-		.pin_banks	= exynos4210_pin_banks2,
-		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks2),
-		.base		= EXYNOS4210_GPIOA_NR_PINS +
-					EXYNOS4210_GPIOB_NR_PINS,
-		.nr_pins	= EXYNOS4210_GPIOC_NR_PINS,
-		.label		= "exynos4210-gpio-ctrl2",
-	},
-};
-
 struct samsung_pin_ctrl_variant exynos4_pin_ctrl = {
 	.eint_gpio_init = exynos_eint_gpio_init,
 	.eint_wkup_init = exynos_eint_wkup_init,
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index 31d0a06..a72cfc7 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -17,133 +17,6 @@
  * (at your option) any later version.
  */
 
-#define EXYNOS_GPIO_START(__gpio)	((__gpio##_START) + (__gpio##_NR))
-
-#define EXYNOS4210_GPIO_A0_NR	(8)
-#define EXYNOS4210_GPIO_A1_NR	(6)
-#define EXYNOS4210_GPIO_B_NR	(8)
-#define EXYNOS4210_GPIO_C0_NR	(5)
-#define EXYNOS4210_GPIO_C1_NR	(5)
-#define EXYNOS4210_GPIO_D0_NR	(4)
-#define EXYNOS4210_GPIO_D1_NR	(4)
-#define EXYNOS4210_GPIO_E0_NR	(5)
-#define EXYNOS4210_GPIO_E1_NR	(8)
-#define EXYNOS4210_GPIO_E2_NR	(6)
-#define EXYNOS4210_GPIO_E3_NR	(8)
-#define EXYNOS4210_GPIO_E4_NR	(8)
-#define EXYNOS4210_GPIO_F0_NR	(8)
-#define EXYNOS4210_GPIO_F1_NR	(8)
-#define EXYNOS4210_GPIO_F2_NR	(8)
-#define EXYNOS4210_GPIO_F3_NR	(6)
-#define EXYNOS4210_GPIO_J0_NR	(8)
-#define EXYNOS4210_GPIO_J1_NR	(5)
-#define EXYNOS4210_GPIO_K0_NR	(7)
-#define EXYNOS4210_GPIO_K1_NR	(7)
-#define EXYNOS4210_GPIO_K2_NR	(7)
-#define EXYNOS4210_GPIO_K3_NR	(7)
-#define EXYNOS4210_GPIO_L0_NR	(8)
-#define EXYNOS4210_GPIO_L1_NR	(3)
-#define EXYNOS4210_GPIO_L2_NR	(8)
-#define EXYNOS4210_GPIO_Y0_NR	(6)
-#define EXYNOS4210_GPIO_Y1_NR	(4)
-#define EXYNOS4210_GPIO_Y2_NR	(6)
-#define EXYNOS4210_GPIO_Y3_NR	(8)
-#define EXYNOS4210_GPIO_Y4_NR	(8)
-#define EXYNOS4210_GPIO_Y5_NR	(8)
-#define EXYNOS4210_GPIO_Y6_NR	(8)
-#define EXYNOS4210_GPIO_X0_NR	(8)
-#define EXYNOS4210_GPIO_X1_NR	(8)
-#define EXYNOS4210_GPIO_X2_NR	(8)
-#define EXYNOS4210_GPIO_X3_NR	(8)
-#define EXYNOS4210_GPIO_Z_NR	(7)
-
-enum exynos4210_gpio_xa_start {
-	EXYNOS4210_GPIO_A0_START	= 0,
-	EXYNOS4210_GPIO_A1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_A0),
-	EXYNOS4210_GPIO_B_START		= EXYNOS_GPIO_START(EXYNOS4210_GPIO_A1),
-	EXYNOS4210_GPIO_C0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_B),
-	EXYNOS4210_GPIO_C1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_C0),
-	EXYNOS4210_GPIO_D0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_C1),
-	EXYNOS4210_GPIO_D1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_D0),
-	EXYNOS4210_GPIO_E0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_D1),
-	EXYNOS4210_GPIO_E1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E0),
-	EXYNOS4210_GPIO_E2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E1),
-	EXYNOS4210_GPIO_E3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E2),
-	EXYNOS4210_GPIO_E4_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E3),
-	EXYNOS4210_GPIO_F0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E4),
-	EXYNOS4210_GPIO_F1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F0),
-	EXYNOS4210_GPIO_F2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F1),
-	EXYNOS4210_GPIO_F3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F2),
-};
-
-enum exynos4210_gpio_xb_start {
-	EXYNOS4210_GPIO_J0_START	= 0,
-	EXYNOS4210_GPIO_J1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_J0),
-	EXYNOS4210_GPIO_K0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_J1),
-	EXYNOS4210_GPIO_K1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K0),
-	EXYNOS4210_GPIO_K2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K1),
-	EXYNOS4210_GPIO_K3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K2),
-	EXYNOS4210_GPIO_L0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K3),
-	EXYNOS4210_GPIO_L1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L0),
-	EXYNOS4210_GPIO_L2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L1),
-	EXYNOS4210_GPIO_Y0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2),
-	EXYNOS4210_GPIO_Y1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y0),
-	EXYNOS4210_GPIO_Y2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y1),
-	EXYNOS4210_GPIO_Y3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y2),
-	EXYNOS4210_GPIO_Y4_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y3),
-	EXYNOS4210_GPIO_Y5_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y4),
-	EXYNOS4210_GPIO_Y6_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y5),
-	EXYNOS4210_GPIO_X0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y6),
-	EXYNOS4210_GPIO_X1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X0),
-	EXYNOS4210_GPIO_X2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X1),
-	EXYNOS4210_GPIO_X3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X2),
-};
-
-enum exynos4210_gpio_xc_start {
-	EXYNOS4210_GPIO_Z_START		= 0,
-};
-
-#define	EXYNOS4210_GPIO_A0_IRQ		EXYNOS4210_GPIO_A0_START
-#define	EXYNOS4210_GPIO_A1_IRQ		EXYNOS4210_GPIO_A1_START
-#define	EXYNOS4210_GPIO_B_IRQ		EXYNOS4210_GPIO_B_START
-#define	EXYNOS4210_GPIO_C0_IRQ		EXYNOS4210_GPIO_C0_START
-#define	EXYNOS4210_GPIO_C1_IRQ		EXYNOS4210_GPIO_C1_START
-#define	EXYNOS4210_GPIO_D0_IRQ		EXYNOS4210_GPIO_D0_START
-#define	EXYNOS4210_GPIO_D1_IRQ		EXYNOS4210_GPIO_D1_START
-#define	EXYNOS4210_GPIO_E0_IRQ		EXYNOS4210_GPIO_E0_START
-#define	EXYNOS4210_GPIO_E1_IRQ		EXYNOS4210_GPIO_E1_START
-#define	EXYNOS4210_GPIO_E2_IRQ		EXYNOS4210_GPIO_E2_START
-#define	EXYNOS4210_GPIO_E3_IRQ		EXYNOS4210_GPIO_E3_START
-#define	EXYNOS4210_GPIO_E4_IRQ		EXYNOS4210_GPIO_E4_START
-#define	EXYNOS4210_GPIO_F0_IRQ		EXYNOS4210_GPIO_F0_START
-#define	EXYNOS4210_GPIO_F1_IRQ		EXYNOS4210_GPIO_F1_START
-#define	EXYNOS4210_GPIO_F2_IRQ		EXYNOS4210_GPIO_F2_START
-#define	EXYNOS4210_GPIO_F3_IRQ		EXYNOS4210_GPIO_F3_START
-#define	EXYNOS4210_GPIO_J0_IRQ		EXYNOS4210_GPIO_J0_START
-#define	EXYNOS4210_GPIO_J1_IRQ		EXYNOS4210_GPIO_J1_START
-#define	EXYNOS4210_GPIO_K0_IRQ		EXYNOS4210_GPIO_K0_START
-#define	EXYNOS4210_GPIO_K1_IRQ		EXYNOS4210_GPIO_K1_START
-#define	EXYNOS4210_GPIO_K2_IRQ		EXYNOS4210_GPIO_K2_START
-#define	EXYNOS4210_GPIO_K3_IRQ		EXYNOS4210_GPIO_K3_START
-#define	EXYNOS4210_GPIO_L0_IRQ		EXYNOS4210_GPIO_L0_START
-#define	EXYNOS4210_GPIO_L1_IRQ		EXYNOS4210_GPIO_L1_START
-#define	EXYNOS4210_GPIO_L2_IRQ		EXYNOS4210_GPIO_L2_START
-#define	EXYNOS4210_GPIO_Z_IRQ		EXYNOS4210_GPIO_Z_START
-
-#define EXYNOS4210_GPIOA_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3)
-#define EXYNOS4210_GPIOA_NR_GINT	EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3)
-#define EXYNOS4210_GPIOB_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_X3)
-#define EXYNOS4210_GPIOB_NR_GINT	EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2)
-#define EXYNOS4210_GPIOC_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_Z)
-
-/* External GPIO and wakeup interrupt related definitions */
-#define EXYNOS_GPIO_ECON_OFFSET		0x700
-#define EXYNOS_GPIO_EMASK_OFFSET	0x900
-#define EXYNOS_GPIO_EPEND_OFFSET	0xA00
-#define EXYNOS_WKUP_ECON_OFFSET		0xE00
-#define EXYNOS_WKUP_EMASK_OFFSET	0xF00
-#define EXYNOS_WKUP_EPEND_OFFSET	0xF40
-#define EXYNOS_SVC_OFFSET		0xB08
 #define EXYNOS_EINT_FUNC		0xF
 
 /* helpers to access interrupt service register */
@@ -163,36 +36,6 @@ enum exynos4210_gpio_xc_start {
 #define EXYNOS_EINT_CON_LEN		4
 
 #define EXYNOS_EINT_MAX_PER_BANK	8
-#define EXYNOS_EINT_NR_WKUP_EINT
-
-#define EXYNOS_PIN_BANK_EINTN(reg, __gpio, id)		\
-	{						\
-		.pctl_offset	= reg,			\
-		.pin_base	= (__gpio##_START),	\
-		.nr_pins	= (__gpio##_NR),	\
-		.func_width	= 4,			\
-		.pud_width	= 2,			\
-		.drv_width	= 2,			\
-		.conpdn_width	= 2,			\
-		.pudpdn_width	= 2,			\
-		.eint_type	= EINT_TYPE_NONE,	\
-		.name		= id			\
-	}
-
-#define EXYNOS_PIN_BANK_EINTG(reg, __gpio, id)		\
-	{						\
-		.pctl_offset	= reg,			\
-		.pin_base	= (__gpio##_START),	\
-		.nr_pins	= (__gpio##_NR),	\
-		.func_width	= 4,			\
-		.pud_width	= 2,			\
-		.drv_width	= 2,			\
-		.conpdn_width	= 2,			\
-		.pudpdn_width	= 2,			\
-		.eint_type	= EINT_TYPE_GPIO,	\
-		.irq_base	= (__gpio##_IRQ),	\
-		.name		= id			\
-	}
 
 /**
  * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks.
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 5d59ce6..db1907c 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -246,7 +246,6 @@ struct samsung_pmx_func {
 };
 
 /* list of all exported SoC specific data */
-extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
 extern struct samsung_pin_ctrl_variant exynos4_pin_ctrl;
 
 #endif /* __PINCTRL_SAMSUNG_H */
-- 
1.7.12

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

* [PATCH 05/16] pinctrl: exynos: Remove static SoC-specific data
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

The patch "pinctrl: samsung: Parse pin banks from DT" introduced parsing
SoC-specific data from device tree, so there is no need to keep the
previously used definitions in headers and source files.

This patch cleans up the pinctrl-exynos driver from unused
SoC-specific data.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  |  96 -----------------------
 drivers/pinctrl/pinctrl-exynos.h  | 157 --------------------------------------
 drivers/pinctrl/pinctrl-samsung.h |   1 -
 3 files changed, 254 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index e3fa263..134fecf 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -504,102 +504,6 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	return 0;
 }
 
-/* pin banks of exynos4210 pin-controller 0 */
-static struct samsung_pin_bank exynos4210_pin_banks0[] = {
-	EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_A0, "gpa0"),
-	EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_A1, "gpa1"),
-	EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_B, "gpb"),
-	EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_C0, "gpc0"),
-	EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_C1, "gpc1"),
-	EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_D0, "gpd0"),
-	EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_D1, "gpd1"),
-	EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_E0, "gpe0"),
-	EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_E1, "gpe1"),
-	EXYNOS_PIN_BANK_EINTG(0x120, EXYNOS4210_GPIO_E2, "gpe2"),
-	EXYNOS_PIN_BANK_EINTG(0x140, EXYNOS4210_GPIO_E3, "gpe3"),
-	EXYNOS_PIN_BANK_EINTG(0x160, EXYNOS4210_GPIO_E4, "gpe4"),
-	EXYNOS_PIN_BANK_EINTG(0x180, EXYNOS4210_GPIO_F0, "gpf0"),
-	EXYNOS_PIN_BANK_EINTG(0x1A0, EXYNOS4210_GPIO_F1, "gpf1"),
-	EXYNOS_PIN_BANK_EINTG(0x1C0, EXYNOS4210_GPIO_F2, "gpf2"),
-	EXYNOS_PIN_BANK_EINTG(0x1E0, EXYNOS4210_GPIO_F3, "gpf3"),
-};
-
-/* pin banks of exynos4210 pin-controller 1 */
-static struct samsung_pin_bank exynos4210_pin_banks1[] = {
-	EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_J0, "gpj0"),
-	EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_J1, "gpj1"),
-	EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_K0, "gpk0"),
-	EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_K1, "gpk1"),
-	EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_K2, "gpk2"),
-	EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_K3, "gpk3"),
-	EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_L0, "gpl0"),
-	EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_L1, "gpl1"),
-	EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_L2, "gpl2"),
-	EXYNOS_PIN_BANK_EINTN(0x120, EXYNOS4210_GPIO_Y0, "gpy0"),
-	EXYNOS_PIN_BANK_EINTN(0x140, EXYNOS4210_GPIO_Y1, "gpy1"),
-	EXYNOS_PIN_BANK_EINTN(0x160, EXYNOS4210_GPIO_Y2, "gpy2"),
-	EXYNOS_PIN_BANK_EINTN(0x180, EXYNOS4210_GPIO_Y3, "gpy3"),
-	EXYNOS_PIN_BANK_EINTN(0x1A0, EXYNOS4210_GPIO_Y4, "gpy4"),
-	EXYNOS_PIN_BANK_EINTN(0x1C0, EXYNOS4210_GPIO_Y5, "gpy5"),
-	EXYNOS_PIN_BANK_EINTN(0x1E0, EXYNOS4210_GPIO_Y6, "gpy6"),
-	EXYNOS_PIN_BANK_EINTN(0xC00, EXYNOS4210_GPIO_X0, "gpx0"),
-	EXYNOS_PIN_BANK_EINTN(0xC20, EXYNOS4210_GPIO_X1, "gpx1"),
-	EXYNOS_PIN_BANK_EINTN(0xC40, EXYNOS4210_GPIO_X2, "gpx2"),
-	EXYNOS_PIN_BANK_EINTN(0xC60, EXYNOS4210_GPIO_X3, "gpx3"),
-};
-
-/* pin banks of exynos4210 pin-controller 2 */
-static struct samsung_pin_bank exynos4210_pin_banks2[] = {
-	EXYNOS_PIN_BANK_EINTN(0x000, EXYNOS4210_GPIO_Z, "gpz"),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
- * three gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
-	{
-		/* pin-controller instance 0 data */
-		.pin_banks	= exynos4210_pin_banks0,
-		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks0),
-		.base		= EXYNOS4210_GPIO_A0_START,
-		.nr_pins	= EXYNOS4210_GPIOA_NR_PINS,
-		.nr_gint	= EXYNOS4210_GPIOA_NR_GINT,
-		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
-		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
-		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
-		.svc		= EXYNOS_SVC_OFFSET,
-		.eint_gpio_init = exynos_eint_gpio_init,
-		.label		= "exynos4210-gpio-ctrl0",
-	}, {
-		/* pin-controller instance 1 data */
-		.pin_banks	= exynos4210_pin_banks1,
-		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks1),
-		.base		= EXYNOS4210_GPIOA_NR_PINS,
-		.nr_pins	= EXYNOS4210_GPIOB_NR_PINS,
-		.nr_gint	= EXYNOS4210_GPIOB_NR_GINT,
-		.nr_wint	= 32,
-		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
-		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
-		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
-		.weint_con	= EXYNOS_WKUP_ECON_OFFSET,
-		.weint_mask	= EXYNOS_WKUP_EMASK_OFFSET,
-		.weint_pend	= EXYNOS_WKUP_EPEND_OFFSET,
-		.svc		= EXYNOS_SVC_OFFSET,
-		.eint_gpio_init = exynos_eint_gpio_init,
-		.eint_wkup_init = exynos_eint_wkup_init,
-		.label		= "exynos4210-gpio-ctrl1",
-	}, {
-		/* pin-controller instance 2 data */
-		.pin_banks	= exynos4210_pin_banks2,
-		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks2),
-		.base		= EXYNOS4210_GPIOA_NR_PINS +
-					EXYNOS4210_GPIOB_NR_PINS,
-		.nr_pins	= EXYNOS4210_GPIOC_NR_PINS,
-		.label		= "exynos4210-gpio-ctrl2",
-	},
-};
-
 struct samsung_pin_ctrl_variant exynos4_pin_ctrl = {
 	.eint_gpio_init = exynos_eint_gpio_init,
 	.eint_wkup_init = exynos_eint_wkup_init,
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index 31d0a06..a72cfc7 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -17,133 +17,6 @@
  * (at your option) any later version.
  */
 
-#define EXYNOS_GPIO_START(__gpio)	((__gpio##_START) + (__gpio##_NR))
-
-#define EXYNOS4210_GPIO_A0_NR	(8)
-#define EXYNOS4210_GPIO_A1_NR	(6)
-#define EXYNOS4210_GPIO_B_NR	(8)
-#define EXYNOS4210_GPIO_C0_NR	(5)
-#define EXYNOS4210_GPIO_C1_NR	(5)
-#define EXYNOS4210_GPIO_D0_NR	(4)
-#define EXYNOS4210_GPIO_D1_NR	(4)
-#define EXYNOS4210_GPIO_E0_NR	(5)
-#define EXYNOS4210_GPIO_E1_NR	(8)
-#define EXYNOS4210_GPIO_E2_NR	(6)
-#define EXYNOS4210_GPIO_E3_NR	(8)
-#define EXYNOS4210_GPIO_E4_NR	(8)
-#define EXYNOS4210_GPIO_F0_NR	(8)
-#define EXYNOS4210_GPIO_F1_NR	(8)
-#define EXYNOS4210_GPIO_F2_NR	(8)
-#define EXYNOS4210_GPIO_F3_NR	(6)
-#define EXYNOS4210_GPIO_J0_NR	(8)
-#define EXYNOS4210_GPIO_J1_NR	(5)
-#define EXYNOS4210_GPIO_K0_NR	(7)
-#define EXYNOS4210_GPIO_K1_NR	(7)
-#define EXYNOS4210_GPIO_K2_NR	(7)
-#define EXYNOS4210_GPIO_K3_NR	(7)
-#define EXYNOS4210_GPIO_L0_NR	(8)
-#define EXYNOS4210_GPIO_L1_NR	(3)
-#define EXYNOS4210_GPIO_L2_NR	(8)
-#define EXYNOS4210_GPIO_Y0_NR	(6)
-#define EXYNOS4210_GPIO_Y1_NR	(4)
-#define EXYNOS4210_GPIO_Y2_NR	(6)
-#define EXYNOS4210_GPIO_Y3_NR	(8)
-#define EXYNOS4210_GPIO_Y4_NR	(8)
-#define EXYNOS4210_GPIO_Y5_NR	(8)
-#define EXYNOS4210_GPIO_Y6_NR	(8)
-#define EXYNOS4210_GPIO_X0_NR	(8)
-#define EXYNOS4210_GPIO_X1_NR	(8)
-#define EXYNOS4210_GPIO_X2_NR	(8)
-#define EXYNOS4210_GPIO_X3_NR	(8)
-#define EXYNOS4210_GPIO_Z_NR	(7)
-
-enum exynos4210_gpio_xa_start {
-	EXYNOS4210_GPIO_A0_START	= 0,
-	EXYNOS4210_GPIO_A1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_A0),
-	EXYNOS4210_GPIO_B_START		= EXYNOS_GPIO_START(EXYNOS4210_GPIO_A1),
-	EXYNOS4210_GPIO_C0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_B),
-	EXYNOS4210_GPIO_C1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_C0),
-	EXYNOS4210_GPIO_D0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_C1),
-	EXYNOS4210_GPIO_D1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_D0),
-	EXYNOS4210_GPIO_E0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_D1),
-	EXYNOS4210_GPIO_E1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E0),
-	EXYNOS4210_GPIO_E2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E1),
-	EXYNOS4210_GPIO_E3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E2),
-	EXYNOS4210_GPIO_E4_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E3),
-	EXYNOS4210_GPIO_F0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E4),
-	EXYNOS4210_GPIO_F1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F0),
-	EXYNOS4210_GPIO_F2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F1),
-	EXYNOS4210_GPIO_F3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F2),
-};
-
-enum exynos4210_gpio_xb_start {
-	EXYNOS4210_GPIO_J0_START	= 0,
-	EXYNOS4210_GPIO_J1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_J0),
-	EXYNOS4210_GPIO_K0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_J1),
-	EXYNOS4210_GPIO_K1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K0),
-	EXYNOS4210_GPIO_K2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K1),
-	EXYNOS4210_GPIO_K3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K2),
-	EXYNOS4210_GPIO_L0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K3),
-	EXYNOS4210_GPIO_L1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L0),
-	EXYNOS4210_GPIO_L2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L1),
-	EXYNOS4210_GPIO_Y0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2),
-	EXYNOS4210_GPIO_Y1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y0),
-	EXYNOS4210_GPIO_Y2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y1),
-	EXYNOS4210_GPIO_Y3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y2),
-	EXYNOS4210_GPIO_Y4_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y3),
-	EXYNOS4210_GPIO_Y5_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y4),
-	EXYNOS4210_GPIO_Y6_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y5),
-	EXYNOS4210_GPIO_X0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y6),
-	EXYNOS4210_GPIO_X1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X0),
-	EXYNOS4210_GPIO_X2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X1),
-	EXYNOS4210_GPIO_X3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X2),
-};
-
-enum exynos4210_gpio_xc_start {
-	EXYNOS4210_GPIO_Z_START		= 0,
-};
-
-#define	EXYNOS4210_GPIO_A0_IRQ		EXYNOS4210_GPIO_A0_START
-#define	EXYNOS4210_GPIO_A1_IRQ		EXYNOS4210_GPIO_A1_START
-#define	EXYNOS4210_GPIO_B_IRQ		EXYNOS4210_GPIO_B_START
-#define	EXYNOS4210_GPIO_C0_IRQ		EXYNOS4210_GPIO_C0_START
-#define	EXYNOS4210_GPIO_C1_IRQ		EXYNOS4210_GPIO_C1_START
-#define	EXYNOS4210_GPIO_D0_IRQ		EXYNOS4210_GPIO_D0_START
-#define	EXYNOS4210_GPIO_D1_IRQ		EXYNOS4210_GPIO_D1_START
-#define	EXYNOS4210_GPIO_E0_IRQ		EXYNOS4210_GPIO_E0_START
-#define	EXYNOS4210_GPIO_E1_IRQ		EXYNOS4210_GPIO_E1_START
-#define	EXYNOS4210_GPIO_E2_IRQ		EXYNOS4210_GPIO_E2_START
-#define	EXYNOS4210_GPIO_E3_IRQ		EXYNOS4210_GPIO_E3_START
-#define	EXYNOS4210_GPIO_E4_IRQ		EXYNOS4210_GPIO_E4_START
-#define	EXYNOS4210_GPIO_F0_IRQ		EXYNOS4210_GPIO_F0_START
-#define	EXYNOS4210_GPIO_F1_IRQ		EXYNOS4210_GPIO_F1_START
-#define	EXYNOS4210_GPIO_F2_IRQ		EXYNOS4210_GPIO_F2_START
-#define	EXYNOS4210_GPIO_F3_IRQ		EXYNOS4210_GPIO_F3_START
-#define	EXYNOS4210_GPIO_J0_IRQ		EXYNOS4210_GPIO_J0_START
-#define	EXYNOS4210_GPIO_J1_IRQ		EXYNOS4210_GPIO_J1_START
-#define	EXYNOS4210_GPIO_K0_IRQ		EXYNOS4210_GPIO_K0_START
-#define	EXYNOS4210_GPIO_K1_IRQ		EXYNOS4210_GPIO_K1_START
-#define	EXYNOS4210_GPIO_K2_IRQ		EXYNOS4210_GPIO_K2_START
-#define	EXYNOS4210_GPIO_K3_IRQ		EXYNOS4210_GPIO_K3_START
-#define	EXYNOS4210_GPIO_L0_IRQ		EXYNOS4210_GPIO_L0_START
-#define	EXYNOS4210_GPIO_L1_IRQ		EXYNOS4210_GPIO_L1_START
-#define	EXYNOS4210_GPIO_L2_IRQ		EXYNOS4210_GPIO_L2_START
-#define	EXYNOS4210_GPIO_Z_IRQ		EXYNOS4210_GPIO_Z_START
-
-#define EXYNOS4210_GPIOA_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3)
-#define EXYNOS4210_GPIOA_NR_GINT	EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3)
-#define EXYNOS4210_GPIOB_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_X3)
-#define EXYNOS4210_GPIOB_NR_GINT	EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2)
-#define EXYNOS4210_GPIOC_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_Z)
-
-/* External GPIO and wakeup interrupt related definitions */
-#define EXYNOS_GPIO_ECON_OFFSET		0x700
-#define EXYNOS_GPIO_EMASK_OFFSET	0x900
-#define EXYNOS_GPIO_EPEND_OFFSET	0xA00
-#define EXYNOS_WKUP_ECON_OFFSET		0xE00
-#define EXYNOS_WKUP_EMASK_OFFSET	0xF00
-#define EXYNOS_WKUP_EPEND_OFFSET	0xF40
-#define EXYNOS_SVC_OFFSET		0xB08
 #define EXYNOS_EINT_FUNC		0xF
 
 /* helpers to access interrupt service register */
@@ -163,36 +36,6 @@ enum exynos4210_gpio_xc_start {
 #define EXYNOS_EINT_CON_LEN		4
 
 #define EXYNOS_EINT_MAX_PER_BANK	8
-#define EXYNOS_EINT_NR_WKUP_EINT
-
-#define EXYNOS_PIN_BANK_EINTN(reg, __gpio, id)		\
-	{						\
-		.pctl_offset	= reg,			\
-		.pin_base	= (__gpio##_START),	\
-		.nr_pins	= (__gpio##_NR),	\
-		.func_width	= 4,			\
-		.pud_width	= 2,			\
-		.drv_width	= 2,			\
-		.conpdn_width	= 2,			\
-		.pudpdn_width	= 2,			\
-		.eint_type	= EINT_TYPE_NONE,	\
-		.name		= id			\
-	}
-
-#define EXYNOS_PIN_BANK_EINTG(reg, __gpio, id)		\
-	{						\
-		.pctl_offset	= reg,			\
-		.pin_base	= (__gpio##_START),	\
-		.nr_pins	= (__gpio##_NR),	\
-		.func_width	= 4,			\
-		.pud_width	= 2,			\
-		.drv_width	= 2,			\
-		.conpdn_width	= 2,			\
-		.pudpdn_width	= 2,			\
-		.eint_type	= EINT_TYPE_GPIO,	\
-		.irq_base	= (__gpio##_IRQ),	\
-		.name		= id			\
-	}
 
 /**
  * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks.
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 5d59ce6..db1907c 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -246,7 +246,6 @@ struct samsung_pmx_func {
 };
 
 /* list of all exported SoC specific data */
-extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
 extern struct samsung_pin_ctrl_variant exynos4_pin_ctrl;
 
 #endif /* __PINCTRL_SAMSUNG_H */
-- 
1.7.12

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

* [PATCH 06/16] pinctrl: samsung: Parse bank-specific eint offset from DT
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

Some SoCs, like Exynos4x12, have non-sequential layout of EINT control
registers and so current way of calculating register addresses does not
work correctly for them.

This patch adds parsing of samsung,eint-offset property from bank nodes
and uses the read values instead of calculating the offsets from bank
index.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 5 ++---
 drivers/pinctrl/pinctrl-samsung.c | 5 +++++
 drivers/pinctrl/pinctrl-samsung.h | 1 +
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 134fecf..340bfc2 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -146,7 +146,7 @@ static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
 	struct samsung_pin_bank *bank = d->ctrl->pin_banks;
 	struct exynos_geint_data *eint_data;
 	unsigned int nr_banks = d->ctrl->nr_banks, idx;
-	unsigned int irq_base = 0, eint_offset = 0;
+	unsigned int irq_base = 0;
 
 	if (hw >= d->ctrl->nr_gint) {
 		dev_err(d->dev, "unsupported ext-gpio interrupt\n");
@@ -159,7 +159,6 @@ static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
 		if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins)))
 			break;
 		irq_base += bank->nr_pins;
-		eint_offset += 4;
 	}
 
 	if (idx == nr_banks) {
@@ -175,7 +174,7 @@ static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
 
 	eint_data->bank	= bank;
 	eint_data->pin = hw - irq_base;
-	eint_data->eint_offset = eint_offset;
+	eint_data->eint_offset = bank->eint_offset;
 	return eint_data;
 }
 
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index e828a0e..962320b 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -859,6 +859,11 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 
 	bank->eint_type = EINT_TYPE_GPIO;
 
+	ret = of_property_read_u32(np, "samsung,eint-offset", &val);
+	if (ret)
+		return ret;
+	bank->eint_offset = val;
+
 	return 0;
 }
 
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index db1907c..72303f1 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -122,6 +122,7 @@ struct samsung_pin_bank {
 	u8		conpdn_width;
 	u8		pudpdn_width;
 	enum eint_type	eint_type;
+	u32		eint_offset;
 	u32		irq_base;
 	const char	*name;
 };
-- 
1.7.12

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

* [PATCH 06/16] pinctrl: samsung: Parse bank-specific eint offset from DT
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Some SoCs, like Exynos4x12, have non-sequential layout of EINT control
registers and so current way of calculating register addresses does not
work correctly for them.

This patch adds parsing of samsung,eint-offset property from bank nodes
and uses the read values instead of calculating the offsets from bank
index.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 5 ++---
 drivers/pinctrl/pinctrl-samsung.c | 5 +++++
 drivers/pinctrl/pinctrl-samsung.h | 1 +
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 134fecf..340bfc2 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -146,7 +146,7 @@ static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
 	struct samsung_pin_bank *bank = d->ctrl->pin_banks;
 	struct exynos_geint_data *eint_data;
 	unsigned int nr_banks = d->ctrl->nr_banks, idx;
-	unsigned int irq_base = 0, eint_offset = 0;
+	unsigned int irq_base = 0;
 
 	if (hw >= d->ctrl->nr_gint) {
 		dev_err(d->dev, "unsupported ext-gpio interrupt\n");
@@ -159,7 +159,6 @@ static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
 		if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins)))
 			break;
 		irq_base += bank->nr_pins;
-		eint_offset += 4;
 	}
 
 	if (idx == nr_banks) {
@@ -175,7 +174,7 @@ static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
 
 	eint_data->bank	= bank;
 	eint_data->pin = hw - irq_base;
-	eint_data->eint_offset = eint_offset;
+	eint_data->eint_offset = bank->eint_offset;
 	return eint_data;
 }
 
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index e828a0e..962320b 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -859,6 +859,11 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 
 	bank->eint_type = EINT_TYPE_GPIO;
 
+	ret = of_property_read_u32(np, "samsung,eint-offset", &val);
+	if (ret)
+		return ret;
+	bank->eint_offset = val;
+
 	return 0;
 }
 
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index db1907c..72303f1 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -122,6 +122,7 @@ struct samsung_pin_bank {
 	u8		conpdn_width;
 	u8		pudpdn_width;
 	enum eint_type	eint_type;
+	u32		eint_offset;
 	u32		irq_base;
 	const char	*name;
 };
-- 
1.7.12

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

* [PATCH 07/16] pinctrl: samsung: Hold OF node of pin bank in bank struct
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

The node pointer will be used in extensions added by patches that will
follow.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 1 +
 drivers/pinctrl/pinctrl-samsung.h | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 962320b..c988a4e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -850,6 +850,7 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 		return ret;
 	bank->nr_pins = val;
 
+	bank->of_node = np;
 	bank->name = np->name;
 
 	if (!of_find_property(np, "interrupt-controller", NULL)) {
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 72303f1..b7b74cc 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -111,6 +111,7 @@ struct samsung_pinctrl_drv_data;
  * @eint_type: type of the external interrupt supported by the bank.
  * @irq_base: starting controller local irq number of the bank.
  * @name: name to be prefixed for each pin in this pin bank.
+ * @of_node: node of pin bank in device tree
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -125,6 +126,8 @@ struct samsung_pin_bank {
 	u32		eint_offset;
 	u32		irq_base;
 	const char	*name;
+
+	struct device_node *of_node;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 07/16] pinctrl: samsung: Hold OF node of pin bank in bank struct
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

The node pointer will be used in extensions added by patches that will
follow.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 1 +
 drivers/pinctrl/pinctrl-samsung.h | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 962320b..c988a4e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -850,6 +850,7 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 		return ret;
 	bank->nr_pins = val;
 
+	bank->of_node = np;
 	bank->name = np->name;
 
 	if (!of_find_property(np, "interrupt-controller", NULL)) {
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 72303f1..b7b74cc 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -111,6 +111,7 @@ struct samsung_pinctrl_drv_data;
  * @eint_type: type of the external interrupt supported by the bank.
  * @irq_base: starting controller local irq number of the bank.
  * @name: name to be prefixed for each pin in this pin bank.
+ * @of_node: node of pin bank in device tree
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -125,6 +126,8 @@ struct samsung_pin_bank {
 	u32		eint_offset;
 	u32		irq_base;
 	const char	*name;
+
+	struct device_node *of_node;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 08/16] pinctrl: samsung: Hold pointer to driver data in bank struct
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

The pointer will be used by further extensions added to the driver.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 20 +++++++++++---------
 drivers/pinctrl/pinctrl-samsung.h |  2 ++
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index c988a4e..63c76ec 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -870,11 +870,12 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 
 /* retrieve the soc specific data */
 static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
-				struct platform_device *pdev)
+					struct platform_device *pdev,
+					struct samsung_pinctrl_drv_data *d)
 {
 	int id;
 	const struct of_device_id *match;
-	const struct device_node *node = pdev->dev.of_node;
+	struct device_node *node = pdev->dev.of_node;
 	struct device_node *bank_np;
 	struct samsung_pin_ctrl *ctrl;
 	struct samsung_pin_bank *banks, *b;
@@ -884,7 +885,7 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 	u32 val;
 	int ret;
 
-	id = of_alias_get_id(pdev->dev.of_node, "pinctrl");
+	id = of_alias_get_id(node, "pinctrl");
 	if (id < 0) {
 		dev_err(&pdev->dev, "failed to get alias id\n");
 		return NULL;
@@ -922,6 +923,7 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 			continue;
 		if (samsung_pinctrl_parse_dt_bank(b, bank_np))
 			return NULL;
+		b->drvdata = d;
 		b->pin_base = ctrl->nr_pins;
 		ctrl->nr_pins += b->nr_pins;
 		if (b->eint_type == EINT_TYPE_GPIO) {
@@ -979,18 +981,18 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	ctrl = samsung_pinctrl_get_soc_data(pdev);
-	if (!ctrl) {
-		dev_err(&pdev->dev, "driver data not available\n");
-		return -EINVAL;
-	}
-
 	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
 	if (!drvdata) {
 		dev_err(dev, "failed to allocate memory for driver's "
 				"private data\n");
 		return -ENOMEM;
 	}
+
+	ctrl = samsung_pinctrl_get_soc_data(pdev, drvdata);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "driver data not available\n");
+		return -EINVAL;
+	}
 	drvdata->ctrl = ctrl;
 	drvdata->dev = dev;
 
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index b7b74cc..9e30081 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -112,6 +112,7 @@ struct samsung_pinctrl_drv_data;
  * @irq_base: starting controller local irq number of the bank.
  * @name: name to be prefixed for each pin in this pin bank.
  * @of_node: node of pin bank in device tree
+ * @drvdata: link to controller driver data
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -128,6 +129,7 @@ struct samsung_pin_bank {
 	const char	*name;
 
 	struct device_node *of_node;
+	struct samsung_pinctrl_drv_data *drvdata;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 08/16] pinctrl: samsung: Hold pointer to driver data in bank struct
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

The pointer will be used by further extensions added to the driver.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 20 +++++++++++---------
 drivers/pinctrl/pinctrl-samsung.h |  2 ++
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index c988a4e..63c76ec 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -870,11 +870,12 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 
 /* retrieve the soc specific data */
 static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
-				struct platform_device *pdev)
+					struct platform_device *pdev,
+					struct samsung_pinctrl_drv_data *d)
 {
 	int id;
 	const struct of_device_id *match;
-	const struct device_node *node = pdev->dev.of_node;
+	struct device_node *node = pdev->dev.of_node;
 	struct device_node *bank_np;
 	struct samsung_pin_ctrl *ctrl;
 	struct samsung_pin_bank *banks, *b;
@@ -884,7 +885,7 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 	u32 val;
 	int ret;
 
-	id = of_alias_get_id(pdev->dev.of_node, "pinctrl");
+	id = of_alias_get_id(node, "pinctrl");
 	if (id < 0) {
 		dev_err(&pdev->dev, "failed to get alias id\n");
 		return NULL;
@@ -922,6 +923,7 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 			continue;
 		if (samsung_pinctrl_parse_dt_bank(b, bank_np))
 			return NULL;
+		b->drvdata = d;
 		b->pin_base = ctrl->nr_pins;
 		ctrl->nr_pins += b->nr_pins;
 		if (b->eint_type == EINT_TYPE_GPIO) {
@@ -979,18 +981,18 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	ctrl = samsung_pinctrl_get_soc_data(pdev);
-	if (!ctrl) {
-		dev_err(&pdev->dev, "driver data not available\n");
-		return -EINVAL;
-	}
-
 	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
 	if (!drvdata) {
 		dev_err(dev, "failed to allocate memory for driver's "
 				"private data\n");
 		return -ENOMEM;
 	}
+
+	ctrl = samsung_pinctrl_get_soc_data(pdev, drvdata);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "driver data not available\n");
+		return -EINVAL;
+	}
 	drvdata->ctrl = ctrl;
 	drvdata->dev = dev;
 
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index b7b74cc..9e30081 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -112,6 +112,7 @@ struct samsung_pinctrl_drv_data;
  * @irq_base: starting controller local irq number of the bank.
  * @name: name to be prefixed for each pin in this pin bank.
  * @of_node: node of pin bank in device tree
+ * @drvdata: link to controller driver data
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -128,6 +129,7 @@ struct samsung_pin_bank {
 	const char	*name;
 
 	struct device_node *of_node;
+	struct samsung_pinctrl_drv_data *drvdata;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 09/16] pinctrl: exynos: Use one IRQ domain per pin bank
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

Instead of registering one IRQ domain for all pin banks of a pin
controller, this patch implements registration of per-bank domains.

At a cost of a little memory overhead (~2.5KiB for all GPIO interrupts
of Exynos4x12) it simplifies driver code and device tree sources,
because GPIO interrupts can be now specified per banks.

Example:
	device {
		/* ... */
		interrupt-parent = <&gpa1>;
		interrupts = <3 0>;
		/* ... */
	};

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 117 +++++++++++---------------------------
 drivers/pinctrl/pinctrl-exynos.h  |  12 ----
 drivers/pinctrl/pinctrl-samsung.c |   5 +-
 drivers/pinctrl/pinctrl-samsung.h |   7 +--
 4 files changed, 36 insertions(+), 105 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 340bfc2..53ed5d9 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -40,46 +40,46 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
 
 static void exynos_gpio_irq_unmask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << edata->pin);
+	mask &= ~(1 << irqd->hwirq);
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_gpio_irq_mask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << edata->pin;
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_gpio_irq_ack(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_pend = d->ctrl->geint_pend + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
 
-	writel(1 << edata->pin, d->virt_base + reg_pend);
+	writel(1 << irqd->hwirq, d->virt_base + reg_pend);
 }
 
 static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	struct samsung_pin_ctrl *ctrl = d->ctrl;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	struct samsung_pin_bank *bank = edata->bank;
-	unsigned int shift = EXYNOS_EINT_CON_LEN * edata->pin;
+	unsigned int pin = irqd->hwirq;
+	unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned int con, trig_type;
-	unsigned long reg_con = ctrl->geint_con + edata->eint_offset;
+	unsigned long reg_con = ctrl->geint_con + bank->eint_offset;
 	unsigned int mask;
 
 	switch (type) {
@@ -114,7 +114,7 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 	writel(con, d->virt_base + reg_con);
 
 	reg_con = bank->pctl_offset;
-	shift = edata->pin * bank->func_width;
+	shift = pin * bank->func_width;
 	mask = (1 << bank->func_width) - 1;
 
 	con = readl(d->virt_base + reg_con);
@@ -136,81 +136,23 @@ static struct irq_chip exynos_gpio_irq_chip = {
 	.irq_set_type	= exynos_gpio_irq_set_type,
 };
 
-/*
- * given a controller-local external gpio interrupt number, prepare the handler
- * data for it.
- */
-static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
-				struct samsung_pinctrl_drv_data *d)
-{
-	struct samsung_pin_bank *bank = d->ctrl->pin_banks;
-	struct exynos_geint_data *eint_data;
-	unsigned int nr_banks = d->ctrl->nr_banks, idx;
-	unsigned int irq_base = 0;
-
-	if (hw >= d->ctrl->nr_gint) {
-		dev_err(d->dev, "unsupported ext-gpio interrupt\n");
-		return NULL;
-	}
-
-	for (idx = 0; idx < nr_banks; idx++, bank++) {
-		if (bank->eint_type != EINT_TYPE_GPIO)
-			continue;
-		if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins)))
-			break;
-		irq_base += bank->nr_pins;
-	}
-
-	if (idx == nr_banks) {
-		dev_err(d->dev, "pin bank not found for ext-gpio interrupt\n");
-		return NULL;
-	}
-
-	eint_data = devm_kzalloc(d->dev, sizeof(*eint_data), GFP_KERNEL);
-	if (!eint_data) {
-		dev_err(d->dev, "no memory for eint-gpio data\n");
-		return NULL;
-	}
-
-	eint_data->bank	= bank;
-	eint_data->pin = hw - irq_base;
-	eint_data->eint_offset = bank->eint_offset;
-	return eint_data;
-}
-
 static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
 					irq_hw_number_t hw)
 {
-	struct samsung_pinctrl_drv_data *d = h->host_data;
-	struct exynos_geint_data *eint_data;
-
-	eint_data = exynos_get_eint_data(hw, d);
-	if (!eint_data)
-		return -EINVAL;
+	struct samsung_pin_bank *b = h->host_data;
 
-	irq_set_handler_data(virq, eint_data);
-	irq_set_chip_data(virq, h->host_data);
+	irq_set_chip_data(virq, b);
 	irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
 					handle_level_irq);
 	set_irq_flags(virq, IRQF_VALID);
 	return 0;
 }
 
-static void exynos_gpio_irq_unmap(struct irq_domain *h, unsigned int virq)
-{
-	struct samsung_pinctrl_drv_data *d = h->host_data;
-	struct exynos_geint_data *eint_data;
-
-	eint_data = irq_get_handler_data(virq);
-	devm_kfree(d->dev, eint_data);
-}
-
 /*
  * irq domain callbacks for external gpio interrupt controller.
  */
 static const struct irq_domain_ops exynos_gpio_irqd_ops = {
 	.map	= exynos_gpio_irq_map,
-	.unmap	= exynos_gpio_irq_unmap,
 	.xlate	= irq_domain_xlate_twocell,
 };
 
@@ -229,7 +171,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
 		return IRQ_HANDLED;
 	bank += (group - 1);
 
-	virq = irq_linear_revmap(d->gpio_irqd, bank->irq_base + pin);
+	virq = irq_linear_revmap(bank->irq_domain, pin);
 	if (!virq)
 		return IRQ_NONE;
 	generic_handle_irq(virq);
@@ -242,8 +184,10 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
  */
 static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 {
+	struct samsung_pin_bank *bank;
 	struct device *dev = d->dev;
 	unsigned int ret;
+	unsigned int i;
 
 	if (!d->irq) {
 		dev_err(dev, "irq number not available\n");
@@ -257,11 +201,16 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 		return -ENXIO;
 	}
 
-	d->gpio_irqd = irq_domain_add_linear(dev->of_node, d->ctrl->nr_gint,
-				&exynos_gpio_irqd_ops, d);
-	if (!d->gpio_irqd) {
-		dev_err(dev, "gpio irq domain allocation failed\n");
-		return -ENXIO;
+	bank = d->ctrl->pin_banks;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_GPIO)
+			continue;
+		bank->irq_domain = irq_domain_add_linear(bank->of_node,
+				bank->nr_pins, &exynos_gpio_irqd_ops, bank);
+		if (!bank->irq_domain) {
+			dev_err(dev, "gpio irq domain add failed\n");
+			return -ENXIO;
+		}
 	}
 
 	return 0;
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index a72cfc7..30aca2b 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -38,18 +38,6 @@
 #define EXYNOS_EINT_MAX_PER_BANK	8
 
 /**
- * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks.
- * @bank: pin bank from which this gpio interrupt originates.
- * @pin: pin number within the bank.
- * @eint_offset: offset to be added to the con/pend/mask register bank base.
- */
-struct exynos_geint_data {
-	struct samsung_pin_bank	*bank;
-	u32			pin;
-	u32			eint_offset;
-};
-
-/**
  * struct exynos_weint_data: irq specific data for all the wakeup interrupts
  * generated by the external wakeup interrupt controller.
  * @domain: irq domain representing the external wakeup interrupts
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 63c76ec..6ae82d5 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -926,10 +926,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 		b->drvdata = d;
 		b->pin_base = ctrl->nr_pins;
 		ctrl->nr_pins += b->nr_pins;
-		if (b->eint_type == EINT_TYPE_GPIO) {
-			b->irq_base = eint_cnt;
+		if (b->eint_type == EINT_TYPE_GPIO)
 			eint_cnt += b->nr_pins;
-		}
 		++b;
 	}
 
@@ -959,7 +957,6 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 
 	ctrl->pin_banks = banks;
 	ctrl->nr_banks = bank_cnt;
-	ctrl->nr_gint = eint_cnt;
 	ctrl->label = node->name;
 	ctrl->eint_wkup_init = variant->eint_wkup_init;
 	ctrl->base = pin_base;
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 9e30081..470e11b 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -109,10 +109,10 @@ struct samsung_pinctrl_drv_data;
  * @conpdn_width: width of the sleep mode function selector bin field.
  * @pudpdn_width: width of the sleep mode pull up/down selector bit field.
  * @eint_type: type of the external interrupt supported by the bank.
- * @irq_base: starting controller local irq number of the bank.
  * @name: name to be prefixed for each pin in this pin bank.
  * @of_node: node of pin bank in device tree
  * @drvdata: link to controller driver data
+ * @irq_domain: IRQ domain of the bank.
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -125,11 +125,11 @@ struct samsung_pin_bank {
 	u8		pudpdn_width;
 	enum eint_type	eint_type;
 	u32		eint_offset;
-	u32		irq_base;
 	const char	*name;
 
 	struct device_node *of_node;
 	struct samsung_pinctrl_drv_data *drvdata;
+	struct irq_domain *irq_domain;
 };
 
 /**
@@ -150,7 +150,6 @@ struct samsung_pin_ctrl_variant {
  * @nr_banks: number of pin banks.
  * @base: starting system wide pin number.
  * @nr_pins: number of pins supported by the controller.
- * @nr_gint: number of external gpio interrupts supported.
  * @nr_wint: number of external wakeup interrupts supported.
  * @geint_con: offset of the ext-gpio controller registers.
  * @geint_mask: offset of the ext-gpio interrupt mask registers.
@@ -171,7 +170,6 @@ struct samsung_pin_ctrl {
 
 	u32		base;
 	u32		nr_pins;
-	u32		nr_gint;
 	u32		nr_wint;
 
 	u32		geint_con;
@@ -218,7 +216,6 @@ struct samsung_pinctrl_drv_data {
 	const struct samsung_pmx_func	*pmx_functions;
 	unsigned int			nr_functions;
 
-	struct irq_domain		*gpio_irqd;
 	struct irq_domain		*wkup_irqd;
 
 	struct gpio_chip		*gc;
-- 
1.7.12

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

* [PATCH 09/16] pinctrl: exynos: Use one IRQ domain per pin bank
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of registering one IRQ domain for all pin banks of a pin
controller, this patch implements registration of per-bank domains.

At a cost of a little memory overhead (~2.5KiB for all GPIO interrupts
of Exynos4x12) it simplifies driver code and device tree sources,
because GPIO interrupts can be now specified per banks.

Example:
	device {
		/* ... */
		interrupt-parent = <&gpa1>;
		interrupts = <3 0>;
		/* ... */
	};

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 117 +++++++++++---------------------------
 drivers/pinctrl/pinctrl-exynos.h  |  12 ----
 drivers/pinctrl/pinctrl-samsung.c |   5 +-
 drivers/pinctrl/pinctrl-samsung.h |   7 +--
 4 files changed, 36 insertions(+), 105 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 340bfc2..53ed5d9 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -40,46 +40,46 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
 
 static void exynos_gpio_irq_unmask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << edata->pin);
+	mask &= ~(1 << irqd->hwirq);
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_gpio_irq_mask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << edata->pin;
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_gpio_irq_ack(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_pend = d->ctrl->geint_pend + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
 
-	writel(1 << edata->pin, d->virt_base + reg_pend);
+	writel(1 << irqd->hwirq, d->virt_base + reg_pend);
 }
 
 static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	struct samsung_pin_ctrl *ctrl = d->ctrl;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	struct samsung_pin_bank *bank = edata->bank;
-	unsigned int shift = EXYNOS_EINT_CON_LEN * edata->pin;
+	unsigned int pin = irqd->hwirq;
+	unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned int con, trig_type;
-	unsigned long reg_con = ctrl->geint_con + edata->eint_offset;
+	unsigned long reg_con = ctrl->geint_con + bank->eint_offset;
 	unsigned int mask;
 
 	switch (type) {
@@ -114,7 +114,7 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 	writel(con, d->virt_base + reg_con);
 
 	reg_con = bank->pctl_offset;
-	shift = edata->pin * bank->func_width;
+	shift = pin * bank->func_width;
 	mask = (1 << bank->func_width) - 1;
 
 	con = readl(d->virt_base + reg_con);
@@ -136,81 +136,23 @@ static struct irq_chip exynos_gpio_irq_chip = {
 	.irq_set_type	= exynos_gpio_irq_set_type,
 };
 
-/*
- * given a controller-local external gpio interrupt number, prepare the handler
- * data for it.
- */
-static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
-				struct samsung_pinctrl_drv_data *d)
-{
-	struct samsung_pin_bank *bank = d->ctrl->pin_banks;
-	struct exynos_geint_data *eint_data;
-	unsigned int nr_banks = d->ctrl->nr_banks, idx;
-	unsigned int irq_base = 0;
-
-	if (hw >= d->ctrl->nr_gint) {
-		dev_err(d->dev, "unsupported ext-gpio interrupt\n");
-		return NULL;
-	}
-
-	for (idx = 0; idx < nr_banks; idx++, bank++) {
-		if (bank->eint_type != EINT_TYPE_GPIO)
-			continue;
-		if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins)))
-			break;
-		irq_base += bank->nr_pins;
-	}
-
-	if (idx == nr_banks) {
-		dev_err(d->dev, "pin bank not found for ext-gpio interrupt\n");
-		return NULL;
-	}
-
-	eint_data = devm_kzalloc(d->dev, sizeof(*eint_data), GFP_KERNEL);
-	if (!eint_data) {
-		dev_err(d->dev, "no memory for eint-gpio data\n");
-		return NULL;
-	}
-
-	eint_data->bank	= bank;
-	eint_data->pin = hw - irq_base;
-	eint_data->eint_offset = bank->eint_offset;
-	return eint_data;
-}
-
 static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
 					irq_hw_number_t hw)
 {
-	struct samsung_pinctrl_drv_data *d = h->host_data;
-	struct exynos_geint_data *eint_data;
-
-	eint_data = exynos_get_eint_data(hw, d);
-	if (!eint_data)
-		return -EINVAL;
+	struct samsung_pin_bank *b = h->host_data;
 
-	irq_set_handler_data(virq, eint_data);
-	irq_set_chip_data(virq, h->host_data);
+	irq_set_chip_data(virq, b);
 	irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
 					handle_level_irq);
 	set_irq_flags(virq, IRQF_VALID);
 	return 0;
 }
 
-static void exynos_gpio_irq_unmap(struct irq_domain *h, unsigned int virq)
-{
-	struct samsung_pinctrl_drv_data *d = h->host_data;
-	struct exynos_geint_data *eint_data;
-
-	eint_data = irq_get_handler_data(virq);
-	devm_kfree(d->dev, eint_data);
-}
-
 /*
  * irq domain callbacks for external gpio interrupt controller.
  */
 static const struct irq_domain_ops exynos_gpio_irqd_ops = {
 	.map	= exynos_gpio_irq_map,
-	.unmap	= exynos_gpio_irq_unmap,
 	.xlate	= irq_domain_xlate_twocell,
 };
 
@@ -229,7 +171,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
 		return IRQ_HANDLED;
 	bank += (group - 1);
 
-	virq = irq_linear_revmap(d->gpio_irqd, bank->irq_base + pin);
+	virq = irq_linear_revmap(bank->irq_domain, pin);
 	if (!virq)
 		return IRQ_NONE;
 	generic_handle_irq(virq);
@@ -242,8 +184,10 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
  */
 static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 {
+	struct samsung_pin_bank *bank;
 	struct device *dev = d->dev;
 	unsigned int ret;
+	unsigned int i;
 
 	if (!d->irq) {
 		dev_err(dev, "irq number not available\n");
@@ -257,11 +201,16 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 		return -ENXIO;
 	}
 
-	d->gpio_irqd = irq_domain_add_linear(dev->of_node, d->ctrl->nr_gint,
-				&exynos_gpio_irqd_ops, d);
-	if (!d->gpio_irqd) {
-		dev_err(dev, "gpio irq domain allocation failed\n");
-		return -ENXIO;
+	bank = d->ctrl->pin_banks;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_GPIO)
+			continue;
+		bank->irq_domain = irq_domain_add_linear(bank->of_node,
+				bank->nr_pins, &exynos_gpio_irqd_ops, bank);
+		if (!bank->irq_domain) {
+			dev_err(dev, "gpio irq domain add failed\n");
+			return -ENXIO;
+		}
 	}
 
 	return 0;
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index a72cfc7..30aca2b 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -38,18 +38,6 @@
 #define EXYNOS_EINT_MAX_PER_BANK	8
 
 /**
- * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks.
- * @bank: pin bank from which this gpio interrupt originates.
- * @pin: pin number within the bank.
- * @eint_offset: offset to be added to the con/pend/mask register bank base.
- */
-struct exynos_geint_data {
-	struct samsung_pin_bank	*bank;
-	u32			pin;
-	u32			eint_offset;
-};
-
-/**
  * struct exynos_weint_data: irq specific data for all the wakeup interrupts
  * generated by the external wakeup interrupt controller.
  * @domain: irq domain representing the external wakeup interrupts
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 63c76ec..6ae82d5 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -926,10 +926,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 		b->drvdata = d;
 		b->pin_base = ctrl->nr_pins;
 		ctrl->nr_pins += b->nr_pins;
-		if (b->eint_type == EINT_TYPE_GPIO) {
-			b->irq_base = eint_cnt;
+		if (b->eint_type == EINT_TYPE_GPIO)
 			eint_cnt += b->nr_pins;
-		}
 		++b;
 	}
 
@@ -959,7 +957,6 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
 
 	ctrl->pin_banks = banks;
 	ctrl->nr_banks = bank_cnt;
-	ctrl->nr_gint = eint_cnt;
 	ctrl->label = node->name;
 	ctrl->eint_wkup_init = variant->eint_wkup_init;
 	ctrl->base = pin_base;
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 9e30081..470e11b 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -109,10 +109,10 @@ struct samsung_pinctrl_drv_data;
  * @conpdn_width: width of the sleep mode function selector bin field.
  * @pudpdn_width: width of the sleep mode pull up/down selector bit field.
  * @eint_type: type of the external interrupt supported by the bank.
- * @irq_base: starting controller local irq number of the bank.
  * @name: name to be prefixed for each pin in this pin bank.
  * @of_node: node of pin bank in device tree
  * @drvdata: link to controller driver data
+ * @irq_domain: IRQ domain of the bank.
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -125,11 +125,11 @@ struct samsung_pin_bank {
 	u8		pudpdn_width;
 	enum eint_type	eint_type;
 	u32		eint_offset;
-	u32		irq_base;
 	const char	*name;
 
 	struct device_node *of_node;
 	struct samsung_pinctrl_drv_data *drvdata;
+	struct irq_domain *irq_domain;
 };
 
 /**
@@ -150,7 +150,6 @@ struct samsung_pin_ctrl_variant {
  * @nr_banks: number of pin banks.
  * @base: starting system wide pin number.
  * @nr_pins: number of pins supported by the controller.
- * @nr_gint: number of external gpio interrupts supported.
  * @nr_wint: number of external wakeup interrupts supported.
  * @geint_con: offset of the ext-gpio controller registers.
  * @geint_mask: offset of the ext-gpio interrupt mask registers.
@@ -171,7 +170,6 @@ struct samsung_pin_ctrl {
 
 	u32		base;
 	u32		nr_pins;
-	u32		nr_gint;
 	u32		nr_wint;
 
 	u32		geint_con;
@@ -218,7 +216,6 @@ struct samsung_pinctrl_drv_data {
 	const struct samsung_pmx_func	*pmx_functions;
 	unsigned int			nr_functions;
 
-	struct irq_domain		*gpio_irqd;
 	struct irq_domain		*wkup_irqd;
 
 	struct gpio_chip		*gc;
-- 
1.7.12

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

* [PATCH 10/16] pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

The pointer to gpio_chip passed to pin_to_reg_bank utility function is
used only to retrieve a pointer to samsung_pinctrl_drv_data structure.

This patch modifies the function and its users to pass a pointer to
samsung_pinctrl_drv_data directly.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 6ae82d5..e63a365 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -252,14 +252,12 @@ static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
  * given a pin number that is local to a pin controller, find out the pin bank
  * and the register base of the pin bank.
  */
-static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin,
-			void __iomem **reg, u32 *offset,
+static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
+			unsigned pin, void __iomem **reg, u32 *offset,
 			struct samsung_pin_bank **bank)
 {
-	struct samsung_pinctrl_drv_data *drvdata;
 	struct samsung_pin_bank *b;
 
-	drvdata = dev_get_drvdata(gc->dev);
 	b = drvdata->ctrl->pin_banks;
 
 	while ((pin >= b->pin_base) &&
@@ -294,7 +292,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
 	 * pin function number in the config register.
 	 */
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
-		pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base,
+		pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
 				&reg, &pin_offset, &bank);
 		mask = (1 << bank->func_width) - 1;
 		shift = pin_offset * bank->func_width;
@@ -331,10 +329,13 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 		struct pinctrl_gpio_range *range, unsigned offset, bool input)
 {
 	struct samsung_pin_bank *bank;
+	struct samsung_pinctrl_drv_data *drvdata;
 	void __iomem *reg;
 	u32 data, pin_offset, mask, shift;
 
-	pin_to_reg_bank(range->gc, offset, &reg, &pin_offset, &bank);
+	drvdata = pinctrl_dev_get_drvdata(pctldev);
+
+	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, &bank);
 	mask = (1 << bank->func_width) - 1;
 	shift = pin_offset * bank->func_width;
 
@@ -368,7 +369,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 	u32 cfg_value, cfg_reg;
 
 	drvdata = pinctrl_dev_get_drvdata(pctldev);
-	pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, &reg_base,
+	pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, &reg_base,
 					&pin_offset, &bank);
 
 	switch (cfg_type) {
@@ -470,8 +471,11 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 {
 	void __iomem *reg;
 	u32 pin_offset, data;
+	struct samsung_pinctrl_drv_data *drvdata;
 
-	pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
+	drvdata = dev_get_drvdata(gc->dev);
+
+	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
 	data &= ~(1 << pin_offset);
 	if (value)
@@ -484,8 +488,11 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 {
 	void __iomem *reg;
 	u32 pin_offset, data;
+	struct samsung_pinctrl_drv_data *drvdata;
+
+	drvdata = dev_get_drvdata(gc->dev);
 
-	pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
+	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
 	data >>= pin_offset;
 	data &= 1;
-- 
1.7.12

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

* [PATCH 10/16] pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

The pointer to gpio_chip passed to pin_to_reg_bank utility function is
used only to retrieve a pointer to samsung_pinctrl_drv_data structure.

This patch modifies the function and its users to pass a pointer to
samsung_pinctrl_drv_data directly.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 6ae82d5..e63a365 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -252,14 +252,12 @@ static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
  * given a pin number that is local to a pin controller, find out the pin bank
  * and the register base of the pin bank.
  */
-static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin,
-			void __iomem **reg, u32 *offset,
+static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
+			unsigned pin, void __iomem **reg, u32 *offset,
 			struct samsung_pin_bank **bank)
 {
-	struct samsung_pinctrl_drv_data *drvdata;
 	struct samsung_pin_bank *b;
 
-	drvdata = dev_get_drvdata(gc->dev);
 	b = drvdata->ctrl->pin_banks;
 
 	while ((pin >= b->pin_base) &&
@@ -294,7 +292,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
 	 * pin function number in the config register.
 	 */
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
-		pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base,
+		pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
 				&reg, &pin_offset, &bank);
 		mask = (1 << bank->func_width) - 1;
 		shift = pin_offset * bank->func_width;
@@ -331,10 +329,13 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 		struct pinctrl_gpio_range *range, unsigned offset, bool input)
 {
 	struct samsung_pin_bank *bank;
+	struct samsung_pinctrl_drv_data *drvdata;
 	void __iomem *reg;
 	u32 data, pin_offset, mask, shift;
 
-	pin_to_reg_bank(range->gc, offset, &reg, &pin_offset, &bank);
+	drvdata = pinctrl_dev_get_drvdata(pctldev);
+
+	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, &bank);
 	mask = (1 << bank->func_width) - 1;
 	shift = pin_offset * bank->func_width;
 
@@ -368,7 +369,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 	u32 cfg_value, cfg_reg;
 
 	drvdata = pinctrl_dev_get_drvdata(pctldev);
-	pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, &reg_base,
+	pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, &reg_base,
 					&pin_offset, &bank);
 
 	switch (cfg_type) {
@@ -470,8 +471,11 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 {
 	void __iomem *reg;
 	u32 pin_offset, data;
+	struct samsung_pinctrl_drv_data *drvdata;
 
-	pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
+	drvdata = dev_get_drvdata(gc->dev);
+
+	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
 	data &= ~(1 << pin_offset);
 	if (value)
@@ -484,8 +488,11 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 {
 	void __iomem *reg;
 	u32 pin_offset, data;
+	struct samsung_pinctrl_drv_data *drvdata;
+
+	drvdata = dev_get_drvdata(gc->dev);
 
-	pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
+	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
 	data >>= pin_offset;
 	data &= 1;
-- 
1.7.12

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

* [PATCH 11/16] pinctrl: samsung: Use one GPIO chip per pin bank
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

This patch modifies the pinctrl-samsung driver to register one GPIO chip
per pin bank, instead of a single chip for all pin banks of the
controller.

It simplifies GPIO accesses a lot (constant time instead of looping
through the list of banks to find the right one) and should have a good
effect on performance of any bit-banging driver.

In addition it allows to reference GPIO pins by a phandle to the bank
node and a local pin offset inside of the bank (similar to previous
gpiolib driver), which is more clear and readable than using indices
relative to the whole pin controller.

Example:
	device {
		/* ... */
		gpios = <&gpk0 4 0>;
		/* ... */
	};

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 119 ++++++++++++++++++++++++--------------
 drivers/pinctrl/pinctrl-samsung.h |  12 ++--
 2 files changed, 81 insertions(+), 50 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index e63a365..4ffd14c 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -48,6 +48,11 @@ struct pin_config {
 
 static unsigned int pin_base = 0;
 
+static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
+{
+	return container_of(gc, struct samsung_pin_bank, gpio_chip);
+}
+
 /* check if the selector is a valid pin group selector */
 static int samsung_get_group_count(struct pinctrl_dev *pctldev)
 {
@@ -333,9 +338,12 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 	void __iomem *reg;
 	u32 data, pin_offset, mask, shift;
 
+	bank = gc_to_pin_bank(range->gc);
 	drvdata = pinctrl_dev_get_drvdata(pctldev);
 
-	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, &bank);
+	pin_offset = offset - bank->pin_base;
+	reg = drvdata->virt_base + bank->pctl_offset;
+
 	mask = (1 << bank->func_width) - 1;
 	shift = pin_offset * bank->func_width;
 
@@ -469,17 +477,16 @@ static struct pinconf_ops samsung_pinconf_ops = {
 /* gpiolib gpio_set callback function */
 static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 {
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 	void __iomem *reg;
-	u32 pin_offset, data;
-	struct samsung_pinctrl_drv_data *drvdata;
+	u32 data;
 
-	drvdata = dev_get_drvdata(gc->dev);
+	reg = bank->drvdata->virt_base + bank->pctl_offset;
 
-	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
-	data &= ~(1 << pin_offset);
+	data &= ~(1 << offset);
 	if (value)
-		data |= 1 << pin_offset;
+		data |= 1 << offset;
 	writel(data, reg + DAT_REG);
 }
 
@@ -487,14 +494,13 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 {
 	void __iomem *reg;
-	u32 pin_offset, data;
-	struct samsung_pinctrl_drv_data *drvdata;
+	u32 data;
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 
-	drvdata = dev_get_drvdata(gc->dev);
+	reg = bank->drvdata->virt_base + bank->pctl_offset;
 
-	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
-	data >>= pin_offset;
+	data >>= offset;
 	data &= 1;
 	return data;
 }
@@ -726,12 +732,16 @@ static int __init samsung_pinctrl_register(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
-	drvdata->grange.name = "samsung-pctrl-gpio-range";
-	drvdata->grange.id = 0;
-	drvdata->grange.base = drvdata->ctrl->base;
-	drvdata->grange.npins = drvdata->ctrl->nr_pins;
-	drvdata->grange.gc = drvdata->gc;
-	pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange);
+	for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) {
+		pin_bank = &drvdata->ctrl->pin_banks[bank];
+		pin_bank->grange.name = pin_bank->name;
+		pin_bank->grange.id = bank;
+		pin_bank->grange.pin_base = pin_bank->pin_base;
+		pin_bank->grange.base = pin_bank->gpio_chip.base;
+		pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
+		pin_bank->grange.gc = &pin_bank->gpio_chip;
+		pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange);
+	}
 
 	ret = samsung_pinctrl_parse_dt(pdev, drvdata);
 	if (ret) {
@@ -742,49 +752,68 @@ static int __init samsung_pinctrl_register(struct platform_device *pdev,
 	return 0;
 }
 
+static const struct gpio_chip samsung_gpiolib_chip = {
+	.set = samsung_gpio_set,
+	.get = samsung_gpio_get,
+	.direction_input = samsung_gpio_direction_input,
+	.direction_output = samsung_gpio_direction_output,
+	.owner = THIS_MODULE,
+};
+
 /* register the gpiolib interface with the gpiolib subsystem */
 static int __init samsung_gpiolib_register(struct platform_device *pdev,
 				struct samsung_pinctrl_drv_data *drvdata)
 {
+	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+	struct samsung_pin_bank *bank = ctrl->pin_banks;
 	struct gpio_chip *gc;
 	int ret;
-
-	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
-	if (!gc) {
-		dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
-		return -ENOMEM;
-	}
-
-	drvdata->gc = gc;
-	gc->base = drvdata->ctrl->base;
-	gc->ngpio = drvdata->ctrl->nr_pins;
-	gc->dev = &pdev->dev;
-	gc->set = samsung_gpio_set;
-	gc->get = samsung_gpio_get;
-	gc->direction_input = samsung_gpio_direction_input;
-	gc->direction_output = samsung_gpio_direction_output;
-	gc->label = drvdata->ctrl->label;
-	gc->owner = THIS_MODULE;
-	ret = gpiochip_add(gc);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
-					"code: %d\n", gc->label, ret);
-		return ret;
+	int i;
+
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		bank->gpio_chip = samsung_gpiolib_chip;
+
+		gc = &bank->gpio_chip;
+		gc->base = ctrl->base + bank->pin_base;
+		gc->ngpio = bank->nr_pins;
+		gc->dev = &pdev->dev;
+		gc->of_node = bank->of_node;
+		gc->label = bank->name;
+
+		ret = gpiochip_add(gc);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
+							gc->label, ret);
+			goto fail;
+		}
 	}
 
 	return 0;
+
+fail:
+	for (--i, --bank; i >= 0; --i, --bank)
+		if (gpiochip_remove(&bank->gpio_chip))
+			dev_err(&pdev->dev, "gpio chip %s remove failed\n",
+							bank->gpio_chip.label);
+	return ret;
 }
 
 /* unregister the gpiolib interface with the gpiolib subsystem */
 static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
 				struct samsung_pinctrl_drv_data *drvdata)
 {
-	int ret = gpiochip_remove(drvdata->gc);
-	if (ret) {
+	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+	struct samsung_pin_bank *bank = ctrl->pin_banks;
+	int ret = 0;
+	int i;
+
+	for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank)
+		ret = gpiochip_remove(&bank->gpio_chip);
+
+	if (ret)
 		dev_err(&pdev->dev, "gpio chip remove failed\n");
-		return ret;
-	}
-	return 0;
+
+	return ret;
 }
 
 static const struct of_device_id samsung_pinctrl_dt_match[];
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 470e11b..f27b1e0 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -23,6 +23,8 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/machine.h>
 
+#include <linux/gpio.h>
+
 /* register offsets within a pin bank */
 #define DAT_REG		0x4
 #define PUD_REG		0x8
@@ -113,6 +115,8 @@ struct samsung_pinctrl_drv_data;
  * @of_node: node of pin bank in device tree
  * @drvdata: link to controller driver data
  * @irq_domain: IRQ domain of the bank.
+ * @gpio_chip: GPIO chip of the bank.
+ * @grange: linux gpio pin range supported by this bank.
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -130,6 +134,9 @@ struct samsung_pin_bank {
 	struct device_node *of_node;
 	struct samsung_pinctrl_drv_data *drvdata;
 	struct irq_domain *irq_domain;
+
+	struct gpio_chip gpio_chip;
+	struct pinctrl_gpio_range grange;
 };
 
 /**
@@ -199,8 +206,6 @@ struct samsung_pin_ctrl {
  * @nr_groups: number of such pin groups.
  * @pmx_functions: list of pin functions available to the driver.
  * @nr_function: number of such pin functions.
- * @gc: gpio_chip instance registered with gpiolib.
- * @grange: linux gpio pin range supported by this controller.
  */
 struct samsung_pinctrl_drv_data {
 	void __iomem			*virt_base;
@@ -217,9 +222,6 @@ struct samsung_pinctrl_drv_data {
 	unsigned int			nr_functions;
 
 	struct irq_domain		*wkup_irqd;
-
-	struct gpio_chip		*gc;
-	struct pinctrl_gpio_range	grange;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 11/16] pinctrl: samsung: Use one GPIO chip per pin bank
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modifies the pinctrl-samsung driver to register one GPIO chip
per pin bank, instead of a single chip for all pin banks of the
controller.

It simplifies GPIO accesses a lot (constant time instead of looping
through the list of banks to find the right one) and should have a good
effect on performance of any bit-banging driver.

In addition it allows to reference GPIO pins by a phandle to the bank
node and a local pin offset inside of the bank (similar to previous
gpiolib driver), which is more clear and readable than using indices
relative to the whole pin controller.

Example:
	device {
		/* ... */
		gpios = <&gpk0 4 0>;
		/* ... */
	};

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 119 ++++++++++++++++++++++++--------------
 drivers/pinctrl/pinctrl-samsung.h |  12 ++--
 2 files changed, 81 insertions(+), 50 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index e63a365..4ffd14c 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -48,6 +48,11 @@ struct pin_config {
 
 static unsigned int pin_base = 0;
 
+static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
+{
+	return container_of(gc, struct samsung_pin_bank, gpio_chip);
+}
+
 /* check if the selector is a valid pin group selector */
 static int samsung_get_group_count(struct pinctrl_dev *pctldev)
 {
@@ -333,9 +338,12 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 	void __iomem *reg;
 	u32 data, pin_offset, mask, shift;
 
+	bank = gc_to_pin_bank(range->gc);
 	drvdata = pinctrl_dev_get_drvdata(pctldev);
 
-	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, &bank);
+	pin_offset = offset - bank->pin_base;
+	reg = drvdata->virt_base + bank->pctl_offset;
+
 	mask = (1 << bank->func_width) - 1;
 	shift = pin_offset * bank->func_width;
 
@@ -469,17 +477,16 @@ static struct pinconf_ops samsung_pinconf_ops = {
 /* gpiolib gpio_set callback function */
 static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 {
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 	void __iomem *reg;
-	u32 pin_offset, data;
-	struct samsung_pinctrl_drv_data *drvdata;
+	u32 data;
 
-	drvdata = dev_get_drvdata(gc->dev);
+	reg = bank->drvdata->virt_base + bank->pctl_offset;
 
-	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
-	data &= ~(1 << pin_offset);
+	data &= ~(1 << offset);
 	if (value)
-		data |= 1 << pin_offset;
+		data |= 1 << offset;
 	writel(data, reg + DAT_REG);
 }
 
@@ -487,14 +494,13 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 {
 	void __iomem *reg;
-	u32 pin_offset, data;
-	struct samsung_pinctrl_drv_data *drvdata;
+	u32 data;
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 
-	drvdata = dev_get_drvdata(gc->dev);
+	reg = bank->drvdata->virt_base + bank->pctl_offset;
 
-	pin_to_reg_bank(drvdata, offset, &reg, &pin_offset, NULL);
 	data = readl(reg + DAT_REG);
-	data >>= pin_offset;
+	data >>= offset;
 	data &= 1;
 	return data;
 }
@@ -726,12 +732,16 @@ static int __init samsung_pinctrl_register(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
-	drvdata->grange.name = "samsung-pctrl-gpio-range";
-	drvdata->grange.id = 0;
-	drvdata->grange.base = drvdata->ctrl->base;
-	drvdata->grange.npins = drvdata->ctrl->nr_pins;
-	drvdata->grange.gc = drvdata->gc;
-	pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange);
+	for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) {
+		pin_bank = &drvdata->ctrl->pin_banks[bank];
+		pin_bank->grange.name = pin_bank->name;
+		pin_bank->grange.id = bank;
+		pin_bank->grange.pin_base = pin_bank->pin_base;
+		pin_bank->grange.base = pin_bank->gpio_chip.base;
+		pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
+		pin_bank->grange.gc = &pin_bank->gpio_chip;
+		pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange);
+	}
 
 	ret = samsung_pinctrl_parse_dt(pdev, drvdata);
 	if (ret) {
@@ -742,49 +752,68 @@ static int __init samsung_pinctrl_register(struct platform_device *pdev,
 	return 0;
 }
 
+static const struct gpio_chip samsung_gpiolib_chip = {
+	.set = samsung_gpio_set,
+	.get = samsung_gpio_get,
+	.direction_input = samsung_gpio_direction_input,
+	.direction_output = samsung_gpio_direction_output,
+	.owner = THIS_MODULE,
+};
+
 /* register the gpiolib interface with the gpiolib subsystem */
 static int __init samsung_gpiolib_register(struct platform_device *pdev,
 				struct samsung_pinctrl_drv_data *drvdata)
 {
+	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+	struct samsung_pin_bank *bank = ctrl->pin_banks;
 	struct gpio_chip *gc;
 	int ret;
-
-	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
-	if (!gc) {
-		dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
-		return -ENOMEM;
-	}
-
-	drvdata->gc = gc;
-	gc->base = drvdata->ctrl->base;
-	gc->ngpio = drvdata->ctrl->nr_pins;
-	gc->dev = &pdev->dev;
-	gc->set = samsung_gpio_set;
-	gc->get = samsung_gpio_get;
-	gc->direction_input = samsung_gpio_direction_input;
-	gc->direction_output = samsung_gpio_direction_output;
-	gc->label = drvdata->ctrl->label;
-	gc->owner = THIS_MODULE;
-	ret = gpiochip_add(gc);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
-					"code: %d\n", gc->label, ret);
-		return ret;
+	int i;
+
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		bank->gpio_chip = samsung_gpiolib_chip;
+
+		gc = &bank->gpio_chip;
+		gc->base = ctrl->base + bank->pin_base;
+		gc->ngpio = bank->nr_pins;
+		gc->dev = &pdev->dev;
+		gc->of_node = bank->of_node;
+		gc->label = bank->name;
+
+		ret = gpiochip_add(gc);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
+							gc->label, ret);
+			goto fail;
+		}
 	}
 
 	return 0;
+
+fail:
+	for (--i, --bank; i >= 0; --i, --bank)
+		if (gpiochip_remove(&bank->gpio_chip))
+			dev_err(&pdev->dev, "gpio chip %s remove failed\n",
+							bank->gpio_chip.label);
+	return ret;
 }
 
 /* unregister the gpiolib interface with the gpiolib subsystem */
 static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
 				struct samsung_pinctrl_drv_data *drvdata)
 {
-	int ret = gpiochip_remove(drvdata->gc);
-	if (ret) {
+	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+	struct samsung_pin_bank *bank = ctrl->pin_banks;
+	int ret = 0;
+	int i;
+
+	for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank)
+		ret = gpiochip_remove(&bank->gpio_chip);
+
+	if (ret)
 		dev_err(&pdev->dev, "gpio chip remove failed\n");
-		return ret;
-	}
-	return 0;
+
+	return ret;
 }
 
 static const struct of_device_id samsung_pinctrl_dt_match[];
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 470e11b..f27b1e0 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -23,6 +23,8 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/machine.h>
 
+#include <linux/gpio.h>
+
 /* register offsets within a pin bank */
 #define DAT_REG		0x4
 #define PUD_REG		0x8
@@ -113,6 +115,8 @@ struct samsung_pinctrl_drv_data;
  * @of_node: node of pin bank in device tree
  * @drvdata: link to controller driver data
  * @irq_domain: IRQ domain of the bank.
+ * @gpio_chip: GPIO chip of the bank.
+ * @grange: linux gpio pin range supported by this bank.
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -130,6 +134,9 @@ struct samsung_pin_bank {
 	struct device_node *of_node;
 	struct samsung_pinctrl_drv_data *drvdata;
 	struct irq_domain *irq_domain;
+
+	struct gpio_chip gpio_chip;
+	struct pinctrl_gpio_range grange;
 };
 
 /**
@@ -199,8 +206,6 @@ struct samsung_pin_ctrl {
  * @nr_groups: number of such pin groups.
  * @pmx_functions: list of pin functions available to the driver.
  * @nr_function: number of such pin functions.
- * @gc: gpio_chip instance registered with gpiolib.
- * @grange: linux gpio pin range supported by this controller.
  */
 struct samsung_pinctrl_drv_data {
 	void __iomem			*virt_base;
@@ -217,9 +222,6 @@ struct samsung_pinctrl_drv_data {
 	unsigned int			nr_functions;
 
 	struct irq_domain		*wkup_irqd;
-
-	struct gpio_chip		*gc;
-	struct pinctrl_gpio_range	grange;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 12/16] pinctrl: samsung: Use per-bank IRQ domain for wake-up interrupts
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

This patch reworks wake-up interrupt handling in pinctrl-exynos driver,
so each pin bank, which provides wake-up interrupts, has its own IRQ
domain.

Information about whether given pin bank provides wake-up interrupts,
how many and whether they are separate or muxed are parsed from device
tree.

It gives following advantages:
  - interrupts can be specified in device tree in a more readable way,
    e.g. :
    	device {
		/* ... */
		interrupt-parent = <&gpx2>;
		interrupts = <4 0>;
		/* ... */
	};
  - the amount and layout of interrupts is not hardcoded in the driver
    anymore
  - bank and pin of each wake-up interrupt can be easily identified, to
    allow operations, such as setting the pin to EINT function, from
    irq_set_type() callback

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 159 +++++++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-exynos.h  |  17 +++-
 drivers/pinctrl/pinctrl-samsung.c |   9 ++-
 drivers/pinctrl/pinctrl-samsung.h |   6 +-
 4 files changed, 119 insertions(+), 72 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 53ed5d9..fa6a5be 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -218,46 +218,43 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 
 static void exynos_wkup_irq_unmask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << pin);
+	mask &= ~(1 << irqd->hwirq);
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_wkup_irq_mask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << pin;
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_wkup_irq_ack(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long pend = d->ctrl->weint_pend + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
 
-	writel(1 << pin, d->virt_base + pend);
+	writel(1 << irqd->hwirq, d->virt_base + pend);
 }
 
 static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_con = d->ctrl->weint_con + (bank << 2);
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned int pin = irqd->hwirq;
+	unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
 	unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned long con, trig_type;
 
@@ -309,6 +306,7 @@ static struct irq_chip exynos_wkup_irq_chip = {
 static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
 {
 	struct exynos_weint_data *eintd = irq_get_handler_data(irq);
+	struct samsung_pin_bank *bank = eintd->bank;
 	struct irq_chip *chip = irq_get_chip(irq);
 	int eint_irq;
 
@@ -318,20 +316,20 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
 	if (chip->irq_ack)
 		chip->irq_ack(&desc->irq_data);
 
-	eint_irq = irq_linear_revmap(eintd->domain, eintd->irq);
+	eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
 	generic_handle_irq(eint_irq);
 	chip->irq_unmask(&desc->irq_data);
 	chained_irq_exit(chip, desc);
 }
 
-static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend,
-					struct irq_domain *domain)
+static inline void exynos_irq_demux_eint(unsigned long pend,
+						struct irq_domain *domain)
 {
 	unsigned int irq;
 
 	while (pend) {
 		irq = fls(pend) - 1;
-		generic_handle_irq(irq_find_mapping(domain, irq_base + irq));
+		generic_handle_irq(irq_find_mapping(domain, irq));
 		pend &= ~(1 << irq);
 	}
 }
@@ -340,18 +338,22 @@ static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend,
 static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_get_chip(irq);
-	struct exynos_weint_data *eintd = irq_get_handler_data(irq);
-	struct samsung_pinctrl_drv_data *d = eintd->domain->host_data;
+	struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
+	struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
+	struct samsung_pin_ctrl *ctrl = d->ctrl;
 	unsigned long pend;
 	unsigned long mask;
+	int i;
 
 	chained_irq_enter(chip, desc);
-	pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8);
-	mask = readl(d->virt_base + d->ctrl->weint_mask + 0x8);
-	exynos_irq_demux_eint(16, pend & ~mask, eintd->domain);
-	pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC);
-	mask = readl(d->virt_base + d->ctrl->weint_mask + 0xC);
-	exynos_irq_demux_eint(24, pend & ~mask, eintd->domain);
+
+	for (i = 0; i < eintd->nr_banks; ++i) {
+		struct samsung_pin_bank *b = eintd->banks[i];
+		pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
+		mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
+		exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
+	}
+
 	chained_irq_exit(chip, desc);
 }
 
@@ -381,7 +383,11 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	struct device *dev = d->dev;
 	struct device_node *wkup_np = NULL;
 	struct device_node *np;
+	struct samsung_pin_bank *bank;
 	struct exynos_weint_data *weint_data;
+	struct exynos_muxed_weint_data *muxed_data;
+	unsigned int muxed_banks = 0;
+	unsigned int i;
 	int idx, irq;
 	u32 val;
 	int ret;
@@ -395,11 +401,6 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	if (!wkup_np)
 		return -ENODEV;
 
-	ret = of_property_read_u32(wkup_np, "samsung,weint-count", &val);
-	if (ret)
-		return -EINVAL;
-	d->ctrl->nr_wint = val;
-
 	ret = of_property_read_u32(wkup_np, "samsung,weint-con", &val);
 	if (ret)
 		return -EINVAL;
@@ -415,40 +416,74 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 		return -EINVAL;
 	d->ctrl->weint_pend = val;
 
-	d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint,
-				&exynos_wkup_irqd_ops, d);
-	if (!d->wkup_irqd) {
-		dev_err(dev, "wakeup irq domain allocation failed\n");
-		return -ENXIO;
-	}
+	bank = d->ctrl->pin_banks;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_WKUP)
+			continue;
 
-	weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL);
-	if (!weint_data) {
-		dev_err(dev, "could not allocate memory for weint_data\n");
-		return -ENOMEM;
-	}
+		bank->irq_domain = irq_domain_add_linear(bank->of_node,
+				bank->nr_pins, &exynos_wkup_irqd_ops, bank);
+		if (!bank->irq_domain) {
+			dev_err(dev, "wkup irq domain add failed\n");
+			return -ENXIO;
+		}
 
-	irq = irq_of_parse_and_map(wkup_np, 16);
-	if (irq) {
-		weint_data[16].domain = d->wkup_irqd;
-		irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
-		irq_set_handler_data(irq, &weint_data[16]);
-	} else {
-		dev_err(dev, "irq number for EINT16-32 not found\n");
-	}
+		if (!of_find_property(bank->of_node, "interrupts", NULL)) {
+			bank->eint_type = EINT_TYPE_WKUP_MUX;
+			++muxed_banks;
+			continue;
+		}
 
-	for (idx = 0; idx < 16; idx++) {
-		weint_data[idx].domain = d->wkup_irqd;
-		weint_data[idx].irq = idx;
+		weint_data = devm_kzalloc(dev, bank->nr_pins
+					* sizeof(*weint_data), GFP_KERNEL);
+		if (!weint_data) {
+			dev_err(dev, "could not allocate memory for weint_data\n");
+			return -ENOMEM;
+		}
 
-		irq = irq_of_parse_and_map(wkup_np, idx);
-		if (irq) {
+		for (idx = 0; idx < bank->nr_pins; ++idx) {
+			irq = irq_of_parse_and_map(bank->of_node, idx);
+			if (!irq) {
+				dev_err(dev, "irq number for eint-%s-%d not found\n",
+							bank->name, idx);
+				continue;
+			}
+			weint_data[idx].irq = idx;
+			weint_data[idx].bank = bank;
 			irq_set_handler_data(irq, &weint_data[idx]);
 			irq_set_chained_handler(irq, exynos_irq_eint0_15);
-		} else {
-			dev_err(dev, "irq number for eint-%x not found\n", idx);
 		}
 	}
+
+	if (!muxed_banks)
+		return 0;
+
+	irq = irq_of_parse_and_map(wkup_np, 0);
+	if (!irq) {
+		dev_err(dev, "irq number for muxed EINTs not found\n");
+		return 0;
+	}
+
+	muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
+		+ muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
+	if (!muxed_data) {
+		dev_err(dev, "could not allocate memory for muxed_data\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
+	irq_set_handler_data(irq, muxed_data);
+
+	bank = d->ctrl->pin_banks;
+	idx = 0;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_WKUP_MUX)
+			continue;
+
+		muxed_data->banks[idx++] = bank;
+	}
+	muxed_data->nr_banks = muxed_banks;
+
 	return 0;
 }
 
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index 30aca2b..a94d6fc 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -40,10 +40,21 @@
 /**
  * struct exynos_weint_data: irq specific data for all the wakeup interrupts
  * generated by the external wakeup interrupt controller.
- * @domain: irq domain representing the external wakeup interrupts
  * @irq: interrupt number within the domain.
+ * @bank: bank responsible for this interrupt
  */
 struct exynos_weint_data {
-	struct irq_domain	*domain;
-	u32			irq;
+	unsigned int irq;
+	struct samsung_pin_bank *bank;
+};
+
+/**
+ * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts
+ * generated by the external wakeup interrupt controller.
+ * @nr_banks: count of banks being part of the mux
+ * @banks: array of banks being part of the mux
+ */
+struct exynos_muxed_weint_data {
+	unsigned int nr_banks;
+	struct samsung_pin_bank *banks[];
 };
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 4ffd14c..215a7e5 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -615,10 +615,10 @@ static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
 	 */
 	for_each_child_of_node(dev_np, cfg_np) {
 		u32 function;
-		if (of_find_property(cfg_np, "interrupt-controller", NULL))
-			continue;
 		if (of_find_property(cfg_np, "gpio-controller", NULL))
 			continue;
+		if (of_find_property(cfg_np, "compatible", NULL))
+			continue;
 
 		ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
 					&drvdata->pctl,	&pin_list, &npins);
@@ -894,7 +894,10 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 		return 0;
 	}
 
-	bank->eint_type = EINT_TYPE_GPIO;
+	if (of_find_property(np, "samsung,wkup-eint", NULL))
+		bank->eint_type = EINT_TYPE_WKUP;
+	else
+		bank->eint_type = EINT_TYPE_GPIO;
 
 	ret = of_property_read_u32(np, "samsung,eint-offset", &val);
 	if (ret)
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index f27b1e0..355f4e2 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -66,6 +66,7 @@ enum pincfg_type {
  * @EINT_TYPE_NONE: bank does not support external interrupts
  * @EINT_TYPE_GPIO: bank supportes external gpio interrupts
  * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts
+ * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts
  *
  * Samsung GPIO controller groups all the available pins into banks. The pins
  * in a pin bank can support external gpio interrupts or external wakeup
@@ -78,6 +79,7 @@ enum eint_type {
 	EINT_TYPE_NONE,
 	EINT_TYPE_GPIO,
 	EINT_TYPE_WKUP,
+	EINT_TYPE_WKUP_MUX,
 };
 
 /* maximum length of a pin in pin descriptor (example: "gpa0-0") */
@@ -157,7 +159,6 @@ struct samsung_pin_ctrl_variant {
  * @nr_banks: number of pin banks.
  * @base: starting system wide pin number.
  * @nr_pins: number of pins supported by the controller.
- * @nr_wint: number of external wakeup interrupts supported.
  * @geint_con: offset of the ext-gpio controller registers.
  * @geint_mask: offset of the ext-gpio interrupt mask registers.
  * @geint_pend: offset of the ext-gpio interrupt pending registers.
@@ -177,7 +178,6 @@ struct samsung_pin_ctrl {
 
 	u32		base;
 	u32		nr_pins;
-	u32		nr_wint;
 
 	u32		geint_con;
 	u32		geint_mask;
@@ -220,8 +220,6 @@ struct samsung_pinctrl_drv_data {
 	unsigned int			nr_groups;
 	const struct samsung_pmx_func	*pmx_functions;
 	unsigned int			nr_functions;
-
-	struct irq_domain		*wkup_irqd;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 12/16] pinctrl: samsung: Use per-bank IRQ domain for wake-up interrupts
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

This patch reworks wake-up interrupt handling in pinctrl-exynos driver,
so each pin bank, which provides wake-up interrupts, has its own IRQ
domain.

Information about whether given pin bank provides wake-up interrupts,
how many and whether they are separate or muxed are parsed from device
tree.

It gives following advantages:
  - interrupts can be specified in device tree in a more readable way,
    e.g. :
    	device {
		/* ... */
		interrupt-parent = <&gpx2>;
		interrupts = <4 0>;
		/* ... */
	};
  - the amount and layout of interrupts is not hardcoded in the driver
    anymore
  - bank and pin of each wake-up interrupt can be easily identified, to
    allow operations, such as setting the pin to EINT function, from
    irq_set_type() callback

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 159 +++++++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-exynos.h  |  17 +++-
 drivers/pinctrl/pinctrl-samsung.c |   9 ++-
 drivers/pinctrl/pinctrl-samsung.h |   6 +-
 4 files changed, 119 insertions(+), 72 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 53ed5d9..fa6a5be 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -218,46 +218,43 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 
 static void exynos_wkup_irq_unmask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << pin);
+	mask &= ~(1 << irqd->hwirq);
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_wkup_irq_mask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << pin;
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_wkup_irq_ack(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long pend = d->ctrl->weint_pend + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
 
-	writel(1 << pin, d->virt_base + pend);
+	writel(1 << irqd->hwirq, d->virt_base + pend);
 }
 
 static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_con = d->ctrl->weint_con + (bank << 2);
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned int pin = irqd->hwirq;
+	unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
 	unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned long con, trig_type;
 
@@ -309,6 +306,7 @@ static struct irq_chip exynos_wkup_irq_chip = {
 static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
 {
 	struct exynos_weint_data *eintd = irq_get_handler_data(irq);
+	struct samsung_pin_bank *bank = eintd->bank;
 	struct irq_chip *chip = irq_get_chip(irq);
 	int eint_irq;
 
@@ -318,20 +316,20 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
 	if (chip->irq_ack)
 		chip->irq_ack(&desc->irq_data);
 
-	eint_irq = irq_linear_revmap(eintd->domain, eintd->irq);
+	eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
 	generic_handle_irq(eint_irq);
 	chip->irq_unmask(&desc->irq_data);
 	chained_irq_exit(chip, desc);
 }
 
-static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend,
-					struct irq_domain *domain)
+static inline void exynos_irq_demux_eint(unsigned long pend,
+						struct irq_domain *domain)
 {
 	unsigned int irq;
 
 	while (pend) {
 		irq = fls(pend) - 1;
-		generic_handle_irq(irq_find_mapping(domain, irq_base + irq));
+		generic_handle_irq(irq_find_mapping(domain, irq));
 		pend &= ~(1 << irq);
 	}
 }
@@ -340,18 +338,22 @@ static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend,
 static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_get_chip(irq);
-	struct exynos_weint_data *eintd = irq_get_handler_data(irq);
-	struct samsung_pinctrl_drv_data *d = eintd->domain->host_data;
+	struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
+	struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
+	struct samsung_pin_ctrl *ctrl = d->ctrl;
 	unsigned long pend;
 	unsigned long mask;
+	int i;
 
 	chained_irq_enter(chip, desc);
-	pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8);
-	mask = readl(d->virt_base + d->ctrl->weint_mask + 0x8);
-	exynos_irq_demux_eint(16, pend & ~mask, eintd->domain);
-	pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC);
-	mask = readl(d->virt_base + d->ctrl->weint_mask + 0xC);
-	exynos_irq_demux_eint(24, pend & ~mask, eintd->domain);
+
+	for (i = 0; i < eintd->nr_banks; ++i) {
+		struct samsung_pin_bank *b = eintd->banks[i];
+		pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
+		mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
+		exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
+	}
+
 	chained_irq_exit(chip, desc);
 }
 
@@ -381,7 +383,11 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	struct device *dev = d->dev;
 	struct device_node *wkup_np = NULL;
 	struct device_node *np;
+	struct samsung_pin_bank *bank;
 	struct exynos_weint_data *weint_data;
+	struct exynos_muxed_weint_data *muxed_data;
+	unsigned int muxed_banks = 0;
+	unsigned int i;
 	int idx, irq;
 	u32 val;
 	int ret;
@@ -395,11 +401,6 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	if (!wkup_np)
 		return -ENODEV;
 
-	ret = of_property_read_u32(wkup_np, "samsung,weint-count", &val);
-	if (ret)
-		return -EINVAL;
-	d->ctrl->nr_wint = val;
-
 	ret = of_property_read_u32(wkup_np, "samsung,weint-con", &val);
 	if (ret)
 		return -EINVAL;
@@ -415,40 +416,74 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 		return -EINVAL;
 	d->ctrl->weint_pend = val;
 
-	d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint,
-				&exynos_wkup_irqd_ops, d);
-	if (!d->wkup_irqd) {
-		dev_err(dev, "wakeup irq domain allocation failed\n");
-		return -ENXIO;
-	}
+	bank = d->ctrl->pin_banks;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_WKUP)
+			continue;
 
-	weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL);
-	if (!weint_data) {
-		dev_err(dev, "could not allocate memory for weint_data\n");
-		return -ENOMEM;
-	}
+		bank->irq_domain = irq_domain_add_linear(bank->of_node,
+				bank->nr_pins, &exynos_wkup_irqd_ops, bank);
+		if (!bank->irq_domain) {
+			dev_err(dev, "wkup irq domain add failed\n");
+			return -ENXIO;
+		}
 
-	irq = irq_of_parse_and_map(wkup_np, 16);
-	if (irq) {
-		weint_data[16].domain = d->wkup_irqd;
-		irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
-		irq_set_handler_data(irq, &weint_data[16]);
-	} else {
-		dev_err(dev, "irq number for EINT16-32 not found\n");
-	}
+		if (!of_find_property(bank->of_node, "interrupts", NULL)) {
+			bank->eint_type = EINT_TYPE_WKUP_MUX;
+			++muxed_banks;
+			continue;
+		}
 
-	for (idx = 0; idx < 16; idx++) {
-		weint_data[idx].domain = d->wkup_irqd;
-		weint_data[idx].irq = idx;
+		weint_data = devm_kzalloc(dev, bank->nr_pins
+					* sizeof(*weint_data), GFP_KERNEL);
+		if (!weint_data) {
+			dev_err(dev, "could not allocate memory for weint_data\n");
+			return -ENOMEM;
+		}
 
-		irq = irq_of_parse_and_map(wkup_np, idx);
-		if (irq) {
+		for (idx = 0; idx < bank->nr_pins; ++idx) {
+			irq = irq_of_parse_and_map(bank->of_node, idx);
+			if (!irq) {
+				dev_err(dev, "irq number for eint-%s-%d not found\n",
+							bank->name, idx);
+				continue;
+			}
+			weint_data[idx].irq = idx;
+			weint_data[idx].bank = bank;
 			irq_set_handler_data(irq, &weint_data[idx]);
 			irq_set_chained_handler(irq, exynos_irq_eint0_15);
-		} else {
-			dev_err(dev, "irq number for eint-%x not found\n", idx);
 		}
 	}
+
+	if (!muxed_banks)
+		return 0;
+
+	irq = irq_of_parse_and_map(wkup_np, 0);
+	if (!irq) {
+		dev_err(dev, "irq number for muxed EINTs not found\n");
+		return 0;
+	}
+
+	muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
+		+ muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
+	if (!muxed_data) {
+		dev_err(dev, "could not allocate memory for muxed_data\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
+	irq_set_handler_data(irq, muxed_data);
+
+	bank = d->ctrl->pin_banks;
+	idx = 0;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_WKUP_MUX)
+			continue;
+
+		muxed_data->banks[idx++] = bank;
+	}
+	muxed_data->nr_banks = muxed_banks;
+
 	return 0;
 }
 
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index 30aca2b..a94d6fc 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -40,10 +40,21 @@
 /**
  * struct exynos_weint_data: irq specific data for all the wakeup interrupts
  * generated by the external wakeup interrupt controller.
- * @domain: irq domain representing the external wakeup interrupts
  * @irq: interrupt number within the domain.
+ * @bank: bank responsible for this interrupt
  */
 struct exynos_weint_data {
-	struct irq_domain	*domain;
-	u32			irq;
+	unsigned int irq;
+	struct samsung_pin_bank *bank;
+};
+
+/**
+ * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts
+ * generated by the external wakeup interrupt controller.
+ * @nr_banks: count of banks being part of the mux
+ * @banks: array of banks being part of the mux
+ */
+struct exynos_muxed_weint_data {
+	unsigned int nr_banks;
+	struct samsung_pin_bank *banks[];
 };
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 4ffd14c..215a7e5 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -615,10 +615,10 @@ static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
 	 */
 	for_each_child_of_node(dev_np, cfg_np) {
 		u32 function;
-		if (of_find_property(cfg_np, "interrupt-controller", NULL))
-			continue;
 		if (of_find_property(cfg_np, "gpio-controller", NULL))
 			continue;
+		if (of_find_property(cfg_np, "compatible", NULL))
+			continue;
 
 		ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
 					&drvdata->pctl,	&pin_list, &npins);
@@ -894,7 +894,10 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
 		return 0;
 	}
 
-	bank->eint_type = EINT_TYPE_GPIO;
+	if (of_find_property(np, "samsung,wkup-eint", NULL))
+		bank->eint_type = EINT_TYPE_WKUP;
+	else
+		bank->eint_type = EINT_TYPE_GPIO;
 
 	ret = of_property_read_u32(np, "samsung,eint-offset", &val);
 	if (ret)
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index f27b1e0..355f4e2 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -66,6 +66,7 @@ enum pincfg_type {
  * @EINT_TYPE_NONE: bank does not support external interrupts
  * @EINT_TYPE_GPIO: bank supportes external gpio interrupts
  * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts
+ * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts
  *
  * Samsung GPIO controller groups all the available pins into banks. The pins
  * in a pin bank can support external gpio interrupts or external wakeup
@@ -78,6 +79,7 @@ enum eint_type {
 	EINT_TYPE_NONE,
 	EINT_TYPE_GPIO,
 	EINT_TYPE_WKUP,
+	EINT_TYPE_WKUP_MUX,
 };
 
 /* maximum length of a pin in pin descriptor (example: "gpa0-0") */
@@ -157,7 +159,6 @@ struct samsung_pin_ctrl_variant {
  * @nr_banks: number of pin banks.
  * @base: starting system wide pin number.
  * @nr_pins: number of pins supported by the controller.
- * @nr_wint: number of external wakeup interrupts supported.
  * @geint_con: offset of the ext-gpio controller registers.
  * @geint_mask: offset of the ext-gpio interrupt mask registers.
  * @geint_pend: offset of the ext-gpio interrupt pending registers.
@@ -177,7 +178,6 @@ struct samsung_pin_ctrl {
 
 	u32		base;
 	u32		nr_pins;
-	u32		nr_wint;
 
 	u32		geint_con;
 	u32		geint_mask;
@@ -220,8 +220,6 @@ struct samsung_pinctrl_drv_data {
 	unsigned int			nr_groups;
 	const struct samsung_pmx_func	*pmx_functions;
 	unsigned int			nr_functions;
-
-	struct irq_domain		*wkup_irqd;
 };
 
 /**
-- 
1.7.12

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

* [PATCH 13/16] pinctrl: exynos: Set pin function to EINT in irq_set_type of wake-up EINT
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

Pins used as wake-up interrupts need to be configured as EINTs. This
patch adds the required configuration code to exynos_wkup_irq_set_type,
to set the pin as EINT when its interrupt trigger type is configured.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index fa6a5be..8cc8018 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -257,6 +257,7 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 	unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
 	unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned long con, trig_type;
+	unsigned int mask;
 
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -288,6 +289,16 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 	con &= ~(EXYNOS_EINT_CON_MASK << shift);
 	con |= trig_type << shift;
 	writel(con, d->virt_base + reg_con);
+
+	reg_con = bank->pctl_offset;
+	shift = pin * bank->func_width;
+	mask = (1 << bank->func_width) - 1;
+
+	con = readl(d->virt_base + reg_con);
+	con &= ~(mask << shift);
+	con |= EXYNOS_EINT_FUNC << shift;
+	writel(con, d->virt_base + reg_con);
+
 	return 0;
 }
 
-- 
1.7.12

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

* [PATCH 13/16] pinctrl: exynos: Set pin function to EINT in irq_set_type of wake-up EINT
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Pins used as wake-up interrupts need to be configured as EINTs. This
patch adds the required configuration code to exynos_wkup_irq_set_type,
to set the pin as EINT when its interrupt trigger type is configured.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index fa6a5be..8cc8018 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -257,6 +257,7 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 	unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
 	unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned long con, trig_type;
+	unsigned int mask;
 
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -288,6 +289,16 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 	con &= ~(EXYNOS_EINT_CON_MASK << shift);
 	con |= trig_type << shift;
 	writel(con, d->virt_base + reg_con);
+
+	reg_con = bank->pctl_offset;
+	shift = pin * bank->func_width;
+	mask = (1 << bank->func_width) - 1;
+
+	con = readl(d->virt_base + reg_con);
+	con &= ~(mask << shift);
+	con |= EXYNOS_EINT_FUNC << shift;
+	writel(con, d->virt_base + reg_con);
+
 	return 0;
 }
 
-- 
1.7.12

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

* [PATCH 14/16] pinctrl: samsung: Parse offsets of particular registers from DT
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

The order and availability of pin control registers vary with SoC.

This patch modifies the driver to parse register offsets from device
tree as a part of bank type definition.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 12 ++---
 drivers/pinctrl/pinctrl-samsung.c | 93 +++++++++++++++++++++------------------
 drivers/pinctrl/pinctrl-samsung.h | 38 +++++++++-------
 3 files changed, 78 insertions(+), 65 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 8cc8018..f264d69 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -113,9 +113,9 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 	con |= trig_type << shift;
 	writel(con, d->virt_base + reg_con);
 
-	reg_con = bank->pctl_offset;
-	shift = pin * bank->func_width;
-	mask = (1 << bank->func_width) - 1;
+	reg_con = bank->pctl_offset + bank->regs[REG_FUNC].offset;
+	shift = pin * bank->regs[REG_FUNC].width;
+	mask = (1 << bank->regs[REG_FUNC].width) - 1;
 
 	con = readl(d->virt_base + reg_con);
 	con &= ~(mask << shift);
@@ -290,9 +290,9 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 	con |= trig_type << shift;
 	writel(con, d->virt_base + reg_con);
 
-	reg_con = bank->pctl_offset;
-	shift = pin * bank->func_width;
-	mask = (1 << bank->func_width) - 1;
+	reg_con = bank->pctl_offset + bank->regs[REG_FUNC].offset;
+	shift = pin * bank->regs[REG_FUNC].width;
+	mask = (1 << bank->regs[REG_FUNC].width) - 1;
 
 	con = readl(d->virt_base + reg_con);
 	con &= ~(mask << shift);
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 215a7e5..495b226 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -273,10 +273,6 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
 	*offset = pin - b->pin_base;
 	if (bank)
 		*bank = b;
-
-	/* some banks have two config registers in a single bank */
-	if (*offset * b->func_width > BITS_PER_LONG)
-		*reg += 4;
 }
 
 /* enable or disable a pinmux function */
@@ -299,8 +295,9 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
 		pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
 				&reg, &pin_offset, &bank);
-		mask = (1 << bank->func_width) - 1;
-		shift = pin_offset * bank->func_width;
+		mask = (1 << bank->regs[REG_FUNC].width) - 1;
+		shift = pin_offset * bank->regs[REG_FUNC].width;
+		reg += bank->regs[REG_FUNC].offset;
 
 		data = readl(reg);
 		data &= ~(mask << shift);
@@ -342,10 +339,11 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 	drvdata = pinctrl_dev_get_drvdata(pctldev);
 
 	pin_offset = offset - bank->pin_base;
-	reg = drvdata->virt_base + bank->pctl_offset;
+	reg = drvdata->virt_base + bank->pctl_offset
+						+ bank->regs[REG_FUNC].offset;
 
-	mask = (1 << bank->func_width) - 1;
-	shift = pin_offset * bank->func_width;
+	mask = (1 << bank->regs[REG_FUNC].width) - 1;
+	shift = pin_offset * bank->regs[REG_FUNC].width;
 
 	data = readl(reg);
 	data &= ~(mask << shift);
@@ -382,20 +380,20 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 
 	switch (cfg_type) {
 	case PINCFG_TYPE_PUD:
-		width = bank->pud_width;
-		cfg_reg = PUD_REG;
+		width = bank->regs[REG_PUD].width;
+		cfg_reg = bank->regs[REG_PUD].offset;
 		break;
 	case PINCFG_TYPE_DRV:
-		width = bank->drv_width;
-		cfg_reg = DRV_REG;
+		width = bank->regs[REG_DRV].width;
+		cfg_reg = bank->regs[REG_DRV].offset;
 		break;
 	case PINCFG_TYPE_CON_PDN:
-		width = bank->conpdn_width;
-		cfg_reg = CONPDN_REG;
+		width = bank->regs[REG_CONPDN].width;
+		cfg_reg = bank->regs[REG_CONPDN].offset;
 		break;
 	case PINCFG_TYPE_PUD_PDN:
-		width = bank->pudpdn_width;
-		cfg_reg = PUDPDN_REG;
+		width = bank->regs[REG_PUDPDN].width;
+		cfg_reg = bank->regs[REG_PUDPDN].offset;
 		break;
 	default:
 		WARN_ON(1);
@@ -481,13 +479,14 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 	void __iomem *reg;
 	u32 data;
 
-	reg = bank->drvdata->virt_base + bank->pctl_offset;
+	reg = bank->drvdata->virt_base + bank->pctl_offset
+						+ bank->regs[REG_DAT].offset;
 
-	data = readl(reg + DAT_REG);
+	data = readl(reg);
 	data &= ~(1 << offset);
 	if (value)
 		data |= 1 << offset;
-	writel(data, reg + DAT_REG);
+	writel(data, reg);
 }
 
 /* gpiolib gpio_get callback function */
@@ -497,9 +496,10 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 	u32 data;
 	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 
-	reg = bank->drvdata->virt_base + bank->pctl_offset;
+	reg = bank->drvdata->virt_base + bank->pctl_offset
+						+ bank->regs[REG_DAT].offset;
 
-	data = readl(reg + DAT_REG);
+	data = readl(reg);
 	data >>= offset;
 	data &= 1;
 	return data;
@@ -818,12 +818,24 @@ static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
 
 static const struct of_device_id samsung_pinctrl_dt_match[];
 
+
+
 static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
 							struct device_node *np)
 {
+	static const char *reg_names[REG_NUM] = {
+		[REG_FUNC] = "func",
+		[REG_DAT] = "dat",
+		[REG_PUD] = "pud",
+		[REG_DRV] = "drv",
+		[REG_CONPDN] = "conpdn",
+		[REG_PUDPDN] = "pudpdn",
+	};
 	struct samsung_pin_bank *type = np->data;
-	int ret;
-	u32 val;
+	const __be32 *data;
+	int len = 0;
+	int index;
+	int i;
 
 	if (type) {
 		*bank = *type;
@@ -834,26 +846,21 @@ static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
 	if (!type)
 		return -ENOMEM;
 
-	ret = of_property_read_u32(np, "samsung,func-width", &val);
-	if (ret)
-		return ret;
-	type->func_width = val;
-
-	ret = of_property_read_u32(np, "samsung,pud-width", &val);
-	if (!ret)
-		type->pud_width = val;
-
-	ret = of_property_read_u32(np, "samsung,drv-width", &val);
-	if (!ret)
-		type->drv_width = val;
-
-	ret = of_property_read_u32(np, "samsung,conpdn-width", &val);
-	if (!ret)
-		type->conpdn_width = val;
+	data = of_get_property(np, "samsung,reg-params", &len);
+	if (!data)
+		return -EINVAL;
+	len /= sizeof(*data);
 
-	ret = of_property_read_u32(np, "samsung,pudpdn-width", &val);
-	if (!ret)
-		type->pudpdn_width = val;
+	for (i = 0; i < ARRAY_SIZE(reg_names); ++i) {
+		index = of_property_match_string(np, "samsung,reg-names",
+								reg_names[i]);
+		if (index < 0)
+			continue;
+		if (index >= len / 2)
+			return -EINVAL;
+		type->regs[i].offset = be32_to_cpu(data[2 * index]);
+		type->regs[i].width = be32_to_cpu(data[2 * index + 1]);
+	}
 
 	*bank = *type;
 	np->data = type;
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 355f4e2..684f042 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -25,12 +25,16 @@
 
 #include <linux/gpio.h>
 
-/* register offsets within a pin bank */
-#define DAT_REG		0x4
-#define PUD_REG		0x8
-#define DRV_REG		0xC
-#define CONPDN_REG	0x10
-#define PUDPDN_REG	0x14
+enum pincfg_reg {
+	REG_FUNC = 0,
+	REG_DAT,
+	REG_PUD,
+	REG_DRV,
+	REG_CONPDN,
+	REG_PUDPDN,
+
+	REG_NUM
+};
 
 /* pinmux function number for pin as gpio output line */
 #define FUNC_OUTPUT	0x1
@@ -103,15 +107,21 @@ enum eint_type {
 struct samsung_pinctrl_drv_data;
 
 /**
+ * struct samsung_pin_reg: defines a configuration register.
+ * @offset: offset from bank base.
+ * @width: with of a bit field used for single pin.
+ */
+struct samsung_pin_reg {
+	u8 offset;
+	u8 width;
+};
+
+/**
  * struct samsung_pin_bank: represent a controller pin-bank.
  * @reg_offset: starting offset of the pin-bank registers.
  * @pin_base: starting pin number of the bank.
  * @nr_pins: number of pins included in this bank.
- * @func_width: width of the function selector bit field.
- * @pud_width: width of the pin pull up/down selector bit field.
- * @drv_width: width of the pin driver strength selector bit field.
- * @conpdn_width: width of the sleep mode function selector bin field.
- * @pudpdn_width: width of the sleep mode pull up/down selector bit field.
+ * @regs: low level parameters of available configuration registers.
  * @eint_type: type of the external interrupt supported by the bank.
  * @name: name to be prefixed for each pin in this pin bank.
  * @of_node: node of pin bank in device tree
@@ -124,11 +134,7 @@ struct samsung_pin_bank {
 	u32		pctl_offset;
 	u32		pin_base;
 	u8		nr_pins;
-	u8		func_width;
-	u8		pud_width;
-	u8		drv_width;
-	u8		conpdn_width;
-	u8		pudpdn_width;
+	struct samsung_pin_reg regs[REG_NUM];
 	enum eint_type	eint_type;
 	u32		eint_offset;
 	const char	*name;
-- 
1.7.12

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

* [PATCH 14/16] pinctrl: samsung: Parse offsets of particular registers from DT
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

The order and availability of pin control registers vary with SoC.

This patch modifies the driver to parse register offsets from device
tree as a part of bank type definition.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-exynos.c  | 12 ++---
 drivers/pinctrl/pinctrl-samsung.c | 93 +++++++++++++++++++++------------------
 drivers/pinctrl/pinctrl-samsung.h | 38 +++++++++-------
 3 files changed, 78 insertions(+), 65 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 8cc8018..f264d69 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -113,9 +113,9 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 	con |= trig_type << shift;
 	writel(con, d->virt_base + reg_con);
 
-	reg_con = bank->pctl_offset;
-	shift = pin * bank->func_width;
-	mask = (1 << bank->func_width) - 1;
+	reg_con = bank->pctl_offset + bank->regs[REG_FUNC].offset;
+	shift = pin * bank->regs[REG_FUNC].width;
+	mask = (1 << bank->regs[REG_FUNC].width) - 1;
 
 	con = readl(d->virt_base + reg_con);
 	con &= ~(mask << shift);
@@ -290,9 +290,9 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 	con |= trig_type << shift;
 	writel(con, d->virt_base + reg_con);
 
-	reg_con = bank->pctl_offset;
-	shift = pin * bank->func_width;
-	mask = (1 << bank->func_width) - 1;
+	reg_con = bank->pctl_offset + bank->regs[REG_FUNC].offset;
+	shift = pin * bank->regs[REG_FUNC].width;
+	mask = (1 << bank->regs[REG_FUNC].width) - 1;
 
 	con = readl(d->virt_base + reg_con);
 	con &= ~(mask << shift);
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 215a7e5..495b226 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -273,10 +273,6 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
 	*offset = pin - b->pin_base;
 	if (bank)
 		*bank = b;
-
-	/* some banks have two config registers in a single bank */
-	if (*offset * b->func_width > BITS_PER_LONG)
-		*reg += 4;
 }
 
 /* enable or disable a pinmux function */
@@ -299,8 +295,9 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
 		pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
 				&reg, &pin_offset, &bank);
-		mask = (1 << bank->func_width) - 1;
-		shift = pin_offset * bank->func_width;
+		mask = (1 << bank->regs[REG_FUNC].width) - 1;
+		shift = pin_offset * bank->regs[REG_FUNC].width;
+		reg += bank->regs[REG_FUNC].offset;
 
 		data = readl(reg);
 		data &= ~(mask << shift);
@@ -342,10 +339,11 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 	drvdata = pinctrl_dev_get_drvdata(pctldev);
 
 	pin_offset = offset - bank->pin_base;
-	reg = drvdata->virt_base + bank->pctl_offset;
+	reg = drvdata->virt_base + bank->pctl_offset
+						+ bank->regs[REG_FUNC].offset;
 
-	mask = (1 << bank->func_width) - 1;
-	shift = pin_offset * bank->func_width;
+	mask = (1 << bank->regs[REG_FUNC].width) - 1;
+	shift = pin_offset * bank->regs[REG_FUNC].width;
 
 	data = readl(reg);
 	data &= ~(mask << shift);
@@ -382,20 +380,20 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 
 	switch (cfg_type) {
 	case PINCFG_TYPE_PUD:
-		width = bank->pud_width;
-		cfg_reg = PUD_REG;
+		width = bank->regs[REG_PUD].width;
+		cfg_reg = bank->regs[REG_PUD].offset;
 		break;
 	case PINCFG_TYPE_DRV:
-		width = bank->drv_width;
-		cfg_reg = DRV_REG;
+		width = bank->regs[REG_DRV].width;
+		cfg_reg = bank->regs[REG_DRV].offset;
 		break;
 	case PINCFG_TYPE_CON_PDN:
-		width = bank->conpdn_width;
-		cfg_reg = CONPDN_REG;
+		width = bank->regs[REG_CONPDN].width;
+		cfg_reg = bank->regs[REG_CONPDN].offset;
 		break;
 	case PINCFG_TYPE_PUD_PDN:
-		width = bank->pudpdn_width;
-		cfg_reg = PUDPDN_REG;
+		width = bank->regs[REG_PUDPDN].width;
+		cfg_reg = bank->regs[REG_PUDPDN].offset;
 		break;
 	default:
 		WARN_ON(1);
@@ -481,13 +479,14 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 	void __iomem *reg;
 	u32 data;
 
-	reg = bank->drvdata->virt_base + bank->pctl_offset;
+	reg = bank->drvdata->virt_base + bank->pctl_offset
+						+ bank->regs[REG_DAT].offset;
 
-	data = readl(reg + DAT_REG);
+	data = readl(reg);
 	data &= ~(1 << offset);
 	if (value)
 		data |= 1 << offset;
-	writel(data, reg + DAT_REG);
+	writel(data, reg);
 }
 
 /* gpiolib gpio_get callback function */
@@ -497,9 +496,10 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 	u32 data;
 	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 
-	reg = bank->drvdata->virt_base + bank->pctl_offset;
+	reg = bank->drvdata->virt_base + bank->pctl_offset
+						+ bank->regs[REG_DAT].offset;
 
-	data = readl(reg + DAT_REG);
+	data = readl(reg);
 	data >>= offset;
 	data &= 1;
 	return data;
@@ -818,12 +818,24 @@ static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
 
 static const struct of_device_id samsung_pinctrl_dt_match[];
 
+
+
 static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
 							struct device_node *np)
 {
+	static const char *reg_names[REG_NUM] = {
+		[REG_FUNC] = "func",
+		[REG_DAT] = "dat",
+		[REG_PUD] = "pud",
+		[REG_DRV] = "drv",
+		[REG_CONPDN] = "conpdn",
+		[REG_PUDPDN] = "pudpdn",
+	};
 	struct samsung_pin_bank *type = np->data;
-	int ret;
-	u32 val;
+	const __be32 *data;
+	int len = 0;
+	int index;
+	int i;
 
 	if (type) {
 		*bank = *type;
@@ -834,26 +846,21 @@ static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
 	if (!type)
 		return -ENOMEM;
 
-	ret = of_property_read_u32(np, "samsung,func-width", &val);
-	if (ret)
-		return ret;
-	type->func_width = val;
-
-	ret = of_property_read_u32(np, "samsung,pud-width", &val);
-	if (!ret)
-		type->pud_width = val;
-
-	ret = of_property_read_u32(np, "samsung,drv-width", &val);
-	if (!ret)
-		type->drv_width = val;
-
-	ret = of_property_read_u32(np, "samsung,conpdn-width", &val);
-	if (!ret)
-		type->conpdn_width = val;
+	data = of_get_property(np, "samsung,reg-params", &len);
+	if (!data)
+		return -EINVAL;
+	len /= sizeof(*data);
 
-	ret = of_property_read_u32(np, "samsung,pudpdn-width", &val);
-	if (!ret)
-		type->pudpdn_width = val;
+	for (i = 0; i < ARRAY_SIZE(reg_names); ++i) {
+		index = of_property_match_string(np, "samsung,reg-names",
+								reg_names[i]);
+		if (index < 0)
+			continue;
+		if (index >= len / 2)
+			return -EINVAL;
+		type->regs[i].offset = be32_to_cpu(data[2 * index]);
+		type->regs[i].width = be32_to_cpu(data[2 * index + 1]);
+	}
 
 	*bank = *type;
 	np->data = type;
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 355f4e2..684f042 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -25,12 +25,16 @@
 
 #include <linux/gpio.h>
 
-/* register offsets within a pin bank */
-#define DAT_REG		0x4
-#define PUD_REG		0x8
-#define DRV_REG		0xC
-#define CONPDN_REG	0x10
-#define PUDPDN_REG	0x14
+enum pincfg_reg {
+	REG_FUNC = 0,
+	REG_DAT,
+	REG_PUD,
+	REG_DRV,
+	REG_CONPDN,
+	REG_PUDPDN,
+
+	REG_NUM
+};
 
 /* pinmux function number for pin as gpio output line */
 #define FUNC_OUTPUT	0x1
@@ -103,15 +107,21 @@ enum eint_type {
 struct samsung_pinctrl_drv_data;
 
 /**
+ * struct samsung_pin_reg: defines a configuration register.
+ * @offset: offset from bank base.
+ * @width: with of a bit field used for single pin.
+ */
+struct samsung_pin_reg {
+	u8 offset;
+	u8 width;
+};
+
+/**
  * struct samsung_pin_bank: represent a controller pin-bank.
  * @reg_offset: starting offset of the pin-bank registers.
  * @pin_base: starting pin number of the bank.
  * @nr_pins: number of pins included in this bank.
- * @func_width: width of the function selector bit field.
- * @pud_width: width of the pin pull up/down selector bit field.
- * @drv_width: width of the pin driver strength selector bit field.
- * @conpdn_width: width of the sleep mode function selector bin field.
- * @pudpdn_width: width of the sleep mode pull up/down selector bit field.
+ * @regs: low level parameters of available configuration registers.
  * @eint_type: type of the external interrupt supported by the bank.
  * @name: name to be prefixed for each pin in this pin bank.
  * @of_node: node of pin bank in device tree
@@ -124,11 +134,7 @@ struct samsung_pin_bank {
 	u32		pctl_offset;
 	u32		pin_base;
 	u8		nr_pins;
-	u8		func_width;
-	u8		pud_width;
-	u8		drv_width;
-	u8		conpdn_width;
-	u8		pudpdn_width;
+	struct samsung_pin_reg regs[REG_NUM];
 	enum eint_type	eint_type;
 	u32		eint_offset;
 	const char	*name;
-- 
1.7.12

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

* [PATCH 15/16] pinctrl: samsung: Add GPIO to IRQ translation
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

Some drivers require a way to translate GPIO pins to their IRQ numbers.

This patch adds the .to_irq() gpiolib callback to pinctrl-samsung
driver, which creates (if not present yet) and returns an IRQ mapping
for given GPIO pin.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 495b226..8172c1e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/irqdomain.h>
 
 #include "core.h"
 #include "pinctrl-samsung.h"
@@ -528,6 +529,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
 }
 
 /*
+ * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
+ * and a virtual IRQ, if not already present.
+ */
+static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
+	unsigned int virq;
+
+	if (!bank->irq_domain)
+		return -ENXIO;
+
+	virq = irq_create_mapping(bank->irq_domain, offset);
+
+	return (virq) ? : -ENXIO;
+}
+
+/*
  * Parse the pin names listed in the 'samsung,pins' property and convert it
  * into a list of gpio numbers are create a pin group from it.
  */
@@ -757,6 +775,7 @@ static const struct gpio_chip samsung_gpiolib_chip = {
 	.get = samsung_gpio_get,
 	.direction_input = samsung_gpio_direction_input,
 	.direction_output = samsung_gpio_direction_output,
+	.to_irq = samsung_gpio_to_irq,
 	.owner = THIS_MODULE,
 };
 
-- 
1.7.12

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

* [PATCH 15/16] pinctrl: samsung: Add GPIO to IRQ translation
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Some drivers require a way to translate GPIO pins to their IRQ numbers.

This patch adds the .to_irq() gpiolib callback to pinctrl-samsung
driver, which creates (if not present yet) and returns an IRQ mapping
for given GPIO pin.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/pinctrl/pinctrl-samsung.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 495b226..8172c1e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/irqdomain.h>
 
 #include "core.h"
 #include "pinctrl-samsung.h"
@@ -528,6 +529,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
 }
 
 /*
+ * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
+ * and a virtual IRQ, if not already present.
+ */
+static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
+	unsigned int virq;
+
+	if (!bank->irq_domain)
+		return -ENXIO;
+
+	virq = irq_create_mapping(bank->irq_domain, offset);
+
+	return (virq) ? : -ENXIO;
+}
+
+/*
  * Parse the pin names listed in the 'samsung,pins' property and convert it
  * into a list of gpio numbers are create a pin group from it.
  */
@@ -757,6 +775,7 @@ static const struct gpio_chip samsung_gpiolib_chip = {
 	.get = samsung_gpio_get,
 	.direction_input = samsung_gpio_direction_input,
 	.direction_output = samsung_gpio_direction_output,
+	.to_irq = samsung_gpio_to_irq,
 	.owner = THIS_MODULE,
 };
 
-- 
1.7.12

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

* [PATCH 16/16] Documentation: Update samsung-pinctrl device tree bindings documentation
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-08  8:39   ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	linus.walleij, swarren, kyungmin.park, m.szyprowski, t.figa,
	tomasz.figa

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 .../bindings/pinctrl/samsung-pinctrl.txt           | 212 ++++++++++++++++++---
 1 file changed, 187 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 03dee50..6ebc946 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -13,8 +13,35 @@ Required Properties:
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
 
-- interrupts: interrupt specifier for the controller. The format and value of
-  the interrupt specifier depends on the interrupt parent for the controller.
+- Pin bank types: Pin bank nodes reference pin bank types by their phandles to
+  determine low level bank parameters such as bit field availability and widths.
+  There is no restriction for placement of such nodes. A bank type node must
+  contain following properties:
+
+  - samsung,reg-names: names of registers specified in samsung,reg-params
+    property. Allowed register names are:
+    - "func" - function configuration register (GPxCON)
+    - "dat" - input/output value register (GPxDAT)
+    - "pud" - pull-up/-down control register (GPxPUD)
+    - "drv" - driver strength control register (GPxDRV)
+    - "conpdn" - power-down state control register (GPxCONPDN)
+    - "pudpdn" - power-down pull-up/-down control register (GPxPUDPDN)
+  - samsung,reg-params: register specifiers for registers named by
+    samsung,reg-names property. Each specifier contains two cells:
+      - first cell: offset in bytes from first register of the bank
+      - second cell: bits in register used for single pin.
+
+- Pin banks as child nodes: Pin banks of the controller are represented by child
+  nodes of the controller node. Bank name is taken from name of the node. Each
+  bank node must contain following properties:
+
+  - gpio-controller: identifies the node as a gpio controller and pin bank.
+  - samsung,pctrl-offset: offset to pin control registers of the bank.
+  - samsung,pin-count: number of pins in the bank.
+  - samsung,bank-type: phandle to a node defining bank type.
+  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+    binding is used, the amount of cells must be specified as 2. See generic
+    GPIO binding documentation for description of particular cells.
 
 - Pin mux/config groups as child nodes: The pin mux (selecting pin function
   mode) and pin config (pull up/down, driver strength) settings are represented
@@ -72,16 +99,30 @@ used as system wakeup events.
 A. External GPIO Interrupts: For supporting external gpio interrupts, the
    following properties should be specified in the pin-controller device node.
 
-- interrupt-controller: identifies the controller node as interrupt-parent.
-- #interrupt-cells: the value of this property should be 2.
-  - First Cell: represents the external gpio interrupt number local to the
-    external gpio interrupt space of the controller.
-  - Second Cell: flags to identify the type of the interrupt
-    - 1 = rising edge triggered
-    - 2 = falling edge triggered
-    - 3 = rising and falling edge triggered
-    - 4 = high level triggered
-    - 8 = low level triggered
+   - samsung,geint-con: offset of first EXT_INTxx_CON register.
+   - samsung,geint-mask: offset of first EXT_INTxx_MASK register.
+   - samsung,geint-pend: offset of first EXT_INTxx_PEND register.
+   - samsung,svc: offset of EXT_INT_SERVICE register.
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     GPIO interrupts are forwarded to.
+   - interrupts: interrupt specifier for the controller. The format and value of
+     the interrupt specifier depends on the interrupt parent for the controller.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting GPIO interrupts:
+
+   - interrupt-controller: identifies the controller node as interrupt-parent.
+   - samsung,eint-offset: offset of register related to this bank from first
+     CON/MASK/PEND register.
+   - #interrupt-cells: the value of this property should be 2.
+     - First Cell: represents the external gpio interrupt number local to the
+       external gpio interrupt space of the controller.
+     - Second Cell: flags to identify the type of the interrupt
+       - 1 = rising edge triggered
+       - 2 = falling edge triggered
+       - 3 = rising and falling edge triggered
+       - 4 = high level triggered
+       - 8 = low level triggered
 
 B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
    child node representing the external wakeup interrupt controller should be
@@ -94,7 +135,18 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
        found on Samsung Exynos4210 SoC.
    - interrupt-parent: phandle of the interrupt parent to which the external
      wakeup interrupts are forwarded to.
+   - interrupts: interrupt used by multiplexed wakeup interrupts.
+   - samsung,weint-con: offset of first wake-up EXT_INTxx_CON register.
+   - samsung,weint-mask: offset of first wake-up EXT_INTxx_MASK register.
+   - samsung,weint-pend: offset of first wake-up EXT_INTxx_PEND register.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting wake-up interrupts:
+
    - interrupt-controller: identifies the node as interrupt-parent.
+   - samsung,wkup-eint: marks the bank as supporting wake-up interrupts.
+   - samsung,eint-offset: offset of register related to this bank from first
+     wake-up CON/MASK/PEND register.
    - #interrupt-cells: the value of this property should be 2
      - First Cell: represents the external wakeup interrupt number local to
        the external wakeup interrupt space of the controller.
@@ -105,17 +157,125 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
        - 4 = high level triggered
        - 8 = low level triggered
 
+   Node of every bank of pins supporting direct wake-up interrupts (without
+   multiplexing) must contain following properties:
+
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     wakeup interrupts are forwarded to.
+   - interrupts: interrupts of the interrupt parent which are used for external
+     wakeup interrupts from pins of the bank, must contain interrupts for all
+     pins of the bank.
+
 Aliases:
 
 All the pin controller nodes should be represented in the aliases node using
 the following format 'pinctrl{n}' where n is a unique number for the alias.
 
+Example: Nodes for pin bank types:
+
+	pinctrl-bank-types {
+		bank_off: bank-off {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv", "conpdn", "pudpdn";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>, <0x10 2>, <0x14 2>;
+		};
+
+		bank_alive: bank-alive {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>;
+		};
+	};
+
+Example: A pin-controller node with pin banks:
+
+	pinctrl_0: pinctrl@11400000 {
+		compatible = "samsung,pinctrl-exynos4210";
+		reg = <0x11400000 0x1000>;
+		interrupts = <0 47 0>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
+
+		/* ... */
+
+		/* Pin bank without external interrupts */
+		gpy0: gpy0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x120>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external GPIO interrupts */
+		gpj0: gpj0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external direct wake-up interrupts */
+		gpx0: gpx0 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC00>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external multiplexed wake-up interrupts */
+		gpx2: gpx2 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC40>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+	};
+
 Example 1: A pin-controller node with pin groups.
 
 	pinctrl_0: pinctrl@11400000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11400000 0x1000>;
 		interrupts = <0 47 0>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
+
+		/* ... */
 
 		uart0_data: uart0-data {
 			samsung,pins = "gpa0-0", "gpa0-1";
@@ -158,20 +318,21 @@ Example 2: A pin-controller node with external wakeup interrupt controller node.
 	pinctrl_1: pinctrl@11000000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11000000 0x1000>;
-		interrupts = <0 46 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
+		interrupts = <0 46 0>
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
 
-		wakup_eint: wakeup-interrupt-controller {
+		/* ... */
+
+		wakeup-interrupt-controller {
 			compatible = "samsung,exynos4210-wakeup-eint";
 			interrupt-parent = <&gic>;
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-					<0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
-					<0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
-					<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>,
-					<0 32 0>;
+			interrupts = <0 32 0>;
+			samsung,weint-con = <0xE00>;
+			samsung,weint-mask = <0xF00>;
+			samsung,weint-pend = <0xF40>;
 		};
 	};
 
@@ -190,7 +351,8 @@ Example 4: Set up the default pin state for uart controller.
 
 	static int s3c24xx_serial_probe(struct platform_device *pdev) {
 		struct pinctrl *pinctrl;
-		...
-		...
+
+		/* ... */
+
 		pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
 	}
-- 
1.7.12

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

* [PATCH 16/16] Documentation: Update samsung-pinctrl device tree bindings documentation
@ 2012-10-08  8:39   ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 .../bindings/pinctrl/samsung-pinctrl.txt           | 212 ++++++++++++++++++---
 1 file changed, 187 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 03dee50..6ebc946 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -13,8 +13,35 @@ Required Properties:
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
 
-- interrupts: interrupt specifier for the controller. The format and value of
-  the interrupt specifier depends on the interrupt parent for the controller.
+- Pin bank types: Pin bank nodes reference pin bank types by their phandles to
+  determine low level bank parameters such as bit field availability and widths.
+  There is no restriction for placement of such nodes. A bank type node must
+  contain following properties:
+
+  - samsung,reg-names: names of registers specified in samsung,reg-params
+    property. Allowed register names are:
+    - "func" - function configuration register (GPxCON)
+    - "dat" - input/output value register (GPxDAT)
+    - "pud" - pull-up/-down control register (GPxPUD)
+    - "drv" - driver strength control register (GPxDRV)
+    - "conpdn" - power-down state control register (GPxCONPDN)
+    - "pudpdn" - power-down pull-up/-down control register (GPxPUDPDN)
+  - samsung,reg-params: register specifiers for registers named by
+    samsung,reg-names property. Each specifier contains two cells:
+      - first cell: offset in bytes from first register of the bank
+      - second cell: bits in register used for single pin.
+
+- Pin banks as child nodes: Pin banks of the controller are represented by child
+  nodes of the controller node. Bank name is taken from name of the node. Each
+  bank node must contain following properties:
+
+  - gpio-controller: identifies the node as a gpio controller and pin bank.
+  - samsung,pctrl-offset: offset to pin control registers of the bank.
+  - samsung,pin-count: number of pins in the bank.
+  - samsung,bank-type: phandle to a node defining bank type.
+  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+    binding is used, the amount of cells must be specified as 2. See generic
+    GPIO binding documentation for description of particular cells.
 
 - Pin mux/config groups as child nodes: The pin mux (selecting pin function
   mode) and pin config (pull up/down, driver strength) settings are represented
@@ -72,16 +99,30 @@ used as system wakeup events.
 A. External GPIO Interrupts: For supporting external gpio interrupts, the
    following properties should be specified in the pin-controller device node.
 
-- interrupt-controller: identifies the controller node as interrupt-parent.
-- #interrupt-cells: the value of this property should be 2.
-  - First Cell: represents the external gpio interrupt number local to the
-    external gpio interrupt space of the controller.
-  - Second Cell: flags to identify the type of the interrupt
-    - 1 = rising edge triggered
-    - 2 = falling edge triggered
-    - 3 = rising and falling edge triggered
-    - 4 = high level triggered
-    - 8 = low level triggered
+   - samsung,geint-con: offset of first EXT_INTxx_CON register.
+   - samsung,geint-mask: offset of first EXT_INTxx_MASK register.
+   - samsung,geint-pend: offset of first EXT_INTxx_PEND register.
+   - samsung,svc: offset of EXT_INT_SERVICE register.
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     GPIO interrupts are forwarded to.
+   - interrupts: interrupt specifier for the controller. The format and value of
+     the interrupt specifier depends on the interrupt parent for the controller.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting GPIO interrupts:
+
+   - interrupt-controller: identifies the controller node as interrupt-parent.
+   - samsung,eint-offset: offset of register related to this bank from first
+     CON/MASK/PEND register.
+   - #interrupt-cells: the value of this property should be 2.
+     - First Cell: represents the external gpio interrupt number local to the
+       external gpio interrupt space of the controller.
+     - Second Cell: flags to identify the type of the interrupt
+       - 1 = rising edge triggered
+       - 2 = falling edge triggered
+       - 3 = rising and falling edge triggered
+       - 4 = high level triggered
+       - 8 = low level triggered
 
 B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
    child node representing the external wakeup interrupt controller should be
@@ -94,7 +135,18 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
        found on Samsung Exynos4210 SoC.
    - interrupt-parent: phandle of the interrupt parent to which the external
      wakeup interrupts are forwarded to.
+   - interrupts: interrupt used by multiplexed wakeup interrupts.
+   - samsung,weint-con: offset of first wake-up EXT_INTxx_CON register.
+   - samsung,weint-mask: offset of first wake-up EXT_INTxx_MASK register.
+   - samsung,weint-pend: offset of first wake-up EXT_INTxx_PEND register.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting wake-up interrupts:
+
    - interrupt-controller: identifies the node as interrupt-parent.
+   - samsung,wkup-eint: marks the bank as supporting wake-up interrupts.
+   - samsung,eint-offset: offset of register related to this bank from first
+     wake-up CON/MASK/PEND register.
    - #interrupt-cells: the value of this property should be 2
      - First Cell: represents the external wakeup interrupt number local to
        the external wakeup interrupt space of the controller.
@@ -105,17 +157,125 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
        - 4 = high level triggered
        - 8 = low level triggered
 
+   Node of every bank of pins supporting direct wake-up interrupts (without
+   multiplexing) must contain following properties:
+
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     wakeup interrupts are forwarded to.
+   - interrupts: interrupts of the interrupt parent which are used for external
+     wakeup interrupts from pins of the bank, must contain interrupts for all
+     pins of the bank.
+
 Aliases:
 
 All the pin controller nodes should be represented in the aliases node using
 the following format 'pinctrl{n}' where n is a unique number for the alias.
 
+Example: Nodes for pin bank types:
+
+	pinctrl-bank-types {
+		bank_off: bank-off {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv", "conpdn", "pudpdn";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>, <0x10 2>, <0x14 2>;
+		};
+
+		bank_alive: bank-alive {
+			samsung,reg-names = "func", "dat", "pud",
+						"drv";
+			samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+						<0x0C 2>;
+		};
+	};
+
+Example: A pin-controller node with pin banks:
+
+	pinctrl_0: pinctrl at 11400000 {
+		compatible = "samsung,pinctrl-exynos4210";
+		reg = <0x11400000 0x1000>;
+		interrupts = <0 47 0>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
+
+		/* ... */
+
+		/* Pin bank without external interrupts */
+		gpy0: gpy0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x120>;
+			samsung,pin-count = <6>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external GPIO interrupts */
+		gpj0: gpj0 {
+			gpio-controller;
+			samsung,pctl-offset = <0x000>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_off>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external direct wake-up interrupts */
+		gpx0: gpx0 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC00>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			samsung,eint-offset = <0x00>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external multiplexed wake-up interrupts */
+		gpx2: gpx2 {
+			gpio-controller;
+			samsung,pctl-offset = <0xC40>;
+			samsung,pin-count = <8>;
+			samsung,bank-type = <&bank_alive>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			samsung,wkup-eint;
+			samsung,eint-offset = <0x08>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+	};
+
 Example 1: A pin-controller node with pin groups.
 
 	pinctrl_0: pinctrl at 11400000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11400000 0x1000>;
 		interrupts = <0 47 0>;
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
+
+		/* ... */
 
 		uart0_data: uart0-data {
 			samsung,pins = "gpa0-0", "gpa0-1";
@@ -158,20 +318,21 @@ Example 2: A pin-controller node with external wakeup interrupt controller node.
 	pinctrl_1: pinctrl at 11000000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11000000 0x1000>;
-		interrupts = <0 46 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
+		interrupts = <0 46 0>
+		samsung,geint-con = <0x700>;
+		samsung,geint-mask = <0x900>;
+		samsung,geint-pend = <0xA00>;
+		samsung,svc = <0xB08>;
 
-		wakup_eint: wakeup-interrupt-controller {
+		/* ... */
+
+		wakeup-interrupt-controller {
 			compatible = "samsung,exynos4210-wakeup-eint";
 			interrupt-parent = <&gic>;
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-					<0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
-					<0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
-					<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>,
-					<0 32 0>;
+			interrupts = <0 32 0>;
+			samsung,weint-con = <0xE00>;
+			samsung,weint-mask = <0xF00>;
+			samsung,weint-pend = <0xF40>;
 		};
 	};
 
@@ -190,7 +351,8 @@ Example 4: Set up the default pin state for uart controller.
 
 	static int s3c24xx_serial_probe(struct platform_device *pdev) {
 		struct pinctrl *pinctrl;
-		...
-		...
+
+		/* ... */
+
 		pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
 	}
-- 
1.7.12

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

* Re: [PATCH 02/16] pinctrl: exynos: Parse wakeup-eint parameters from DT
  2012-10-08  8:39   ` Tomasz Figa
@ 2012-10-10  7:18     ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:18 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, thomas.abraham, swarren, kyungmin.park, m.szyprowski,
	tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch converts the pinctrl-exynos driver to parse wakeup interrupt
> count and register offsets from device tree. It reduces the amount of
> static platform-specific data and facilitates adding further SoC
> variants to pinctrl-samsung driver.

So these are:

> +       ret = of_property_read_u32(wkup_np, "samsung,weint-count", &val);
> +       ret = of_property_read_u32(wkup_np, "samsung,weint-con", &val);
> +       ret = of_property_read_u32(wkup_np, "samsung,weint-mask", &val);
> +       ret = of_property_read_u32(wkup_np, "samsung,weint-pend", &val);

Are these all four register offsets?

I don't think it's proper for the device tree to contain register offsets.

Base address, "regs" property, yes. Individual registers, no. That just
makes the code hard to read and compare to the datasheet.

Or what are you aiming at here?

Linus Walleij

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

* [PATCH 02/16] pinctrl: exynos: Parse wakeup-eint parameters from DT
@ 2012-10-10  7:18     ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch converts the pinctrl-exynos driver to parse wakeup interrupt
> count and register offsets from device tree. It reduces the amount of
> static platform-specific data and facilitates adding further SoC
> variants to pinctrl-samsung driver.

So these are:

> +       ret = of_property_read_u32(wkup_np, "samsung,weint-count", &val);
> +       ret = of_property_read_u32(wkup_np, "samsung,weint-con", &val);
> +       ret = of_property_read_u32(wkup_np, "samsung,weint-mask", &val);
> +       ret = of_property_read_u32(wkup_np, "samsung,weint-pend", &val);

Are these all four register offsets?

I don't think it's proper for the device tree to contain register offsets.

Base address, "regs" property, yes. Individual registers, no. That just
makes the code hard to read and compare to the datasheet.

Or what are you aiming at here?

Linus Walleij

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

* Re: [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
  2012-10-08  8:39   ` Tomasz Figa
@ 2012-10-10  7:26     ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:26 UTC (permalink / raw)
  To: Tomasz Figa, Grant Likely
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, thomas.abraham, swarren, kyungmin.park, m.szyprowski,
	tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> Seuqential patches from this series introduce SoC-specific data parsing
> from device tree.
>
> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> replaces them with nodes and properties required for these patches.

So to be clear:

> +       pinctrl-bank-types {
> +               bank_off: bank-off {
> +                       samsung,reg-names = "func", "dat", "pud",
> +                                               "drv", "conpdn", "pudpdn";
> +                       samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
> +                                               <0x0C 2>, <0x10 2>, <0x14 2>;
> +               };

This is starting to look like a firmware language, I have mixed
feelings about this. Shall this be read:

"Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?

We really need to discuss this, Grant has already NACK:ed
such approaches once.

If you're still going to do this, it is mandatory
to NOT use magic hex numbers anymore, because Stephen has
merged preprocessor support to the DTC compiler so you
can use #defined macros.

See commit:
cd296721a9645f9f28800a072490fa15458d1fb7

> +       pinctrl@11400000 {
> +               gpa0: gpa0 {
> +                       gpio-controller;
> +                       samsung,pctl-offset = <0x000>;
> +                       samsung,pin-count = <8>;
> +                       samsung,bank-type = <&bank_off>;
> +                       #gpio-cells = <2>;

This part is OK.

> +
> +                       interrupt-controller;
> +                       samsung,eint-offset = <0x00>;

This property is *NOT* OK. IMHO the driver should know these
offsets, not the device tree. The driver only needs the offset to
the register range, what registers there are and their names
should be #defined.

> +                       #interrupt-cells = <2>;
> +               };

Yours,
Linus Walleij

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
@ 2012-10-10  7:26     ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> Seuqential patches from this series introduce SoC-specific data parsing
> from device tree.
>
> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> replaces them with nodes and properties required for these patches.

So to be clear:

> +       pinctrl-bank-types {
> +               bank_off: bank-off {
> +                       samsung,reg-names = "func", "dat", "pud",
> +                                               "drv", "conpdn", "pudpdn";
> +                       samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
> +                                               <0x0C 2>, <0x10 2>, <0x14 2>;
> +               };

This is starting to look like a firmware language, I have mixed
feelings about this. Shall this be read:

"Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?

We really need to discuss this, Grant has already NACK:ed
such approaches once.

If you're still going to do this, it is mandatory
to NOT use magic hex numbers anymore, because Stephen has
merged preprocessor support to the DTC compiler so you
can use #defined macros.

See commit:
cd296721a9645f9f28800a072490fa15458d1fb7

> +       pinctrl at 11400000 {
> +               gpa0: gpa0 {
> +                       gpio-controller;
> +                       samsung,pctl-offset = <0x000>;
> +                       samsung,pin-count = <8>;
> +                       samsung,bank-type = <&bank_off>;
> +                       #gpio-cells = <2>;

This part is OK.

> +
> +                       interrupt-controller;
> +                       samsung,eint-offset = <0x00>;

This property is *NOT* OK. IMHO the driver should know these
offsets, not the device tree. The driver only needs the offset to
the register range, what registers there are and their names
should be #defined.

> +                       #interrupt-cells = <2>;
> +               };

Yours,
Linus Walleij

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

* Re: [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
  2012-10-08  8:39   ` Tomasz Figa
@ 2012-10-10  7:34     ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:34 UTC (permalink / raw)
  To: Tomasz Figa, ext Tony Lindgren, Grant Likely
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, thomas.abraham, swarren, kyungmin.park, m.szyprowski,
	tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> Currently SoC-specific properties such as list of pin banks, register
> offsets and bitfield sizes are being taken from static data structures
> residing in pinctrl-exynos.c.
>
> This patch modifies the pinctrl-samsung driver to parse all SoC-specific
> data from device tree, which will allow to remove the static data
> structures and facilitate adding of further SoC variants to the
> pinctrl-samsung driver.

So why? Two approaches:

- Put as much info as possible into the device tree
- Put as much info as possible into the driver

The first approach is currently only used by pinctrl-single.c.

That driver is designed for the case where all info about
the hardware arrives in some description language that
can be translated into a simple DT description.

If you want to use that approach, you should use that
driver. If that driver does not work for you, then it's not
fulfilling it's purpose as a one-stop shop for simple
pin controllers entirely contained within the device tree,
and should be renamed or redesigned.

If you will end up with a hybrid approach with some
stuff in the device tree and some stuff in the code,
it's better to keep the old driver.

Yours,
Linus Walleij

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

* [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
@ 2012-10-10  7:34     ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> Currently SoC-specific properties such as list of pin banks, register
> offsets and bitfield sizes are being taken from static data structures
> residing in pinctrl-exynos.c.
>
> This patch modifies the pinctrl-samsung driver to parse all SoC-specific
> data from device tree, which will allow to remove the static data
> structures and facilitate adding of further SoC variants to the
> pinctrl-samsung driver.

So why? Two approaches:

- Put as much info as possible into the device tree
- Put as much info as possible into the driver

The first approach is currently only used by pinctrl-single.c.

That driver is designed for the case where all info about
the hardware arrives in some description language that
can be translated into a simple DT description.

If you want to use that approach, you should use that
driver. If that driver does not work for you, then it's not
fulfilling it's purpose as a one-stop shop for simple
pin controllers entirely contained within the device tree,
and should be renamed or redesigned.

If you will end up with a hybrid approach with some
stuff in the device tree and some stuff in the code,
it's better to keep the old driver.

Yours,
Linus Walleij

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

* Re: [PATCH 03/16] pinctrl: samsung: Detect and handle unsupported configuration types
  2012-10-08  8:39   ` Tomasz Figa
@ 2012-10-10  7:37     ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:37 UTC (permalink / raw)
  To: Tomasz Figa, Thomas Abraham
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch modifies the pinctrl-samsung driver to detect when width of a
> bit field is set to zero (which means that such configuraton type is not
> supported) and return an error instead of trying to modify an inexistent
> register.
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> ---
>  drivers/pinctrl/pinctrl-samsung.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
> index dd108a9..c660fa5 100644
> --- a/drivers/pinctrl/pinctrl-samsung.c
> +++ b/drivers/pinctrl/pinctrl-samsung.c
> @@ -391,6 +391,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
>                 return -EINVAL;
>         }
>
> +       if (!width)
> +               return -EINVAL;
> +

Can this patch be applied in isolation from the others?
Thomas A: can you ACK this so I can apply it in that case?

Yours,
Linus Walleij

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

* [PATCH 03/16] pinctrl: samsung: Detect and handle unsupported configuration types
@ 2012-10-10  7:37     ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch modifies the pinctrl-samsung driver to detect when width of a
> bit field is set to zero (which means that such configuraton type is not
> supported) and return an error instead of trying to modify an inexistent
> register.
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> ---
>  drivers/pinctrl/pinctrl-samsung.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
> index dd108a9..c660fa5 100644
> --- a/drivers/pinctrl/pinctrl-samsung.c
> +++ b/drivers/pinctrl/pinctrl-samsung.c
> @@ -391,6 +391,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
>                 return -EINVAL;
>         }
>
> +       if (!width)
> +               return -EINVAL;
> +

Can this patch be applied in isolation from the others?
Thomas A: can you ACK this so I can apply it in that case?

Yours,
Linus Walleij

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

* Re: [PATCH 09/16] pinctrl: exynos: Use one IRQ domain per pin bank
  2012-10-08  8:39   ` Tomasz Figa
@ 2012-10-10  7:40     ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:40 UTC (permalink / raw)
  To: Tomasz Figa, Thomas Abraham
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> Instead of registering one IRQ domain for all pin banks of a pin
> controller, this patch implements registration of per-bank domains.
>
> At a cost of a little memory overhead (~2.5KiB for all GPIO interrupts
> of Exynos4x12) it simplifies driver code and device tree sources,
> because GPIO interrupts can be now specified per banks.
>
> Example:
>         device {
>                 /* ... */
>                 interrupt-parent = <&gpa1>;
>                 interrupts = <3 0>;
>                 /* ... */
>         };
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>

This looks like a very good patch!
Can it be applied in isolation from the other patches?
Thomas A: can you ACK this?

Yours,
Linus Walleij

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

* [PATCH 09/16] pinctrl: exynos: Use one IRQ domain per pin bank
@ 2012-10-10  7:40     ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> Instead of registering one IRQ domain for all pin banks of a pin
> controller, this patch implements registration of per-bank domains.
>
> At a cost of a little memory overhead (~2.5KiB for all GPIO interrupts
> of Exynos4x12) it simplifies driver code and device tree sources,
> because GPIO interrupts can be now specified per banks.
>
> Example:
>         device {
>                 /* ... */
>                 interrupt-parent = <&gpa1>;
>                 interrupts = <3 0>;
>                 /* ... */
>         };
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>

This looks like a very good patch!
Can it be applied in isolation from the other patches?
Thomas A: can you ACK this?

Yours,
Linus Walleij

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

* Re: [PATCH 10/16] pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
  2012-10-08  8:39   ` Tomasz Figa
@ 2012-10-10  7:42     ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:42 UTC (permalink / raw)
  To: Tomasz Figa, Thomas Abraham
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> The pointer to gpio_chip passed to pin_to_reg_bank utility function is
> used only to retrieve a pointer to samsung_pinctrl_drv_data structure.
>
> This patch modifies the function and its users to pass a pointer to
> samsung_pinctrl_drv_data directly.
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>

Looks good, can it be applied without the others?

Maybe you can make a patch series without all the
stuff moving register offsets to the DT so I can begin
with merging that and we can discuss the movement
of register info separately?

Thomas A: is this ACK:able?

Yours,
Linus Walleij

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

* [PATCH 10/16] pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
@ 2012-10-10  7:42     ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> The pointer to gpio_chip passed to pin_to_reg_bank utility function is
> used only to retrieve a pointer to samsung_pinctrl_drv_data structure.
>
> This patch modifies the function and its users to pass a pointer to
> samsung_pinctrl_drv_data directly.
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>

Looks good, can it be applied without the others?

Maybe you can make a patch series without all the
stuff moving register offsets to the DT so I can begin
with merging that and we can discuss the movement
of register info separately?

Thomas A: is this ACK:able?

Yours,
Linus Walleij

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

* Re: [PATCH 11/16] pinctrl: samsung: Use one GPIO chip per pin bank
  2012-10-08  8:39   ` Tomasz Figa
@ 2012-10-10  7:43     ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:43 UTC (permalink / raw)
  To: Tomasz Figa, Thomas Abraham
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch modifies the pinctrl-samsung driver to register one GPIO chip
> per pin bank, instead of a single chip for all pin banks of the
> controller.
>
> It simplifies GPIO accesses a lot (constant time instead of looping
> through the list of banks to find the right one) and should have a good
> effect on performance of any bit-banging driver.
>
> In addition it allows to reference GPIO pins by a phandle to the bank
> node and a local pin offset inside of the bank (similar to previous
> gpiolib driver), which is more clear and readable than using indices
> relative to the whole pin controller.
>
> Example:
>         device {
>                 /* ... */
>                 gpios = <&gpk0 4 0>;
>                 /* ... */
>         };
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>

This also looks good (and I think it has been discussed before)
so needs to be applied in isolation from the regs-to-DT stuff.

Yours,
Linus Walleij

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

* [PATCH 11/16] pinctrl: samsung: Use one GPIO chip per pin bank
@ 2012-10-10  7:43     ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch modifies the pinctrl-samsung driver to register one GPIO chip
> per pin bank, instead of a single chip for all pin banks of the
> controller.
>
> It simplifies GPIO accesses a lot (constant time instead of looping
> through the list of banks to find the right one) and should have a good
> effect on performance of any bit-banging driver.
>
> In addition it allows to reference GPIO pins by a phandle to the bank
> node and a local pin offset inside of the bank (similar to previous
> gpiolib driver), which is more clear and readable than using indices
> relative to the whole pin controller.
>
> Example:
>         device {
>                 /* ... */
>                 gpios = <&gpk0 4 0>;
>                 /* ... */
>         };
>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>

This also looks good (and I think it has been discussed before)
so needs to be applied in isolation from the regs-to-DT stuff.

Yours,
Linus Walleij

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

* Re: [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
  2012-10-08  8:39 ` Tomasz Figa
@ 2012-10-10  7:46   ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:46 UTC (permalink / raw)
  To: Tomasz Figa, Thomas Abraham
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch series is a work on improving usability and extensibiltiy of the
> pinctrl-samsung driver. It consists of three main parts:
>  - moving SoC-specific data to device tree
>  - converting the driver to use one GPIO chip and one IRQ domain per pin bank
>  - introducing generic wake-up interrupt capability description

So can you prepare a patch series which does all but the first
bullet to begin with, and a SoC-and register offset patch
on top of that as a separate series, because it is controversial?

I don't like that these two things are mingled together like this
in an all-or-nothing manner.

So I'm OK with a patch series for bulle (2) and (3) but not (1).

And I'd like to have Thomas A:s ACK on the series too.

Yours,
Linus Walleij

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

* [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
@ 2012-10-10  7:46   ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-10  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:

> This patch series is a work on improving usability and extensibiltiy of the
> pinctrl-samsung driver. It consists of three main parts:
>  - moving SoC-specific data to device tree
>  - converting the driver to use one GPIO chip and one IRQ domain per pin bank
>  - introducing generic wake-up interrupt capability description

So can you prepare a patch series which does all but the first
bullet to begin with, and a SoC-and register offset patch
on top of that as a separate series, because it is controversial?

I don't like that these two things are mingled together like this
in an all-or-nothing manner.

So I'm OK with a patch series for bulle (2) and (3) but not (1).

And I'd like to have Thomas A:s ACK on the series too.

Yours,
Linus Walleij

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

* Re: [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
  2012-10-10  7:26     ` Linus Walleij
@ 2012-10-10  8:20       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:20 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Grant Likely, linux-arm-kernel, linux-samsung-soc,
	devicetree-discuss, kgene.kim, thomas.abraham, swarren,
	kyungmin.park, m.szyprowski, tomasz.figa

On Wednesday 10 of October 2012 09:26:51 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > Seuqential patches from this series introduce SoC-specific data parsing
> > from device tree.
> > 
> > This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> > replaces them with nodes and properties required for these patches.
> 
> So to be clear:
> > +       pinctrl-bank-types {
> > +               bank_off: bank-off {
> > +                       samsung,reg-names = "func", "dat", "pud",
> > +                                               "drv", "conpdn",
> > "pudpdn"; +                       samsung,reg-params = <0x00 4>, <0x04
> > 1>, <0x08 2>, +                                               <0x0C
> > 2>, <0x10 2>, <0x14 2>; +               };
> 
> This is starting to look like a firmware language, I have mixed
> feelings about this. Shall this be read:
> 
> "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?

I'm not sure if I understood you correctly, so let me explain how this 
works.

Each specifier defines register offset inside bank registers and how many 
bits are used for one pin in this register to specify configuration value.

E.g. func register is available at offset 0x00 and pin 0 occupies bits 0-3, 
pin 1 bit 4-7, etc.

> 
> We really need to discuss this, Grant has already NACK:ed
> such approaches once.
> 
> If you're still going to do this, it is mandatory
> to NOT use magic hex numbers anymore, because Stephen has
> merged preprocessor support to the DTC compiler so you
> can use #defined macros.
> 
> See commit:
> cd296721a9645f9f28800a072490fa15458d1fb7

That's definitely nice. I have seen the work going on this before, but 
haven't followed it recently. Good to know that now it can be used.
 
> > +       pinctrl@11400000 {
> > +               gpa0: gpa0 {
> > +                       gpio-controller;
> > +                       samsung,pctl-offset = <0x000>;
> > +                       samsung,pin-count = <8>;
> > +                       samsung,bank-type = <&bank_off>;
> > +                       #gpio-cells = <2>;
> 
> This part is OK.
> 
> > +
> > +                       interrupt-controller;
> > +                       samsung,eint-offset = <0x00>;
> 
> This property is *NOT* OK. IMHO the driver should know these
> offsets, not the device tree. The driver only needs the offset to
> the register range, what registers there are and their names
> should be #defined.

This is an offset inside of EINT register group. EINT registers are 
organized in groups as following:

EINT_CON_0
EINT_CON_1
...
EINT_CON_N

...

EINT_MASK_0
EINT_MASK_1
...
EINT_MASK_N

...

EINT_PEND_0
EINT_PEND_1
...
EINT_PEND_N

With arbitrary order of particular groups, arbitrary space between groups 
and arbitrary mapping of particular registers to pin banks, although the 
mapping is the same for all groups of registers, that's why there is only 
one eint-offset property. Also holes (reserved/unused registers) inside 
groups might exist.

So if we want to access EINT_MASK register of bank A0 (of pinctrl 0), we 
must construct the address as following:

eint_mask_a0 = pinctrl_0_base + pinctrl_0_geint_mask + bank_a0_eint_offset

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
@ 2012-10-10  8:20       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:26:51 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > Seuqential patches from this series introduce SoC-specific data parsing
> > from device tree.
> > 
> > This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> > replaces them with nodes and properties required for these patches.
> 
> So to be clear:
> > +       pinctrl-bank-types {
> > +               bank_off: bank-off {
> > +                       samsung,reg-names = "func", "dat", "pud",
> > +                                               "drv", "conpdn",
> > "pudpdn"; +                       samsung,reg-params = <0x00 4>, <0x04
> > 1>, <0x08 2>, +                                               <0x0C
> > 2>, <0x10 2>, <0x14 2>; +               };
> 
> This is starting to look like a firmware language, I have mixed
> feelings about this. Shall this be read:
> 
> "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?

I'm not sure if I understood you correctly, so let me explain how this 
works.

Each specifier defines register offset inside bank registers and how many 
bits are used for one pin in this register to specify configuration value.

E.g. func register is available at offset 0x00 and pin 0 occupies bits 0-3, 
pin 1 bit 4-7, etc.

> 
> We really need to discuss this, Grant has already NACK:ed
> such approaches once.
> 
> If you're still going to do this, it is mandatory
> to NOT use magic hex numbers anymore, because Stephen has
> merged preprocessor support to the DTC compiler so you
> can use #defined macros.
> 
> See commit:
> cd296721a9645f9f28800a072490fa15458d1fb7

That's definitely nice. I have seen the work going on this before, but 
haven't followed it recently. Good to know that now it can be used.
 
> > +       pinctrl at 11400000 {
> > +               gpa0: gpa0 {
> > +                       gpio-controller;
> > +                       samsung,pctl-offset = <0x000>;
> > +                       samsung,pin-count = <8>;
> > +                       samsung,bank-type = <&bank_off>;
> > +                       #gpio-cells = <2>;
> 
> This part is OK.
> 
> > +
> > +                       interrupt-controller;
> > +                       samsung,eint-offset = <0x00>;
> 
> This property is *NOT* OK. IMHO the driver should know these
> offsets, not the device tree. The driver only needs the offset to
> the register range, what registers there are and their names
> should be #defined.

This is an offset inside of EINT register group. EINT registers are 
organized in groups as following:

EINT_CON_0
EINT_CON_1
...
EINT_CON_N

...

EINT_MASK_0
EINT_MASK_1
...
EINT_MASK_N

...

EINT_PEND_0
EINT_PEND_1
...
EINT_PEND_N

With arbitrary order of particular groups, arbitrary space between groups 
and arbitrary mapping of particular registers to pin banks, although the 
mapping is the same for all groups of registers, that's why there is only 
one eint-offset property. Also holes (reserved/unused registers) inside 
groups might exist.

So if we want to access EINT_MASK register of bank A0 (of pinctrl 0), we 
must construct the address as following:

eint_mask_a0 = pinctrl_0_base + pinctrl_0_geint_mask + bank_a0_eint_offset

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 02/16] pinctrl: exynos: Parse wakeup-eint parameters from DT
  2012-10-10  7:18     ` Linus Walleij
@ 2012-10-10  8:23       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:23 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, thomas.abraham, swarren, kyungmin.park, m.szyprowski,
	tomasz.figa

On Wednesday 10 of October 2012 09:18:51 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch converts the pinctrl-exynos driver to parse wakeup interrupt
> > count and register offsets from device tree. It reduces the amount of
> > static platform-specific data and facilitates adding further SoC
> > variants to pinctrl-samsung driver.
> 
> So these are:
> > +       ret = of_property_read_u32(wkup_np, "samsung,weint-count",
> > &val); +       ret = of_property_read_u32(wkup_np,
> > "samsung,weint-con", &val); +       ret =
> > of_property_read_u32(wkup_np, "samsung,weint-mask", &val); +       ret
> > = of_property_read_u32(wkup_np, "samsung,weint-pend", &val);
> Are these all four register offsets?
> 
> I don't think it's proper for the device tree to contain register
> offsets.
> 
> Base address, "regs" property, yes. Individual registers, no. That just
> makes the code hard to read and compare to the datasheet.
> 
> Or what are you aiming at here?

See my reply to your comments for patch 1. I think it should explain how 
these values are used.

One thing worth mentioning is that registers for GPIO interrupts and wakeup 
interrupts can be located at different areas of pin controller address 
space, so these offsets have to be specified for both (using geint-* and 
weint-* properties).

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 02/16] pinctrl: exynos: Parse wakeup-eint parameters from DT
@ 2012-10-10  8:23       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:18:51 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch converts the pinctrl-exynos driver to parse wakeup interrupt
> > count and register offsets from device tree. It reduces the amount of
> > static platform-specific data and facilitates adding further SoC
> > variants to pinctrl-samsung driver.
> 
> So these are:
> > +       ret = of_property_read_u32(wkup_np, "samsung,weint-count",
> > &val); +       ret = of_property_read_u32(wkup_np,
> > "samsung,weint-con", &val); +       ret =
> > of_property_read_u32(wkup_np, "samsung,weint-mask", &val); +       ret
> > = of_property_read_u32(wkup_np, "samsung,weint-pend", &val);
> Are these all four register offsets?
> 
> I don't think it's proper for the device tree to contain register
> offsets.
> 
> Base address, "regs" property, yes. Individual registers, no. That just
> makes the code hard to read and compare to the datasheet.
> 
> Or what are you aiming at here?

See my reply to your comments for patch 1. I think it should explain how 
these values are used.

One thing worth mentioning is that registers for GPIO interrupts and wakeup 
interrupts can be located at different areas of pin controller address 
space, so these offsets have to be specified for both (using geint-* and 
weint-* properties).

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 03/16] pinctrl: samsung: Detect and handle unsupported configuration types
  2012-10-10  7:37     ` Linus Walleij
@ 2012-10-10  8:25       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:25 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Abraham, linux-arm-kernel, linux-samsung-soc,
	devicetree-discuss, kgene.kim, swarren, kyungmin.park,
	m.szyprowski, tomasz.figa

On Wednesday 10 of October 2012 09:37:42 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch modifies the pinctrl-samsung driver to detect when width of
> > a
> > bit field is set to zero (which means that such configuraton type is
> > not
> > supported) and return an error instead of trying to modify an
> > inexistent
> > register.
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> > ---
> > 
> >  drivers/pinctrl/pinctrl-samsung.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/pinctrl/pinctrl-samsung.c
> > b/drivers/pinctrl/pinctrl-samsung.c index dd108a9..c660fa5 100644
> > --- a/drivers/pinctrl/pinctrl-samsung.c
> > +++ b/drivers/pinctrl/pinctrl-samsung.c
> > @@ -391,6 +391,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev
> > *pctldev, unsigned int pin,> 
> >                 return -EINVAL;
> >         
> >         }
> > 
> > +       if (!width)
> > +               return -EINVAL;
> > +
> 
> Can this patch be applied in isolation from the others?

Yes, I don't see any problem here.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 03/16] pinctrl: samsung: Detect and handle unsupported configuration types
@ 2012-10-10  8:25       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:37:42 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch modifies the pinctrl-samsung driver to detect when width of
> > a
> > bit field is set to zero (which means that such configuraton type is
> > not
> > supported) and return an error instead of trying to modify an
> > inexistent
> > register.
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> > ---
> > 
> >  drivers/pinctrl/pinctrl-samsung.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/pinctrl/pinctrl-samsung.c
> > b/drivers/pinctrl/pinctrl-samsung.c index dd108a9..c660fa5 100644
> > --- a/drivers/pinctrl/pinctrl-samsung.c
> > +++ b/drivers/pinctrl/pinctrl-samsung.c
> > @@ -391,6 +391,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev
> > *pctldev, unsigned int pin,> 
> >                 return -EINVAL;
> >         
> >         }
> > 
> > +       if (!width)
> > +               return -EINVAL;
> > +
> 
> Can this patch be applied in isolation from the others?

Yes, I don't see any problem here.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
  2012-10-10  7:34     ` Linus Walleij
@ 2012-10-10  8:39       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:39 UTC (permalink / raw)
  To: Linus Walleij
  Cc: ext Tony Lindgren, Grant Likely, linux-arm-kernel,
	linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Wednesday 10 of October 2012 09:34:05 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > Currently SoC-specific properties such as list of pin banks, register
> > offsets and bitfield sizes are being taken from static data structures
> > residing in pinctrl-exynos.c.
> > 
> > This patch modifies the pinctrl-samsung driver to parse all
> > SoC-specific
> > data from device tree, which will allow to remove the static data
> > structures and facilitate adding of further SoC variants to the
> > pinctrl-samsung driver.
> 
> So why? Two approaches:
> 
> - Put as much info as possible into the device tree
> - Put as much info as possible into the driver
> 
> The first approach is currently only used by pinctrl-single.c.
> 
> That driver is designed for the case where all info about
> the hardware arrives in some description language that
> can be translated into a simple DT description.
> 
> If you want to use that approach, you should use that
> driver. If that driver does not work for you, then it's not
> fulfilling it's purpose as a one-stop shop for simple
> pin controllers entirely contained within the device tree,
> and should be renamed or redesigned.
> 
> If you will end up with a hybrid approach with some
> stuff in the device tree and some stuff in the code,
> it's better to keep the old driver.

This will allow us to cover all the existing Samsung SoCs, starting from 
S3C24xx, through S3C64xx, S5P*, all supported Exynos SoCs and ending on any 
future SoCs using this kind of pin controller, without bloating the driver 
with hardly readable macros, lots of (often duplicated) static data and 
similar.

If there are some serious problems with this approach, just let me know and 
I will reconsider it, but if not, I'd like to keep it, because of the 
benefits it gives.

(Even if I moved all those SoC-specific data to static structures located 
in the driver, to keep the most readable way of GPIO specification in DT, I 
would have to create nodes for all banks in DT anyway and the driver would 
have to match particular nodes with their static data. I don't like this 
kind of approach.)

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
@ 2012-10-10  8:39       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:34:05 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > Currently SoC-specific properties such as list of pin banks, register
> > offsets and bitfield sizes are being taken from static data structures
> > residing in pinctrl-exynos.c.
> > 
> > This patch modifies the pinctrl-samsung driver to parse all
> > SoC-specific
> > data from device tree, which will allow to remove the static data
> > structures and facilitate adding of further SoC variants to the
> > pinctrl-samsung driver.
> 
> So why? Two approaches:
> 
> - Put as much info as possible into the device tree
> - Put as much info as possible into the driver
> 
> The first approach is currently only used by pinctrl-single.c.
> 
> That driver is designed for the case where all info about
> the hardware arrives in some description language that
> can be translated into a simple DT description.
> 
> If you want to use that approach, you should use that
> driver. If that driver does not work for you, then it's not
> fulfilling it's purpose as a one-stop shop for simple
> pin controllers entirely contained within the device tree,
> and should be renamed or redesigned.
> 
> If you will end up with a hybrid approach with some
> stuff in the device tree and some stuff in the code,
> it's better to keep the old driver.

This will allow us to cover all the existing Samsung SoCs, starting from 
S3C24xx, through S3C64xx, S5P*, all supported Exynos SoCs and ending on any 
future SoCs using this kind of pin controller, without bloating the driver 
with hardly readable macros, lots of (often duplicated) static data and 
similar.

If there are some serious problems with this approach, just let me know and 
I will reconsider it, but if not, I'd like to keep it, because of the 
benefits it gives.

(Even if I moved all those SoC-specific data to static structures located 
in the driver, to keep the most readable way of GPIO specification in DT, I 
would have to create nodes for all banks in DT anyway and the driver would 
have to match particular nodes with their static data. I don't like this 
kind of approach.)

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 09/16] pinctrl: exynos: Use one IRQ domain per pin bank
  2012-10-10  7:40     ` Linus Walleij
@ 2012-10-10  8:45       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:45 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Abraham, linux-arm-kernel, linux-samsung-soc,
	devicetree-discuss, kgene.kim, swarren, kyungmin.park,
	m.szyprowski, tomasz.figa

On Wednesday 10 of October 2012 09:40:16 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > Instead of registering one IRQ domain for all pin banks of a pin
> > controller, this patch implements registration of per-bank domains.
> > 
> > At a cost of a little memory overhead (~2.5KiB for all GPIO interrupts
> > of Exynos4x12) it simplifies driver code and device tree sources,
> > because GPIO interrupts can be now specified per banks.
> > 
> > Example:
> >         device {
> >         
> >                 /* ... */
> >                 interrupt-parent = <&gpa1>;
> >                 interrupts = <3 0>;
> >                 /* ... */
> >         
> >         };
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> 
> This looks like a very good patch!
> Can it be applied in isolation from the other patches?

This is heavily dependent on previous patches, because each pin bank must 
have its own node that can be bound to the IRQ domain and used as an 
interrupt-controller in interrupt-parent property.

I can imagine kind of hybrid solution, where bank nodes contain almost no 
data, other than gpio-controller, interrupt-controller and #*-cells 
properties, but this would introduce the need of matching bank nodes with 
banks statically defined in the driver.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 09/16] pinctrl: exynos: Use one IRQ domain per pin bank
@ 2012-10-10  8:45       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:40:16 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > Instead of registering one IRQ domain for all pin banks of a pin
> > controller, this patch implements registration of per-bank domains.
> > 
> > At a cost of a little memory overhead (~2.5KiB for all GPIO interrupts
> > of Exynos4x12) it simplifies driver code and device tree sources,
> > because GPIO interrupts can be now specified per banks.
> > 
> > Example:
> >         device {
> >         
> >                 /* ... */
> >                 interrupt-parent = <&gpa1>;
> >                 interrupts = <3 0>;
> >                 /* ... */
> >         
> >         };
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> 
> This looks like a very good patch!
> Can it be applied in isolation from the other patches?

This is heavily dependent on previous patches, because each pin bank must 
have its own node that can be bound to the IRQ domain and used as an 
interrupt-controller in interrupt-parent property.

I can imagine kind of hybrid solution, where bank nodes contain almost no 
data, other than gpio-controller, interrupt-controller and #*-cells 
properties, but this would introduce the need of matching bank nodes with 
banks statically defined in the driver.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 11/16] pinctrl: samsung: Use one GPIO chip per pin bank
  2012-10-10  7:43     ` Linus Walleij
@ 2012-10-10  8:49       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:49 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Abraham, linux-arm-kernel, linux-samsung-soc,
	devicetree-discuss, kgene.kim, swarren, kyungmin.park,
	m.szyprowski, tomasz.figa

On Wednesday 10 of October 2012 09:43:25 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch modifies the pinctrl-samsung driver to register one GPIO
> > chip
> > per pin bank, instead of a single chip for all pin banks of the
> > controller.
> > 
> > It simplifies GPIO accesses a lot (constant time instead of looping
> > through the list of banks to find the right one) and should have a good
> > effect on performance of any bit-banging driver.
> > 
> > In addition it allows to reference GPIO pins by a phandle to the bank
> > node and a local pin offset inside of the bank (similar to previous
> > gpiolib driver), which is more clear and readable than using indices
> > relative to the whole pin controller.
> > 
> > Example:
> >         device {
> >         
> >                 /* ... */
> >                 gpios = <&gpk0 4 0>;
> >                 /* ... */
> >         
> >         };
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> 
> This also looks good (and I think it has been discussed before)
> so needs to be applied in isolation from the regs-to-DT stuff.

Please see my reply for patch 9.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 11/16] pinctrl: samsung: Use one GPIO chip per pin bank
@ 2012-10-10  8:49       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:43:25 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch modifies the pinctrl-samsung driver to register one GPIO
> > chip
> > per pin bank, instead of a single chip for all pin banks of the
> > controller.
> > 
> > It simplifies GPIO accesses a lot (constant time instead of looping
> > through the list of banks to find the right one) and should have a good
> > effect on performance of any bit-banging driver.
> > 
> > In addition it allows to reference GPIO pins by a phandle to the bank
> > node and a local pin offset inside of the bank (similar to previous
> > gpiolib driver), which is more clear and readable than using indices
> > relative to the whole pin controller.
> > 
> > Example:
> >         device {
> >         
> >                 /* ... */
> >                 gpios = <&gpk0 4 0>;
> >                 /* ... */
> >         
> >         };
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> 
> This also looks good (and I think it has been discussed before)
> so needs to be applied in isolation from the regs-to-DT stuff.

Please see my reply for patch 9.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 10/16] pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
  2012-10-10  7:42     ` Linus Walleij
@ 2012-10-10  8:51       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Abraham, linux-arm-kernel, linux-samsung-soc,
	devicetree-discuss, kgene.kim, swarren, kyungmin.park,
	m.szyprowski, tomasz.figa

On Wednesday 10 of October 2012 09:42:10 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > The pointer to gpio_chip passed to pin_to_reg_bank utility function is
> > used only to retrieve a pointer to samsung_pinctrl_drv_data structure.
> > 
> > This patch modifies the function and its users to pass a pointer to
> > samsung_pinctrl_drv_data directly.
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> 
> Looks good, can it be applied without the others?

Yes, I think this one should apply fine.

> Maybe you can make a patch series without all the
> stuff moving register offsets to the DT so I can begin
> with merging that and we can discuss the movement
> of register info separately?

I already considered this approach, but it introduces some problems, as I 
mentioned in my other replies.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 10/16] pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank
@ 2012-10-10  8:51       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:42:10 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > The pointer to gpio_chip passed to pin_to_reg_bank utility function is
> > used only to retrieve a pointer to samsung_pinctrl_drv_data structure.
> > 
> > This patch modifies the function and its users to pass a pointer to
> > samsung_pinctrl_drv_data directly.
> > 
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> 
> Looks good, can it be applied without the others?

Yes, I think this one should apply fine.

> Maybe you can make a patch series without all the
> stuff moving register offsets to the DT so I can begin
> with merging that and we can discuss the movement
> of register info separately?

I already considered this approach, but it introduces some problems, as I 
mentioned in my other replies.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
  2012-10-10  7:46   ` Linus Walleij
@ 2012-10-10  9:04       ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  9:04 UTC (permalink / raw)
  To: Linus Walleij
  Cc: kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ

On Wednesday 10 of October 2012 09:46:28 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> > This patch series is a work on improving usability and extensibiltiy of
> > the> 
> > pinctrl-samsung driver. It consists of three main parts:
> >  - moving SoC-specific data to device tree
> >  - converting the driver to use one GPIO chip and one IRQ domain per
> >  pin bank - introducing generic wake-up interrupt capability
> >  description
> 
> So can you prepare a patch series which does all but the first
> bullet to begin with, and a SoC-and register offset patch
> on top of that as a separate series, because it is controversial?
> 
> I don't like that these two things are mingled together like this
> in an all-or-nothing manner.
> 
> So I'm OK with a patch series for bulle (2) and (3) but not (1).

As I already stated in my other replies, patches for (2) and (3) depend on 
(1), because current architecture of the driver makes it hard to implement 
in an elegant way, so some code would have to be reworked anyway.

I should still have some preliminary work on this in one of my branches in 
my working tree, but it was heavily incomplete, as it turned out that using 
DT would simplify some things.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
@ 2012-10-10  9:04       ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:46:28 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch series is a work on improving usability and extensibiltiy of
> > the> 
> > pinctrl-samsung driver. It consists of three main parts:
> >  - moving SoC-specific data to device tree
> >  - converting the driver to use one GPIO chip and one IRQ domain per
> >  pin bank - introducing generic wake-up interrupt capability
> >  description
> 
> So can you prepare a patch series which does all but the first
> bullet to begin with, and a SoC-and register offset patch
> on top of that as a separate series, because it is controversial?
> 
> I don't like that these two things are mingled together like this
> in an all-or-nothing manner.
> 
> So I'm OK with a patch series for bulle (2) and (3) but not (1).

As I already stated in my other replies, patches for (2) and (3) depend on 
(1), because current architecture of the driver makes it hard to implement 
in an elegant way, so some code would have to be reworked anyway.

I should still have some preliminary work on this in one of my branches in 
my working tree, but it was heavily incomplete, as it turned out that using 
DT would simplify some things.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
  2012-10-10  7:46   ` Linus Walleij
@ 2012-10-10 15:22     ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10 15:22 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Abraham, linux-arm-kernel, linux-samsung-soc,
	devicetree-discuss, kgene.kim, swarren, kyungmin.park,
	m.szyprowski, tomasz.figa

On Wednesday 10 of October 2012 09:46:28 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch series is a work on improving usability and extensibiltiy of
> > the> 
> > pinctrl-samsung driver. It consists of three main parts:
> >  - moving SoC-specific data to device tree
> >  - converting the driver to use one GPIO chip and one IRQ domain per
> >  pin bank - introducing generic wake-up interrupt capability
> >  description
> 
> So can you prepare a patch series which does all but the first
> bullet to begin with, and a SoC-and register offset patch
> on top of that as a separate series, because it is controversial?
> 
> I don't like that these two things are mingled together like this
> in an all-or-nothing manner.
> 
> So I'm OK with a patch series for bulle (2) and (3) but not (1).
> 
> And I'd like to have Thomas A:s ACK on the series too.
> 

I have managed to rework the changes to drop (1). I will send next version 
of patches tomorrow. It would be nice to have them merged for 3.7, as they 
are rather important for further work.

Moving data from the driver to device tree is not as important, so it might 
be discussed later.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
@ 2012-10-10 15:22     ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 10 of October 2012 09:46:28 Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > This patch series is a work on improving usability and extensibiltiy of
> > the> 
> > pinctrl-samsung driver. It consists of three main parts:
> >  - moving SoC-specific data to device tree
> >  - converting the driver to use one GPIO chip and one IRQ domain per
> >  pin bank - introducing generic wake-up interrupt capability
> >  description
> 
> So can you prepare a patch series which does all but the first
> bullet to begin with, and a SoC-and register offset patch
> on top of that as a separate series, because it is controversial?
> 
> I don't like that these two things are mingled together like this
> in an all-or-nothing manner.
> 
> So I'm OK with a patch series for bulle (2) and (3) but not (1).
> 
> And I'd like to have Thomas A:s ACK on the series too.
> 

I have managed to rework the changes to drop (1). I will send next version 
of patches tomorrow. It would be nice to have them merged for 3.7, as they 
are rather important for further work.

Moving data from the driver to device tree is not as important, so it might 
be discussed later.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center

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

* Re: [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
  2012-10-10  7:26     ` Linus Walleij
@ 2012-10-10 16:27       ` Stephen Warren
  -1 siblings, 0 replies; 80+ messages in thread
From: Stephen Warren @ 2012-10-10 16:27 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Tomasz Figa, Grant Likely, linux-arm-kernel, linux-samsung-soc,
	devicetree-discuss, kgene.kim, thomas.abraham, kyungmin.park,
	m.szyprowski, tomasz.figa

On 10/10/2012 01:26 AM, Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> 
>> Seuqential patches from this series introduce SoC-specific data parsing
>> from device tree.
>>
>> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
>> replaces them with nodes and properties required for these patches.
> 
> So to be clear:
> 
>> +       pinctrl-bank-types {
>> +               bank_off: bank-off {
>> +                       samsung,reg-names = "func", "dat", "pud",
>> +                                               "drv", "conpdn", "pudpdn";
>> +                       samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
>> +                                               <0x0C 2>, <0x10 2>, <0x14 2>;
>> +               };
> 
> This is starting to look like a firmware language, I have mixed
> feelings about this. Shall this be read:
> 
> "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> 
> We really need to discuss this, Grant has already NACK:ed
> such approaches once.

Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
which is doing this exact same thing. I did raise the same point about
Tony's driver when he posted it, but nobody seemed inclined to NACK it
based on that at the time, IIRC...

BTW, the idea here is IIRC to create a generic Samsung pinctrl driver
that works across N different Samsung SoCs, each with different register
layout, without having to encode the register layout into tables in the
kernel.

> If you're still going to do this, it is mandatory
> to NOT use magic hex numbers anymore, because Stephen has
> merged preprocessor support to the DTC compiler so you
> can use #defined macros.
> 
> See commit:
> cd296721a9645f9f28800a072490fa15458d1fb7

That feature isn't enabled yet. While dtc has been modified to be able
to accept input that's been generated/processed by cpp, there is still
ongoing discussion about how/whether to actually enable *.dts to use
that feature.

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
@ 2012-10-10 16:27       ` Stephen Warren
  0 siblings, 0 replies; 80+ messages in thread
From: Stephen Warren @ 2012-10-10 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/10/2012 01:26 AM, Linus Walleij wrote:
> On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> 
>> Seuqential patches from this series introduce SoC-specific data parsing
>> from device tree.
>>
>> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
>> replaces them with nodes and properties required for these patches.
> 
> So to be clear:
> 
>> +       pinctrl-bank-types {
>> +               bank_off: bank-off {
>> +                       samsung,reg-names = "func", "dat", "pud",
>> +                                               "drv", "conpdn", "pudpdn";
>> +                       samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
>> +                                               <0x0C 2>, <0x10 2>, <0x14 2>;
>> +               };
> 
> This is starting to look like a firmware language, I have mixed
> feelings about this. Shall this be read:
> 
> "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> 
> We really need to discuss this, Grant has already NACK:ed
> such approaches once.

Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
which is doing this exact same thing. I did raise the same point about
Tony's driver when he posted it, but nobody seemed inclined to NACK it
based on that at the time, IIRC...

BTW, the idea here is IIRC to create a generic Samsung pinctrl driver
that works across N different Samsung SoCs, each with different register
layout, without having to encode the register layout into tables in the
kernel.

> If you're still going to do this, it is mandatory
> to NOT use magic hex numbers anymore, because Stephen has
> merged preprocessor support to the DTC compiler so you
> can use #defined macros.
> 
> See commit:
> cd296721a9645f9f28800a072490fa15458d1fb7

That feature isn't enabled yet. While dtc has been modified to be able
to accept input that's been generated/processed by cpp, there is still
ongoing discussion about how/whether to actually enable *.dts to use
that feature.

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

* Re: [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
  2012-10-10 16:27       ` Stephen Warren
@ 2012-10-10 18:12         ` Tony Lindgren
  -1 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2012-10-10 18:12 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Linus Walleij, kgene.kim, tomasz.figa, kyungmin.park,
	linux-samsung-soc, devicetree-discuss, linux-arm-kernel,
	m.szyprowski

* Stephen Warren <swarren@wwwdotorg.org> [121010 09:36]:
> On 10/10/2012 01:26 AM, Linus Walleij wrote:
> > On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > 
> >> Seuqential patches from this series introduce SoC-specific data parsing
> >> from device tree.
> >>
> >> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> >> replaces them with nodes and properties required for these patches.
> > 
> > So to be clear:
> > 
> >> +       pinctrl-bank-types {
> >> +               bank_off: bank-off {
> >> +                       samsung,reg-names = "func", "dat", "pud",
> >> +                                               "drv", "conpdn", "pudpdn";
> >> +                       samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
> >> +                                               <0x0C 2>, <0x10 2>, <0x14 2>;
> >> +               };
> > 
> > This is starting to look like a firmware language, I have mixed
> > feelings about this. Shall this be read:
> > 
> > "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> > 
> > We really need to discuss this, Grant has already NACK:ed
> > such approaches once.
> 
> Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
> which is doing this exact same thing. I did raise the same point about
> Tony's driver when he posted it, but nobody seemed inclined to NACK it
> based on that at the time, IIRC...

To summarize, using reg value pairs in DT makes sense if the amount
of data is huge. Otherwise we'll be describing indidual hardware bits
as properties in DT, or have to have huge amounts of static data in
the kernel.

Where it does not make sense is if there's a sequence of reads
and writes with test loops in between.. But that's does not look
to be the case here.

The reg value pairs will be readable when the DT preprocessing is
available, and that allows the values to be orred together while
DT properties don't. The alternative is to describe hardware register
bits as DT properties, which is very bloated.

But considering all this.. Are the samsung,reg-names really needed
by the kernel?

The pinctrl named modes actually are more generic from the pinctrl
client driver point of view as you can set up multiple states for
runtime PM.
 
> BTW, the idea here is IIRC to create a generic Samsung pinctrl driver
> that works across N different Samsung SoCs, each with different register
> layout, without having to encode the register layout into tables in the
> kernel.
> 
> > If you're still going to do this, it is mandatory
> > to NOT use magic hex numbers anymore, because Stephen has
> > merged preprocessor support to the DTC compiler so you
> > can use #defined macros.
> > 
> > See commit:
> > cd296721a9645f9f28800a072490fa15458d1fb7
> 
> That feature isn't enabled yet. While dtc has been modified to be able
> to accept input that's been generated/processed by cpp, there is still
> ongoing discussion about how/whether to actually enable *.dts to use
> that feature.

Hey finally! That's good news.

Regards,

Tony

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
@ 2012-10-10 18:12         ` Tony Lindgren
  0 siblings, 0 replies; 80+ messages in thread
From: Tony Lindgren @ 2012-10-10 18:12 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren <swarren@wwwdotorg.org> [121010 09:36]:
> On 10/10/2012 01:26 AM, Linus Walleij wrote:
> > On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> > 
> >> Seuqential patches from this series introduce SoC-specific data parsing
> >> from device tree.
> >>
> >> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> >> replaces them with nodes and properties required for these patches.
> > 
> > So to be clear:
> > 
> >> +       pinctrl-bank-types {
> >> +               bank_off: bank-off {
> >> +                       samsung,reg-names = "func", "dat", "pud",
> >> +                                               "drv", "conpdn", "pudpdn";
> >> +                       samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
> >> +                                               <0x0C 2>, <0x10 2>, <0x14 2>;
> >> +               };
> > 
> > This is starting to look like a firmware language, I have mixed
> > feelings about this. Shall this be read:
> > 
> > "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> > 
> > We really need to discuss this, Grant has already NACK:ed
> > such approaches once.
> 
> Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
> which is doing this exact same thing. I did raise the same point about
> Tony's driver when he posted it, but nobody seemed inclined to NACK it
> based on that at the time, IIRC...

To summarize, using reg value pairs in DT makes sense if the amount
of data is huge. Otherwise we'll be describing indidual hardware bits
as properties in DT, or have to have huge amounts of static data in
the kernel.

Where it does not make sense is if there's a sequence of reads
and writes with test loops in between.. But that's does not look
to be the case here.

The reg value pairs will be readable when the DT preprocessing is
available, and that allows the values to be orred together while
DT properties don't. The alternative is to describe hardware register
bits as DT properties, which is very bloated.

But considering all this.. Are the samsung,reg-names really needed
by the kernel?

The pinctrl named modes actually are more generic from the pinctrl
client driver point of view as you can set up multiple states for
runtime PM.
 
> BTW, the idea here is IIRC to create a generic Samsung pinctrl driver
> that works across N different Samsung SoCs, each with different register
> layout, without having to encode the register layout into tables in the
> kernel.
> 
> > If you're still going to do this, it is mandatory
> > to NOT use magic hex numbers anymore, because Stephen has
> > merged preprocessor support to the DTC compiler so you
> > can use #defined macros.
> > 
> > See commit:
> > cd296721a9645f9f28800a072490fa15458d1fb7
> 
> That feature isn't enabled yet. While dtc has been modified to be able
> to accept input that's been generated/processed by cpp, there is still
> ongoing discussion about how/whether to actually enable *.dts to use
> that feature.

Hey finally! That's good news.

Regards,

Tony

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

* Re: [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
  2012-10-10 18:12         ` Tony Lindgren
@ 2012-10-10 18:22           ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10 18:22 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-samsung-soc, Stephen Warren, devicetree-discuss,
	kyungmin.park, kgene.kim, Linus Walleij, linux-arm-kernel,
	m.szyprowski


[-- Attachment #1.1: Type: text/plain, Size: 2670 bytes --]

Dnia środa, 10 października 2012 11:12:53 Tony Lindgren pisze:
> * Stephen Warren <swarren@wwwdotorg.org> [121010 09:36]:
> > On 10/10/2012 01:26 AM, Linus Walleij wrote:
> > > On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> 
wrote:
> > >> Seuqential patches from this series introduce SoC-specific data 
parsing
> > >> from device tree.
> > >> 
> > >> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> > >> replaces them with nodes and properties required for these patches.
> > > 
> > > So to be clear:
> > >> +       pinctrl-bank-types {
> > >> +               bank_off: bank-off {
> > >> +                       samsung,reg-names = "func", "dat", "pud",
> > >> +                                               "drv", "conpdn",
> > >> "pudpdn";
> > >> +                       samsung,reg-params = <0x00 4>, <0x04 1>, 
<0x08
> > >> 2>,
> > >> +                                               <0x0C 2>, <0x10 2>,
> > >> <0x14 2>; +               };
> > > 
> > > This is starting to look like a firmware language, I have mixed
> > > feelings about this. Shall this be read:
> > > 
> > > "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> > > 
> > > We really need to discuss this, Grant has already NACK:ed
> > > such approaches once.
> > 
> > Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
> > which is doing this exact same thing. I did raise the same point about
> > Tony's driver when he posted it, but nobody seemed inclined to NACK it
> > based on that at the time, IIRC...
> 
> To summarize, using reg value pairs in DT makes sense if the amount
> of data is huge. Otherwise we'll be describing indidual hardware bits
> as properties in DT, or have to have huge amounts of static data in
> the kernel.
> 
> Where it does not make sense is if there's a sequence of reads
> and writes with test loops in between.. But that's does not look
> to be the case here.
> 
> The reg value pairs will be readable when the DT preprocessing is
> available, and that allows the values to be orred together while
> DT properties don't. The alternative is to describe hardware register
> bits as DT properties, which is very bloated.
> 
> But considering all this.. Are the samsung,reg-names really needed
> by the kernel?

They are used to specify which registers are defined in reg-params property 
and in which order. Most of the registers are not mandatory and this is 
needed to be able to specify only those that are present. At least I 
couldn't think of a better solution for this. Do you have some suggestions?

Best regards,
Tomasz Figa

[-- Attachment #1.2: Type: text/html, Size: 11404 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
@ 2012-10-10 18:22           ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10 18:22 UTC (permalink / raw)
  To: linux-arm-kernel

Dnia ?roda, 10 pa?dziernika 2012 11:12:53 Tony Lindgren pisze:
> * Stephen Warren <swarren@wwwdotorg.org> [121010 09:36]:
> > On 10/10/2012 01:26 AM, Linus Walleij wrote:
> > > On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> 
wrote:
> > >> Seuqential patches from this series introduce SoC-specific data 
parsing
> > >> from device tree.
> > >> 
> > >> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> > >> replaces them with nodes and properties required for these patches.
> > > 
> > > So to be clear:
> > >> +       pinctrl-bank-types {
> > >> +               bank_off: bank-off {
> > >> +                       samsung,reg-names = "func", "dat", "pud",
> > >> +                                               "drv", "conpdn",
> > >> "pudpdn";
> > >> +                       samsung,reg-params = <0x00 4>, <0x04 1>, 
<0x08
> > >> 2>,
> > >> +                                               <0x0C 2>, <0x10 2>,
> > >> <0x14 2>; +               };
> > > 
> > > This is starting to look like a firmware language, I have mixed
> > > feelings about this. Shall this be read:
> > > 
> > > "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> > > 
> > > We really need to discuss this, Grant has already NACK:ed
> > > such approaches once.
> > 
> > Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
> > which is doing this exact same thing. I did raise the same point about
> > Tony's driver when he posted it, but nobody seemed inclined to NACK it
> > based on that at the time, IIRC...
> 
> To summarize, using reg value pairs in DT makes sense if the amount
> of data is huge. Otherwise we'll be describing indidual hardware bits
> as properties in DT, or have to have huge amounts of static data in
> the kernel.
> 
> Where it does not make sense is if there's a sequence of reads
> and writes with test loops in between.. But that's does not look
> to be the case here.
> 
> The reg value pairs will be readable when the DT preprocessing is
> available, and that allows the values to be orred together while
> DT properties don't. The alternative is to describe hardware register
> bits as DT properties, which is very bloated.
> 
> But considering all this.. Are the samsung,reg-names really needed
> by the kernel?

They are used to specify which registers are defined in reg-params property 
and in which order. Most of the registers are not mandatory and this is 
needed to be able to specify only those that are present. At least I 
couldn't think of a better solution for this. Do you have some suggestions?

Best regards,
Tomasz Figa
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121010/8a94d561/attachment-0001.html>

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

* Re: [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
  2012-10-10 18:12         ` Tony Lindgren
@ 2012-10-10 18:26           ` Tomasz Figa
  -1 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10 18:26 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Stephen Warren, Linus Walleij, kgene.kim, kyungmin.park,
	linux-samsung-soc, devicetree-discuss, linux-arm-kernel,
	m.szyprowski

Dnia środa, 10 października 2012 11:12:53 Tony Lindgren pisze:
> * Stephen Warren <swarren@wwwdotorg.org> [121010 09:36]:
> > On 10/10/2012 01:26 AM, Linus Walleij wrote:
> > > On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> 
wrote:
> > >> Seuqential patches from this series introduce SoC-specific data
> > >> parsing
> > >> from device tree.
> > >> 
> > >> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> > >> replaces them with nodes and properties required for these patches.
> > > 
> > > So to be clear:
> > >> +       pinctrl-bank-types {
> > >> +               bank_off: bank-off {
> > >> +                       samsung,reg-names = "func", "dat", "pud",
> > >> +                                               "drv", "conpdn",
> > >> "pudpdn"; +                       samsung,reg-params = <0x00 4>,
> > >> <0x04 1>, <0x08 2>, +                                              
> > >> <0x0C 2>, <0x10 2>, <0x14 2>; +               };
> > > 
> > > This is starting to look like a firmware language, I have mixed
> > > feelings about this. Shall this be read:
> > > 
> > > "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> > > 
> > > We really need to discuss this, Grant has already NACK:ed
> > > such approaches once.
> > 
> > Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
> > which is doing this exact same thing. I did raise the same point about
> > Tony's driver when he posted it, but nobody seemed inclined to NACK it
> > based on that at the time, IIRC...
> 
> To summarize, using reg value pairs in DT makes sense if the amount
> of data is huge. Otherwise we'll be describing indidual hardware bits
> as properties in DT, or have to have huge amounts of static data in
> the kernel.
> 
> Where it does not make sense is if there's a sequence of reads
> and writes with test loops in between.. But that's does not look
> to be the case here.
> 
> The reg value pairs will be readable when the DT preprocessing is
> available, and that allows the values to be orred together while
> DT properties don't. The alternative is to describe hardware register
> bits as DT properties, which is very bloated.
> 
> But considering all this.. Are the samsung,reg-names really needed
> by the kernel?

They are used to specify which registers are defined in reg-params property 
and in which order. Most of the registers are not mandatory and this is 
needed to be able to specify only those that are present. At least I 
couldn't think of a better solution for this. Do you have some suggestions?
 
Best regards,
Tomasz Figa

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

* [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes
@ 2012-10-10 18:26           ` Tomasz Figa
  0 siblings, 0 replies; 80+ messages in thread
From: Tomasz Figa @ 2012-10-10 18:26 UTC (permalink / raw)
  To: linux-arm-kernel

Dnia ?roda, 10 pa?dziernika 2012 11:12:53 Tony Lindgren pisze:
> * Stephen Warren <swarren@wwwdotorg.org> [121010 09:36]:
> > On 10/10/2012 01:26 AM, Linus Walleij wrote:
> > > On Mon, Oct 8, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> 
wrote:
> > >> Seuqential patches from this series introduce SoC-specific data
> > >> parsing
> > >> from device tree.
> > >> 
> > >> This patch removes legacy GPIO bank nodes from exynos4210.dtsi and
> > >> replaces them with nodes and properties required for these patches.
> > > 
> > > So to be clear:
> > >> +       pinctrl-bank-types {
> > >> +               bank_off: bank-off {
> > >> +                       samsung,reg-names = "func", "dat", "pud",
> > >> +                                               "drv", "conpdn",
> > >> "pudpdn"; +                       samsung,reg-params = <0x00 4>,
> > >> <0x04 1>, <0x08 2>, +                                              
> > >> <0x0C 2>, <0x10 2>, <0x14 2>; +               };
> > > 
> > > This is starting to look like a firmware language, I have mixed
> > > feelings about this. Shall this be read:
> > > 
> > > "Poke 4 into 0x00, poke 1 into 0x04, poke 2 into 0x08" etc?
> > > 
> > > We really need to discuss this, Grant has already NACK:ed
> > > such approaches once.
> > 
> > Well, I don't think he NACK'd Tony Lindgren's generic pinctrl driver,
> > which is doing this exact same thing. I did raise the same point about
> > Tony's driver when he posted it, but nobody seemed inclined to NACK it
> > based on that at the time, IIRC...
> 
> To summarize, using reg value pairs in DT makes sense if the amount
> of data is huge. Otherwise we'll be describing indidual hardware bits
> as properties in DT, or have to have huge amounts of static data in
> the kernel.
> 
> Where it does not make sense is if there's a sequence of reads
> and writes with test loops in between.. But that's does not look
> to be the case here.
> 
> The reg value pairs will be readable when the DT preprocessing is
> available, and that allows the values to be orred together while
> DT properties don't. The alternative is to describe hardware register
> bits as DT properties, which is very bloated.
> 
> But considering all this.. Are the samsung,reg-names really needed
> by the kernel?

They are used to specify which registers are defined in reg-params property 
and in which order. Most of the registers are not mandatory and this is 
needed to be able to specify only those that are present. At least I 
couldn't think of a better solution for this. Do you have some suggestions?
 
Best regards,
Tomasz Figa

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

* Re: [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
  2012-10-10 15:22     ` Tomasz Figa
@ 2012-10-11 13:48       ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-11 13:48 UTC (permalink / raw)
  To: Tomasz Figa, Thomas Abraham
  Cc: linux-arm-kernel, linux-samsung-soc, devicetree-discuss,
	kgene.kim, swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Wed, Oct 10, 2012 at 5:22 PM, Tomasz Figa <t.figa@samsung.com> wrote:

> I have managed to rework the changes to drop (1). I will send next version
> of patches tomorrow. It would be nice to have them merged for 3.7, as they
> are rather important for further work.
>
> Moving data from the driver to device tree is not as important, so it might
> be discussed later.

Thanks! :-D

I'll look at it now... I still would really like to see Mr. Abraham's
ACK on this before I merge any of it.

Yours,
Linus Walleij

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

* [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements
@ 2012-10-11 13:48       ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-11 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 10, 2012 at 5:22 PM, Tomasz Figa <t.figa@samsung.com> wrote:

> I have managed to rework the changes to drop (1). I will send next version
> of patches tomorrow. It would be nice to have them merged for 3.7, as they
> are rather important for further work.
>
> Moving data from the driver to device tree is not as important, so it might
> be discussed later.

Thanks! :-D

I'll look at it now... I still would really like to see Mr. Abraham's
ACK on this before I merge any of it.

Yours,
Linus Walleij

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

* Re: [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
  2012-10-10  8:39       ` Tomasz Figa
@ 2012-10-11 13:52         ` Linus Walleij
  -1 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-11 13:52 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: ext Tony Lindgren, Grant Likely, linux-arm-kernel,
	linux-samsung-soc, devicetree-discuss, kgene.kim, thomas.abraham,
	swarren, kyungmin.park, m.szyprowski, tomasz.figa

On Wed, Oct 10, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> On Wednesday 10 of October 2012 09:34:05 Linus Walleij wrote:

>> If you will end up with a hybrid approach with some
>> stuff in the device tree and some stuff in the code,
>> it's better to keep the old driver.
>
> This will allow us to cover all the existing Samsung SoCs, starting from
> S3C24xx, through S3C64xx, S5P*, all supported Exynos SoCs and ending on any
> future SoCs using this kind of pin controller, without bloating the driver
> with hardly readable macros, lots of (often duplicated) static data and
> similar.

I do not agree with this, as you probably have realized by now...

I think it's better to use the compatible string to choose the offset
variable directly in the driver. But hey, it's just me, still.

> If there are some serious problems with this approach, just let me know and
> I will reconsider it, but if not, I'd like to keep it, because of the
> benefits it gives.

I'd like some input from Thomas Abraham before I make up my
mind about it.

Yours,
Linus Walleij

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

* [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT
@ 2012-10-11 13:52         ` Linus Walleij
  0 siblings, 0 replies; 80+ messages in thread
From: Linus Walleij @ 2012-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 10, 2012 at 10:39 AM, Tomasz Figa <t.figa@samsung.com> wrote:
> On Wednesday 10 of October 2012 09:34:05 Linus Walleij wrote:

>> If you will end up with a hybrid approach with some
>> stuff in the device tree and some stuff in the code,
>> it's better to keep the old driver.
>
> This will allow us to cover all the existing Samsung SoCs, starting from
> S3C24xx, through S3C64xx, S5P*, all supported Exynos SoCs and ending on any
> future SoCs using this kind of pin controller, without bloating the driver
> with hardly readable macros, lots of (often duplicated) static data and
> similar.

I do not agree with this, as you probably have realized by now...

I think it's better to use the compatible string to choose the offset
variable directly in the driver. But hey, it's just me, still.

> If there are some serious problems with this approach, just let me know and
> I will reconsider it, but if not, I'd like to keep it, because of the
> benefits it gives.

I'd like some input from Thomas Abraham before I make up my
mind about it.

Yours,
Linus Walleij

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

end of thread, other threads:[~2012-10-11 13:52 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-08  8:39 [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements Tomasz Figa
2012-10-08  8:39 ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 01/16] ARM: dts: exynos4210: Replace legacy GPIO bank nodes with pinctrl bank nodes Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:26   ` Linus Walleij
2012-10-10  7:26     ` Linus Walleij
2012-10-10  8:20     ` Tomasz Figa
2012-10-10  8:20       ` Tomasz Figa
2012-10-10 16:27     ` Stephen Warren
2012-10-10 16:27       ` Stephen Warren
2012-10-10 18:12       ` Tony Lindgren
2012-10-10 18:12         ` Tony Lindgren
2012-10-10 18:22         ` Tomasz Figa
2012-10-10 18:22           ` Tomasz Figa
2012-10-10 18:26         ` Tomasz Figa
2012-10-10 18:26           ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 02/16] pinctrl: exynos: Parse wakeup-eint parameters from DT Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:18   ` Linus Walleij
2012-10-10  7:18     ` Linus Walleij
2012-10-10  8:23     ` Tomasz Figa
2012-10-10  8:23       ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 03/16] pinctrl: samsung: Detect and handle unsupported configuration types Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:37   ` Linus Walleij
2012-10-10  7:37     ` Linus Walleij
2012-10-10  8:25     ` Tomasz Figa
2012-10-10  8:25       ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 04/16] pinctrl: samsung: Parse pin banks from DT Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:34   ` Linus Walleij
2012-10-10  7:34     ` Linus Walleij
2012-10-10  8:39     ` Tomasz Figa
2012-10-10  8:39       ` Tomasz Figa
2012-10-11 13:52       ` Linus Walleij
2012-10-11 13:52         ` Linus Walleij
2012-10-08  8:39 ` [PATCH 05/16] pinctrl: exynos: Remove static SoC-specific data Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 06/16] pinctrl: samsung: Parse bank-specific eint offset from DT Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 07/16] pinctrl: samsung: Hold OF node of pin bank in bank struct Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 08/16] pinctrl: samsung: Hold pointer to driver data " Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 09/16] pinctrl: exynos: Use one IRQ domain per pin bank Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:40   ` Linus Walleij
2012-10-10  7:40     ` Linus Walleij
2012-10-10  8:45     ` Tomasz Figa
2012-10-10  8:45       ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 10/16] pinctrl: samsung: Do not pass gpio_chip to pin_to_reg_bank Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:42   ` Linus Walleij
2012-10-10  7:42     ` Linus Walleij
2012-10-10  8:51     ` Tomasz Figa
2012-10-10  8:51       ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 11/16] pinctrl: samsung: Use one GPIO chip per pin bank Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:43   ` Linus Walleij
2012-10-10  7:43     ` Linus Walleij
2012-10-10  8:49     ` Tomasz Figa
2012-10-10  8:49       ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 12/16] pinctrl: samsung: Use per-bank IRQ domain for wake-up interrupts Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 13/16] pinctrl: exynos: Set pin function to EINT in irq_set_type of wake-up EINT Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 14/16] pinctrl: samsung: Parse offsets of particular registers from DT Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 15/16] pinctrl: samsung: Add GPIO to IRQ translation Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-08  8:39 ` [PATCH 16/16] Documentation: Update samsung-pinctrl device tree bindings documentation Tomasz Figa
2012-10-08  8:39   ` Tomasz Figa
2012-10-10  7:46 ` [PATCH 00/16] pinctrl: samsung: Usability and extensibiltiy improvements Linus Walleij
2012-10-10  7:46   ` Linus Walleij
     [not found]   ` <CACRpkdbUmM2=vhjhCq_qN2v=8RUDeWV4b8A8oXXPE4e8Z9C7zg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-10-10  9:04     ` Tomasz Figa
2012-10-10  9:04       ` Tomasz Figa
2012-10-10 15:22   ` Tomasz Figa
2012-10-10 15:22     ` Tomasz Figa
2012-10-11 13:48     ` Linus Walleij
2012-10-11 13:48       ` 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.