* [GIT PULL] Ux500 pin changes
From: Linus Walleij @ 2012-11-08 8:28 UTC (permalink / raw)
To: linux-arm-kernel
Hi ARM SoC guys,
here is a set of pinctrl table patches all just hitting one and the same ux500
file. Description in the signed tag, intended for v3.8.
Please pull them in!
Yours,
Linus Walleij
The following changes since commit ddffeb8c4d0331609ef2581d84de4d763607bd37:
Linux 3.7-rc1 (2012-10-14 14:41:04 -0700)
are available in the git repository at:
http://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
tags/ux500-pins-for-arm-soc
for you to fetch changes up to d792aebfa2daeb58ac6a669ce328ad05e9e4112c:
ARM: ux500: fixup magnetometer pins (2012-11-06 11:10:55 +0100)
----------------------------------------------------------------
Ux500 pinctrl table update for v3.8, basically accumulated
updates to pin muxing and biasing from internal deployment
and regression testing for power performance.
----------------------------------------------------------------
Jean-Nicolas Graux (1):
ARM: ux500: add STM pin configuration
Jorgen Jonsson (1):
ARM: ux500: fixup magnetometer pins
Linus Walleij (1):
ARM: ux500: delete duplicate macro
Patrice Chotard (6):
ARM: ux500: 8500: register LCD VSI pinctrl table
ARM: ux500: 8500: add IDLE pin configuration for SPI
ARM: ux500: 8500: update SKE keypad pinctrl table
ARM: ux500: 8500: define SDI sleep states
ARM: ux500: cosmetic fixups for uart0
ARM: ux500: 8500: add pinctrl support for uart1 and uart2
arch/arm/mach-ux500/board-mop500-pins.c | 427 +++++++++++++++++++++++++++-----
1 file changed, 362 insertions(+), 65 deletions(-)
^ permalink raw reply
* [PATCH] pwm: lpc32xx - Add a driver for the motor PWM
From: Thierry Reding @ 2012-11-08 8:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <509B6B87.8030102@antcom.de>
On Thu, Nov 08, 2012 at 09:21:27AM +0100, Roland Stigge wrote:
> On 07/11/12 21:30, Thierry Reding wrote:
> > On Wed, Nov 07, 2012 at 06:19:38PM +0100, Roland Stigge wrote:
> >> On 07/11/12 17:30, Alban Bedel wrote:
> >>> Signed-off-by: Alban Bedel <alban.bedel@avionic-design.de> ---
> >>> .../devicetree/bindings/pwm/lpc32xx-motor-pwm.txt | 24 ++
> >>> arch/arm/boot/dts/lpc32xx.dtsi | 7 +
> >>
> >> Is all this supposed to go via mach-lpc32xx -> arm-soc.git? Then,
> >> I can take this into the lpc32xx tree. Otherwise, you can split
> >> off the .dtsi file and I include it via lpc32xx.
> >
> > I'd prefer a split between the arch/arm changes and the rest. I'll
> > take the drivers/pwm and Documentation changes through the PWM
> > tree.
>
> OK, I'll organize everything lpc32xx specific under arch/arm/
Alban, I haven't finished reviewing yet, but once I'm done, can you
resubmit a set of two patches split by arch/arm and the rest?
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121108/e75de120/attachment.sig>
^ permalink raw reply
* [PATCH 6/7] ARM: u300: remove obsoleted init_consistent_dma_size()
From: Linus Walleij @ 2012-11-08 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352360783-17523-7-git-send-email-m.szyprowski@samsung.com>
On Thu, Nov 8, 2012 at 8:46 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> CC: Linus Walleij <linus.walleij@linaro.org>
> ---
> arch/arm/mach-u300/core.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
> index b8efac4..d8632eb 100644
> --- a/arch/arm/mach-u300/core.c
> +++ b/arch/arm/mach-u300/core.c
> @@ -82,8 +82,6 @@ static struct map_desc u300_io_desc[] __initdata = {
> static void __init u300_map_io(void)
> {
> iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
> - /* We enable a real big DMA buffer if need be. */
> - init_consistent_dma_size(SZ_4M);
> }
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH] pwm: lpc32xx - Add a driver for the motor PWM
From: Roland Stigge @ 2012-11-08 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121107203028.GA6186@avionic-0098.mockup.avionic-design.de>
On 07/11/12 21:30, Thierry Reding wrote:
> On Wed, Nov 07, 2012 at 06:19:38PM +0100, Roland Stigge wrote:
>> On 07/11/12 17:30, Alban Bedel wrote:
>>> Signed-off-by: Alban Bedel <alban.bedel@avionic-design.de> ---
>>> .../devicetree/bindings/pwm/lpc32xx-motor-pwm.txt | 24 ++
>>> arch/arm/boot/dts/lpc32xx.dtsi | 7 +
>>
>> Is all this supposed to go via mach-lpc32xx -> arm-soc.git? Then,
>> I can take this into the lpc32xx tree. Otherwise, you can split
>> off the .dtsi file and I include it via lpc32xx.
>
> I'd prefer a split between the arch/arm changes and the rest. I'll
> take the drivers/pwm and Documentation changes through the PWM
> tree.
OK, I'll organize everything lpc32xx specific under arch/arm/
Thanks,
Roland
^ permalink raw reply
* [PATCH v2 2/2] ARM: Exynos5250: Enabling ohci-exynos driver
From: Vivek Gautam @ 2012-11-08 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAFp+6iH20vwDit-=wk=HfPDArjr_Kuoj5AaVgTv_drjjz+23zQ@mail.gmail.com>
Adding OHCI device tree node for Exynos5250 along with
the device base address.
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---
.../devicetree/bindings/usb/exynos-usb.txt | 15 +++++++++++++++
arch/arm/boot/dts/exynos5250.dtsi | 6 ++++++
arch/arm/mach-exynos/include/mach/map.h | 1 +
arch/arm/mach-exynos/mach-exynos5-dt.c | 2 ++
4 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
index 833f5cf..5ff3def1 100644
--- a/Documentation/devicetree/bindings/usb/exynos-usb.txt
+++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt
@@ -23,3 +23,18 @@ Example:
interrupts = <0 71 0>;
samsung,vbus-gpio = <&gpx2 6 1 3 3>;
};
+
+OHCI
+Required properties:
+ - compatible: should be "samsung,exynos-ohci" for USB 2.0
+ OHCI companion controller in host mode.
+ - reg: physical base address of the controller and length of memory mapped
+ region.
+ - interrupts: interrupt number to the cpu.
+
+Example:
+ usb at 12120000 {
+ compatible = "samsung,exynos-ohci";
+ reg = <0x12120000 0x100>;
+ interrupts = <0 71 0>;
+ };
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 2995445..f18abe0 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -244,6 +244,12 @@
interrupts = <0 71 0>;
};
+ usb at 12120000 {
+ compatible = "samsung,exynos-ohci";
+ reg = <0x12120000 0x100>;
+ interrupts = <0 71 0>;
+ };
+
amba {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 9a86b99..471ffaf 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -198,6 +198,7 @@
#define EXYNOS4_PA_OHCI 0x12590000
#define EXYNOS4_PA_HSPHY 0x125B0000
#define EXYNOS5_PA_EHCI 0x12110000
+#define EXYNOS5_PA_OHCI 0x12120000
#define EXYNOS4_PA_MFC 0x13400000
#define EXYNOS4_PA_UART 0x13800000
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index 89fa624..c03f3dd 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -88,6 +88,8 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
"exynos5-mixer", NULL),
OF_DEV_AUXDATA("samsung,exynos-ehci", EXYNOS5_PA_EHCI,
"s5p-ehci", NULL),
+ OF_DEV_AUXDATA("samsung,exynos-ohci", EXYNOS5_PA_OHCI,
+ "exynos-ohci", NULL),
{},
};
--
1.7.6.5
^ permalink raw reply related
* [PATCH v2 1/2] ARM: Exynos5250: Enabling ehci-s5p driver
From: Vivek Gautam @ 2012-11-08 8:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAFp+6iEwbw5jw_JiUosfZYykFNdbnh+OW6-RrJ7NnYN8csUJmw@mail.gmail.com>
Adding EHCI device tree node for Exynos5250 along with
the device base adress and gpio line for vbus.
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---
.../devicetree/bindings/usb/exynos-usb.txt | 25 ++++++++++++++++++++
arch/arm/boot/dts/exynos5250-smdk5250.dts | 4 +++
arch/arm/boot/dts/exynos5250.dtsi | 6 ++++
arch/arm/mach-exynos/include/mach/map.h | 1 +
arch/arm/mach-exynos/mach-exynos5-dt.c | 2 +
5 files changed, 38 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/exynos-usb.txt
diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
new file mode 100644
index 0000000..833f5cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt
@@ -0,0 +1,25 @@
+Samsung Exynos SoC USB controller
+
+The USB devices interface with USB controllers on Exynos SOCs.
+The device node has following properties.
+
+EHCI
+Required properties:
+ - compatible: should be "samsung,exynos-ehci" for USB 2.0
+ EHCI controller in host mode.
+ - reg: physical base address of the controller and length of memory mapped
+ region.
+ - interrupts: interrupt number to the cpu.
+
+Optional properties:
+ - samsung,vbus-gpio: if present, specifies the GPIO that
+ needs to be pulled up for the bus to be powered.
+
+Example:
+
+ usb at 12110000 {
+ compatible = "samsung,exynos-ehci";
+ reg = <0x12110000 0x100>;
+ interrupts = <0 71 0>;
+ samsung,vbus-gpio = <&gpx2 6 1 3 3>;
+ };
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 405009c..7c8064f 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -193,4 +193,8 @@
hdmi {
hpd-gpio = <&gpx3 7 0xf 1 3>;
};
+
+ usb at 12110000 {
+ samsung,vbus-gpio = <&gpx2 6 1 3 3>;
+ };
};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index cf6a02d..2995445 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -238,6 +238,12 @@
#size-cells = <0>;
};
+ usb at 12110000 {
+ compatible = "samsung,exynos-ehci";
+ reg = <0x12110000 0x100>;
+ interrupts = <0 71 0>;
+ };
+
amba {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index ef4958b..9a86b99 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -197,6 +197,7 @@
#define EXYNOS4_PA_EHCI 0x12580000
#define EXYNOS4_PA_OHCI 0x12590000
#define EXYNOS4_PA_HSPHY 0x125B0000
+#define EXYNOS5_PA_EHCI 0x12110000
#define EXYNOS4_PA_MFC 0x13400000
#define EXYNOS4_PA_UART 0x13800000
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index ed37273..89fa624 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -86,6 +86,8 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
"exynos5-hdmi", NULL),
OF_DEV_AUXDATA("samsung,exynos5-mixer", 0x14450000,
"exynos5-mixer", NULL),
+ OF_DEV_AUXDATA("samsung,exynos-ehci", EXYNOS5_PA_EHCI,
+ "s5p-ehci", NULL),
{},
};
--
1.7.6.5
^ permalink raw reply related
* [PATCH v2 2/2] ARM: Exynos5250: Enabling ohci-exynos driver
From: Vivek Gautam @ 2012-11-08 8:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352357665-7435-3-git-send-email-gautam.vivek@samsung.com>
Hi all,
On Thu, Nov 8, 2012 at 12:24 PM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Adding OHCI device tree node for Exynos5250 along with
> the device base address.
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> ---
> .../devicetree/bindings/usb/exynos-usb.txt | 15 +++++++++++++++
> arch/arm/boot/dts/exynos5250.dtsi | 6 ++++++
> arch/arm/mach-exynos/include/mach/map.h | 1 +
> arch/arm/mach-exynos/mach-exynos5-dt.c | 2 ++
> 4 files changed, 24 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
> index 833f5cf..5ff3def1 100644
> --- a/Documentation/devicetree/bindings/usb/exynos-usb.txt
> +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt
> @@ -23,3 +23,18 @@ Example:
> interrupts = <0 71 0>;
> samsung,vbus-gpio = <&gpx2 6 1 3 3>;
> };
> +
> +OHCI
> +Required properties:
> + - compatible: should be "samsung,exynos-ohci" for USB 2.0
> + OHCI companion controller in host mode.
> + - reg: physical base address of the controller and length of memory mapped
> + region.
> + - interrupts: interrupt number to the cpu.
> +
> +Example:
> + usb at 12120000 {
> + compatible = "samsung,exynos-ohci";
> + reg = <0x12120000 0x100>;
> + interrupts = <0 71 0>;
> + };
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> index 2995445..f18abe0 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -244,6 +244,12 @@
> interrupts = <0 71 0>;
> };
>
> + usb at 12120000 {
> + compatible = "samsung,exynos-ohci";
> + reg = <0x12120000 0x100>;
> + interrupts = <0 71 0>;
> + };
> +
> amba {
> #address-cells = <1>;
> #size-cells = <1>;
> diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
> index 9a86b99..471ffaf 100644
> --- a/arch/arm/mach-exynos/include/mach/map.h
> +++ b/arch/arm/mach-exynos/include/mach/map.h
> @@ -198,6 +198,7 @@
> #define EXYNOS4_PA_OHCI 0x12590000
> #define EXYNOS4_PA_HSPHY 0x125B0000
> #define EXYNOS5_PA_EHCI 0x12110000
> +#define EXYNOS5_PA_OHCI 0x12120000
> #define EXYNOS4_PA_MFC 0x13400000
>
> #define EXYNOS4_PA_UART 0x13800000
> diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
> index f60994e..6348acb 100644
> --- a/arch/arm/mach-exynos/mach-exynos5-dt.c
> +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
> @@ -88,6 +88,8 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
> "exynos5-mixer", NULL),
> OF_DEV_AUXDATA("samsung,exynos-ehci", EXYNOS5_PA_EHCI,
> "s5p-ehci", NULL),
> + OF_DEV_AUXDATA("samsung,exynos-ohci", EXYNOS5_PA_OHCI,
> + "exynos-ohci", NULL),
missed the alignment here :-(
> {},
> };
>
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Thanks & Regards
Vivek
^ permalink raw reply
* No subject
From: Abhimanyu Kapur @ 2012-11-08 8:07 UTC (permalink / raw)
To: linux-arm-kernel
subscribe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121108/ea49c32b/attachment-0001.html>
^ permalink raw reply
* [PATCH v2 1/2] ARM: Exynos5250: Enabling ehci-s5p driver
From: Vivek Gautam @ 2012-11-08 8:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352357665-7435-2-git-send-email-gautam.vivek@samsung.com>
Hi all,
On Thu, Nov 8, 2012 at 12:24 PM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Adding EHCI device tree node for Exynos5250 along with
> the device base adress and gpio line for vbus.
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> ---
> .../devicetree/bindings/usb/exynos-usb.txt | 25 ++++++++++++++++++++
> arch/arm/boot/dts/exynos5250-smdk5250.dts | 4 +++
> arch/arm/boot/dts/exynos5250.dtsi | 6 ++++
> arch/arm/mach-exynos/include/mach/map.h | 1 +
> arch/arm/mach-exynos/mach-exynos5-dt.c | 2 +
> 5 files changed, 38 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/usb/exynos-usb.txt
>
> diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
> new file mode 100644
> index 0000000..833f5cf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt
> @@ -0,0 +1,25 @@
> +Samsung Exynos SoC USB controller
> +
> +The USB devices interface with USB controllers on Exynos SOCs.
> +The device node has following properties.
> +
> +EHCI
> +Required properties:
> + - compatible: should be "samsung,exynos-ehci" for USB 2.0
> + EHCI controller in host mode.
> + - reg: physical base address of the controller and length of memory mapped
> + region.
> + - interrupts: interrupt number to the cpu.
> +
> +Optional properties:
> + - samsung,vbus-gpio: if present, specifies the GPIO that
> + needs to be pulled up for the bus to be powered.
> +
> +Example:
> +
> + usb at 12110000 {
> + compatible = "samsung,exynos-ehci";
> + reg = <0x12110000 0x100>;
> + interrupts = <0 71 0>;
> + samsung,vbus-gpio = <&gpx2 6 1 3 3>;
> + };
> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> index 405009c..7c8064f 100644
> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> @@ -193,4 +193,8 @@
> hdmi {
> hpd-gpio = <&gpx3 7 0xf 1 3>;
> };
> +
> + usb at 12110000 {
> + samsung,vbus-gpio = <&gpx2 6 1 3 3>;
> + };
> };
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> index cf6a02d..2995445 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -238,6 +238,12 @@
> #size-cells = <0>;
> };
>
> + usb at 12110000 {
> + compatible = "samsung,exynos-ehci";
> + reg = <0x12110000 0x100>;
> + interrupts = <0 71 0>;
> + };
> +
> amba {
> #address-cells = <1>;
> #size-cells = <1>;
> diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
> index ef4958b..9a86b99 100644
> --- a/arch/arm/mach-exynos/include/mach/map.h
> +++ b/arch/arm/mach-exynos/include/mach/map.h
> @@ -197,6 +197,7 @@
> #define EXYNOS4_PA_EHCI 0x12580000
> #define EXYNOS4_PA_OHCI 0x12590000
> #define EXYNOS4_PA_HSPHY 0x125B0000
> +#define EXYNOS5_PA_EHCI 0x12110000
> #define EXYNOS4_PA_MFC 0x13400000
>
> #define EXYNOS4_PA_UART 0x13800000
> diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
> index ed37273..f60994e 100644
> --- a/arch/arm/mach-exynos/mach-exynos5-dt.c
> +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
> @@ -86,6 +86,8 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
> "exynos5-hdmi", NULL),
> OF_DEV_AUXDATA("samsung,exynos5-mixer", 0x14450000,
> "exynos5-mixer", NULL),
> + OF_DEV_AUXDATA("samsung,exynos-ehci", EXYNOS5_PA_EHCI,
> + "s5p-ehci", NULL),
missed the alignment here :-(
> {},
> };
>
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Thanks & Regards
Vivek
^ permalink raw reply
* [PATCH] ARM: OMAP2+: timer: remove CONFIG_OMAP_32K_TIMER
From: Igor Grinberg @ 2012-11-08 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <509AD478.1050904@ti.com>
On 11/07/12 23:36, Jon Hunter wrote:
> Hi Igor,
>
> On 11/07/2012 08:42 AM, Igor Grinberg wrote:
>> CONFIG_OMAP_32K_TIMER is kind of standing on the single zImage way.
>> Make OMAP2+ timer code independant from the CONFIG_OMAP_32K_TIMER
>> setting.
>> To remove the dependancy, several conversions/additions had to be done:
>> 1) Timer structures and initialization functions are named by the platform
>> name and the clock source in use. The decision which timer is
>> used is done statically from the machine_desc structure. In the
>> future it should come from DT.
>> 2) Settings under the CONFIG_OMAP_32K_TIMER option are expanded into
>> separate timer structures along with the timer init functions.
>> This removes the CONFIG_OMAP_32K_TIMER on OMAP2+ timer code.
>> 3) Since we have all the timers defined inside machine_desc structure
>> and we no longer need the fallback to gp_timer clock source in case
>> 32k_timer clock source is unavailable (namely on AM33xx), we no
>> longer need the #ifdef around __omap2_sync32k_clocksource_init()
>> function. Remove the #ifdef CONFIG_OMAP_32K_TIMER around the
>> __omap2_sync32k_clocksource_init() function.
>>
>> Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
>> Cc: Jon Hunter <jon-hunter@ti.com>
>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>
> [snip]
>
>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>> index 684d2fc..a4ad7a0 100644
>> --- a/arch/arm/mach-omap2/timer.c
>> +++ b/arch/arm/mach-omap2/timer.c
>> @@ -63,20 +63,8 @@
>> #define OMAP2_32K_SOURCE "func_32k_ck"
>> #define OMAP3_32K_SOURCE "omap_32k_fck"
>> #define OMAP4_32K_SOURCE "sys_32k_ck"
>> -
>> -#ifdef CONFIG_OMAP_32K_TIMER
>> -#define OMAP2_CLKEV_SOURCE OMAP2_32K_SOURCE
>> -#define OMAP3_CLKEV_SOURCE OMAP3_32K_SOURCE
>> -#define OMAP4_CLKEV_SOURCE OMAP4_32K_SOURCE
>> -#define OMAP3_SECURE_TIMER 12
>> #define TIMER_PROP_SECURE "ti,timer-secure"
>> -#else
>> -#define OMAP2_CLKEV_SOURCE OMAP2_MPU_SOURCE
>> -#define OMAP3_CLKEV_SOURCE OMAP3_MPU_SOURCE
>> -#define OMAP4_CLKEV_SOURCE OMAP4_MPU_SOURCE
>> -#define OMAP3_SECURE_TIMER 1
>> -#define TIMER_PROP_SECURE "ti,timer-alwon"
>> -#endif
>> +#define TIMER_PROP_ALWON "ti,timer-alwon"
>
> Nit-pick, can we drop the TIMER_PROP_SECURE/ALWON and use the
> "ti,timer-secure" and "ti,timer-alwon" directly?
>
> Initially, I also defined TIMER_PROP_ALWON and Rob Herring's feedback
> was to drop this and use the property string directly to remove any
> abstraction.
Well, I don't understand what do you mean by "any abstraction".
The purpose of defining those two was to eliminate multiple occurrences
of the string in the code, so for example if someone decides to change the
property string for some currently unknown reason - it will be easy and small.
Defines are a common practice for that, no?
If you still think it should be inlined, I will do.
>
>> #define REALTIME_COUNTER_BASE 0x48243200
>> #define INCREMENTER_NUMERATOR_OFFSET 0x10
>> @@ -216,7 +204,7 @@ void __init omap_dmtimer_init(void)
>>
>> /* If we are a secure device, remove any secure timer nodes */
>> if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) {
>> - np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure");
>> + np = omap_get_timer_dt(omap_timer_match, TIMER_PROP_SECURE);
>> if (np)
>> of_node_put(np);
>> }
>> @@ -378,9 +366,8 @@ static u32 notrace dmtimer_read_sched_clock(void)
>> return 0;
>> }
>>
>> -#ifdef CONFIG_OMAP_32K_TIMER
>> /* Setup free-running counter for clocksource */
>> -static int __init omap2_sync32k_clocksource_init(void)
>> +static int __init __omap2_sync32k_clocksource_init(void)
>
> Not sure I follow why you renamed this function here ...
I didn't want to add unused arguments to this function, so I've made a
wrapper below to have both the sync32k and the gp functions have the same
signature (argument list) and be called from a single macro.
Anyway, see below.
>
>> {
>> int ret;
>> struct device_node *np = NULL;
>> @@ -439,15 +426,9 @@ static int __init omap2_sync32k_clocksource_init(void)
>>
>> return ret;
>> }
>> -#else
>> -static inline int omap2_sync32k_clocksource_init(void)
>> -{
>> - return -ENODEV;
>> -}
>> -#endif
>>
>> -static void __init omap2_gptimer_clocksource_init(int gptimer_id,
>> - const char *fck_source)
>> +static void __init omap2_gp_clocksource_init(int gptimer_id,
>> + const char *fck_source)
>
> Nit, I personally prefer keeping gptimer, because gp just means
> "general-purpose" and does not imply a timer per-se.
I've made this change, so we will not get something like:
omapx_gptimer_timer_init(), but this really does not meter to me,
so no problem will do for v2.
>
>> {
>> int res;
>>
>> @@ -466,23 +447,10 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
>> gptimer_id, clksrc.rate);
>> }
>>
>> -static void __init omap2_clocksource_init(int gptimer_id,
>> - const char *fck_source)
>> +static void __init omap2_sync32k_clocksource_init(int gptimer_id,
>> + const char *fck_source)
>> {
>> - /*
>> - * First give preference to kernel parameter configuration
>> - * by user (clocksource="gp_timer").
>> - *
>> - * In case of missing kernel parameter for clocksource,
>> - * first check for availability for 32k-sync timer, in case
>> - * of failure in finding 32k_counter module or registering
>> - * it as clocksource, execution will fallback to gp-timer.
>> - */
>> - if (use_gptimer_clksrc == true)
>> - omap2_gptimer_clocksource_init(gptimer_id, fck_source);
>> - else if (omap2_sync32k_clocksource_init())
>> - /* Fall back to gp-timer code */
>> - omap2_gptimer_clocksource_init(gptimer_id, fck_source);
>> + __omap2_sync32k_clocksource_init();
>> }
>
> ... this just appears to be a wrapper function, but I don't see why this
> is needed? Do we need this wrapper?
no, not really, just consider the explanation above.
I will remove the wrapper for v2.
>
>> #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
>> @@ -563,52 +531,64 @@ static inline void __init realtime_counter_init(void)
>> {}
>> #endif
>>
>> -#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
>> - clksrc_nr, clksrc_src) \
>> -static void __init omap##name##_timer_init(void) \
>> +#define OMAP_SYS_TIMER_INIT(n, clksrc_name, clkev_nr, clkev_src, \
>> + clkev_prop, clksrc_nr, clksrc_src) \
>> +static void __init omap##n##_##clksrc_name##_timer_init(void) \
>
>
>> { \
>> omap_dmtimer_init(); \
>> omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
>> - omap2_clocksource_init((clksrc_nr), clksrc_src); \
>> + \
>> + if (use_gptimer_clksrc) \
>> + omap2_gp_clocksource_init((clksrc_nr), clksrc_src); \
>> + else \
>> + omap2_##clksrc_name##_clocksource_init((clksrc_nr), \
>> + clksrc_src); \
>
> Something here seems a little odd. If "clksrc_name" is "gp", then the
> if-else parts will call the same function. Or am I missing something here?
Yes, you are right - this is odd.
What do you think of:
if (use_gptimer_clksrc) {
omap2_gp_clocksource_init((clksrc_nr), clksrc_src);
return;
}
omap2_##clksrc_name##_clocksource_init((clksrc_nr), clksrc_src);
>
> I think that I prefer how it works today where we call just
> omap2_clocksource_init(), and it determines whether to use the gptimer
> or the 32k-sync.
There is no reliable way to determine which source should be used in runtime
for boards that do not have the 32k oscillator wired.
>
> For OMAP I think that it is fine to default to the 32k-sync and then if
> the gptimer is selected, it uses the higher frequency sys_clk as the
> timer source.
I agree for the 32k-sync as a default, but gptimer will not be selected
on SoC that have 32k while board does not have the 32k wired.
>
> For AMxxx, devices, sync-32k does not exist, and so I understand it does
> not work the same.
>
> I am wondering if the use_gptimer_clksrc, should become
> use_sysclk_clksrc, and then ...
>
> For OMAP ...
> use_sysclk_clksrc = 0 --> use sync-32k (default)
> use_sysclk_clksrc = 1 --> use gptimer with sys_clk
>
> For AM33xx ...
> use_sysclk_clksrc = 0 --> use gptimer with 32khz clock (default)
> use_sysclk_clksrc = 1 --> use gptimer with sys_clk
Well, this is more or less how it works today, but it does not consider
the board wiring information that after all defines which source should
be used. (Not all boards out there are clones of beagles and evms...)
And the generic code should be flexible enough
to enable any legal configuration.
>
>> }
>>
>> -#define OMAP_SYS_TIMER(name) \
>> -struct sys_timer omap##name##_timer = { \
>> - .init = omap##name##_timer_init, \
>> -};
>> +#define OMAP_SYS_TIMER(n, clksrc) \
>> +struct sys_timer omap##n##_##clksrc##_timer = { \
>> + .init = omap##n##_##clksrc##_timer_init, \
>> +}
>>
>> #ifdef CONFIG_ARCH_OMAP2
>> -OMAP_SYS_TIMER_INIT(2, 1, OMAP2_CLKEV_SOURCE, "ti,timer-alwon",
>> - 2, OMAP2_MPU_SOURCE)
>> -OMAP_SYS_TIMER(2)
>> +OMAP_SYS_TIMER_INIT(2, sync32k, 1, OMAP2_32K_SOURCE, TIMER_PROP_ALWON,
>> + 2, OMAP2_MPU_SOURCE);
>> +OMAP_SYS_TIMER(2, sync32k);
>> +OMAP_SYS_TIMER_INIT(2, gp, 1, OMAP2_MPU_SOURCE, TIMER_PROP_ALWON,
>> + 2, OMAP2_MPU_SOURCE);
>> +OMAP_SYS_TIMER(2, gp);
>
> It would be good if we can avoid having two timer_init functions for
> each OMAP generation.
Yes, but then we will not have the right description of the hardware
but IMHO workarounds on workarounds on...
There are several clock sources - all can be used,
why not have them described and ready for use?
--
Regards,
Igor.
^ permalink raw reply
* [RFC PATCH v4 2/2] ASoC: sam9g20-wm8731: convert to dt support
From: Bo Shen @ 2012-11-08 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361422-13265-1-git-send-email-voice.shen@atmel.com>
Signed-off-by: Bo Shen <voice.shen@atmel.com>
---
Change since v3 RFC:
Remove dai node, remap ssc in place
without pinctrl added, so don't modify the dtsi file, will be added
soon
Change since v2:
No change
Change since v1:
Add sam9g20-wm8731 binding document
---
.../bindings/sound/atmel-sam9g20-wm8731-audio.txt | 21 ++++++
sound/soc/atmel/Kconfig | 3 +-
sound/soc/atmel/sam9g20_wm8731.c | 71 ++++++++++++++++++--
3 files changed, 88 insertions(+), 7 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/atmel-sam9g20-wm8731-audio.txt
diff --git a/Documentation/devicetree/bindings/sound/atmel-sam9g20-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-sam9g20-wm8731-audio.txt
new file mode 100644
index 0000000..adf7e7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel-sam9g20-wm8731-audio.txt
@@ -0,0 +1,21 @@
+* Atmel sam9g20ek audio complex
+
+Required properties:
+ - compatible: "atmel,at91sam9g20-audio"
+ - atmel,model: The user-visible name of this sound complex.
+ - atmel,audio-routing: A list of the connections between audio components.
+ - atmel,ssc-controller: The phandle of the SSC controller
+ - atmel,audio-codec: The phandle of the WM8731 audio codec
+
+Example:
+sound {
+ compatible = "atmel,at91sam9g20-audio";
+ atmel,model = "wm8731 @ AT91SAMG20EK";
+
+ atmel,audio-routing =
+ "Ext Spk", "LHPOUT",
+ "Int MIC", "MICIN";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8731>;
+};
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 72b09cf..397ec75 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -16,8 +16,7 @@ config SND_ATMEL_SOC_SSC
config SND_AT91_SOC_SAM9G20_WM8731
tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
- depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
- AT91_PROGRAMMABLE_CLOCKS
+ depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS
select SND_ATMEL_SOC_SSC
select SND_SOC_WM8731
help
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index eef6eed..62c3a3d 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -197,14 +197,30 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *codec_np, *cpu_np;
struct clk *pllb;
struct snd_soc_card *card = &snd_soc_at91sam9g20ek;
- int ret;
-
- if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
- return -ENODEV;
+ int ret, id;
+
+ if (np) {
+ cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "codec info missing\n");
+ return -EINVAL;
+ }
+
+ id = of_alias_get_id(cpu_np, "ssc");
+ of_node_put(cpu_np);
+ } else {
+ if (!(machine_is_at91sam9g20ek() ||
+ machine_is_at91sam9g20ek_2mmc()))
+ return -ENODEV;
+
+ id = pdev->id;
+ }
- ret = atmel_ssc_set_audio(pdev->id);
+ ret = atmel_ssc_set_audio(id);
if (ret)
goto err;
@@ -234,6 +250,42 @@ static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
clk_set_rate(mclk, MCLK_RATE);
card->dev = &pdev->dev;
+
+ /* Parse device node info */
+ if (np) {
+ ret = snd_soc_of_parse_card_name(card, "atmel,model");
+ if (ret)
+ goto err;
+
+ ret = snd_soc_of_parse_audio_routing(card,
+ "atmel,audio-routing");
+ if (ret)
+ goto err;
+
+ /* Parse codec info */
+ at91sam9g20ek_dai.codec_name = NULL;
+ codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "codec info missing\n");
+ return -EINVAL;
+ }
+ at91sam9g20ek_dai.codec_of_node = codec_np;
+
+ /* Parse dai and platform info */
+ at91sam9g20ek_dai.cpu_dai_name = NULL;
+ at91sam9g20ek_dai.platform_name = NULL;
+ cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "dai and pcm info missing\n");
+ return -EINVAL;
+ }
+ at91sam9g20ek_dai.cpu_of_node = cpu_np;
+ at91sam9g20ek_dai.platform_of_node = cpu_np;
+
+ of_node_put(codec_np);
+ of_node_put(cpu_np);
+ }
+
ret = snd_soc_register_card(card);
if (ret) {
printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n");
@@ -262,10 +314,19 @@ static int __devexit at91sam9g20ek_audio_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id sam9g20ek_wm8731_dt_ids[] = {
+ { .compatible = "atmel,at91sam9g20-audio", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sam9g20ek_wm8731_dt_ids);
+#endif
+
static struct platform_driver at91sam9g20ek_audio_driver = {
.driver = {
.name = "at91sam9g20ek-audio",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(sam9g20ek_wm8731_dt_ids),
},
.probe = at91sam9g20ek_audio_probe,
.remove = __devexit_p(at91sam9g20ek_audio_remove),
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH v4 1/2] ASoC: atmel-ssc-dai: register dai and pcm directly
From: Bo Shen @ 2012-11-08 7:57 UTC (permalink / raw)
To: linux-arm-kernel
change the method for register dai and pcm
- let the atmel-ssc-dai no longer as a standalone platform device
- remap ssc and then register dai directly
- register pcm from dai directly
Modify the code which related with this change
Signed-off-by: Bo Shen <voice.shen@atmel.com>
---
Change since v3 RFC
- remap ssc and then register dai and pcm directly
Change since v2
- Register dai and pcm directly according to Mark Brown's suggestion
- using name to distinguish ssc register for audio or library
if for audio, the name with dai subfix
if for library, the name without dai subfix
- fix the issue for sam9g20-wm8731
- when register dai and pcm cause the sam9g20-wm8731 doesn't work,
so fix it
- Add device tree support
- Detail information reference atmel-ssc-dai.txt binding document
Change since v1
No change
---
arch/arm/mach-at91/at91sam9260_devices.c | 9 --
arch/arm/mach-at91/board-sam9g20ek.c | 8 +-
sound/soc/atmel/atmel-pcm.c | 23 +--
sound/soc/atmel/atmel-pcm.h | 3 +
sound/soc/atmel/atmel_ssc_dai.c | 228 +++++++-----------------------
sound/soc/atmel/atmel_ssc_dai.h | 1 +
sound/soc/atmel/sam9g20_wm8731.c | 13 +-
7 files changed, 76 insertions(+), 209 deletions(-)
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index df7bebf..6959fd2 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -768,14 +768,6 @@ static inline void configure_ssc_pins(unsigned pins)
at91_set_A_periph(AT91_PIN_PB21, 1);
}
-static struct platform_device at91sam9260_ssc_dai_device = {
- .name = "atmel-ssc-dai",
- .id = 0,
- .dev = {
- .parent = &(at91sam9260_ssc_device.dev),
- },
-};
-
/*
* SSC controllers are accessed through library code, instead of any
* kind of all-singing/all-dancing driver. For example one could be
@@ -800,7 +792,6 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins)
}
platform_device_register(pdev);
- platform_device_register(&at91sam9260_ssc_dai_device);
}
#else
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index 5b6a6f9..f3faf54 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -353,19 +353,13 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = {
},
};
-static struct platform_device sam9g20ek_pcm_device = {
- .name = "atmel-pcm-audio",
- .id = -1,
-};
-
static struct platform_device sam9g20ek_audio_device = {
.name = "at91sam9g20ek-audio",
- .id = -1,
+ .id = 0,
};
static void __init ek_add_device_audio(void)
{
- platform_device_register(&sam9g20ek_pcm_device);
platform_device_register(&sam9g20ek_audio_device);
}
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 9b84f98..40e17d1 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -473,28 +473,17 @@ static struct snd_soc_platform_driver atmel_soc_platform = {
.resume = atmel_pcm_resume,
};
-static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
+int atmel_pcm_platform_register(struct device *dev)
{
- return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
+ return snd_soc_register_platform(dev, &atmel_soc_platform);
}
+EXPORT_SYMBOL(atmel_pcm_platform_register);
-static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
+void atmel_pcm_platform_unregister(struct device *dev)
{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
+ snd_soc_unregister_platform(dev);
}
-
-static struct platform_driver atmel_pcm_driver = {
- .driver = {
- .name = "atmel-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = atmel_soc_platform_probe,
- .remove = __devexit_p(atmel_soc_platform_remove),
-};
-
-module_platform_driver(atmel_pcm_driver);
+EXPORT_SYMBOL(atmel_pcm_platform_unregister);
MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
MODULE_DESCRIPTION("Atmel PCM module");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index 5e0a95e..e6d67b3 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -80,4 +80,7 @@ struct atmel_pcm_dma_params {
#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
+int atmel_pcm_platform_register(struct device *dev);
+void atmel_pcm_platform_unregister(struct device *dev);
+
#endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 354341e..4435e19 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -47,13 +47,6 @@
#include "atmel-pcm.h"
#include "atmel_ssc_dai.h"
-
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
-#define NUM_SSC_DEVICES 1
-#else
-#define NUM_SSC_DEVICES 3
-#endif
-
/*
* SSC PDC registers required by the PCM DMA engine.
*/
@@ -96,63 +89,24 @@ static struct atmel_ssc_mask ssc_rx_mask = {
/*
* DMA parameters.
*/
-static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
- {{
- .name = "SSC0 PCM out",
- .pdc = &pdc_tx_reg,
- .mask = &ssc_tx_mask,
- },
+static struct atmel_pcm_dma_params ssc_dma_params[2] = {
{
- .name = "SSC0 PCM in",
- .pdc = &pdc_rx_reg,
- .mask = &ssc_rx_mask,
- } },
-#if NUM_SSC_DEVICES == 3
- {{
- .name = "SSC1 PCM out",
+ .name = "SSC PCM out",
.pdc = &pdc_tx_reg,
.mask = &ssc_tx_mask,
},
{
- .name = "SSC1 PCM in",
+ .name = "SSC PCM in",
.pdc = &pdc_rx_reg,
.mask = &ssc_rx_mask,
- } },
- {{
- .name = "SSC2 PCM out",
- .pdc = &pdc_tx_reg,
- .mask = &ssc_tx_mask,
},
- {
- .name = "SSC2 PCM in",
- .pdc = &pdc_rx_reg,
- .mask = &ssc_rx_mask,
- } },
-#endif
};
-
-static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
- {
- .name = "ssc0",
- .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
- .dir_mask = SSC_DIR_MASK_UNUSED,
- .initialized = 0,
- },
-#if NUM_SSC_DEVICES == 3
- {
- .name = "ssc1",
- .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
+static struct atmel_ssc_info ssc_info = {
+ .name = "ssc",
+ .lock = __SPIN_LOCK_UNLOCKED(ssc_info.lock),
.dir_mask = SSC_DIR_MASK_UNUSED,
.initialized = 0,
- },
- {
- .name = "ssc2",
- .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
- .dir_mask = SSC_DIR_MASK_UNUSED,
- .initialized = 0,
- },
-#endif
};
@@ -205,7 +159,7 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
static int atmel_ssc_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
+ struct atmel_ssc_info *ssc_p = &ssc_info;
int dir_mask;
pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
@@ -234,7 +188,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
+ struct atmel_ssc_info *ssc_p = &ssc_info;
struct atmel_pcm_dma_params *dma_params;
int dir, dir_mask;
@@ -285,7 +239,7 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
- struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
+ struct atmel_ssc_info *ssc_p = &ssc_info;
ssc_p->daifmt = fmt;
return 0;
@@ -297,7 +251,7 @@ static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
int div_id, int div)
{
- struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
+ struct atmel_ssc_info *ssc_p = &ssc_info;
switch (div_id) {
case ATMEL_SSC_CMR_DIV:
@@ -336,8 +290,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
- int id = dai->id;
- struct atmel_ssc_info *ssc_p = &ssc_info[id];
+ struct atmel_ssc_info *ssc_p = &ssc_info;
struct atmel_pcm_dma_params *dma_params;
int dir, channels, bits;
u32 tfmr, rfmr, tcmr, rcmr;
@@ -354,7 +307,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
else
dir = 1;
- dma_params = &ssc_dma_params[id][dir];
+ dma_params = &ssc_dma_params[dir];
dma_params->ssc = ssc_p->ssc;
dma_params->substream = substream;
@@ -603,7 +556,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
+ struct atmel_ssc_info *ssc_p = &ssc_info;
struct atmel_pcm_dma_params *dma_params;
int dir;
@@ -631,7 +584,7 @@ static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
if (!cpu_dai->active)
return 0;
- ssc_p = &ssc_info[cpu_dai->id];
+ ssc_p = &ssc_info;
/* Save the status register before disabling transmit and receive */
ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
@@ -660,7 +613,7 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
if (!cpu_dai->active)
return 0;
- ssc_p = &ssc_info[cpu_dai->id];
+ ssc_p = &ssc_info;
/* restore SSC register settings */
ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
@@ -689,28 +642,10 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
static int atmel_ssc_probe(struct snd_soc_dai *dai)
{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
- int ret = 0;
+ struct atmel_ssc_info *ssc_p = &ssc_info;
snd_soc_dai_set_drvdata(dai, ssc_p);
- /*
- * Request SSC device
- */
- ssc_p->ssc = ssc_request(dai->id);
- if (IS_ERR(ssc_p->ssc)) {
- printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
- ret = PTR_ERR(ssc_p->ssc);
- }
-
- return ret;
-}
-
-static int atmel_ssc_remove(struct snd_soc_dai *dai)
-{
- struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
-
- ssc_free(ssc_p->ssc);
return 0;
}
@@ -728,11 +663,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
.set_clkdiv = atmel_ssc_set_dai_clkdiv,
};
-static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
- {
- .name = "atmel-ssc-dai.0",
+static struct snd_soc_dai_driver atmel_ssc_dai = {
.probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
.suspend = atmel_ssc_suspend,
.resume = atmel_ssc_resume,
.playback = {
@@ -746,69 +678,37 @@ static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
.rates = ATMEL_SSC_RATES,
.formats = ATMEL_SSC_FORMATS,},
.ops = &atmel_ssc_dai_ops,
- },
-#if NUM_SSC_DEVICES == 3
- {
- .name = "atmel-ssc-dai.1",
- .probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
- .suspend = atmel_ssc_suspend,
- .resume = atmel_ssc_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .ops = &atmel_ssc_dai_ops,
- },
- {
- .name = "atmel-ssc-dai.2",
- .probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
- .suspend = atmel_ssc_suspend,
- .resume = atmel_ssc_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .ops = &atmel_ssc_dai_ops,
- },
-#endif
};
-static __devinit int asoc_ssc_probe(struct platform_device *pdev)
+static int asoc_ssc_init(struct device *dev)
{
- BUG_ON(pdev->id < 0);
- BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai));
- return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]);
-}
+ int ret;
+
+ ret = snd_soc_register_dai(dev, &atmel_ssc_dai);
+ if (ret) {
+ dev_err(dev, "Could not register DAI: %d\n", ret);
+ goto err;
+ }
+
+ ret = atmel_pcm_platform_register(dev);
+ if (ret) {
+ dev_err(dev, "Could not register PCM: %d\n", ret);
+ goto err_unregister_dai;
+ };
-static int __devexit asoc_ssc_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
return 0;
-}
-static struct platform_driver asoc_ssc_driver = {
- .driver = {
- .name = "atmel-ssc-dai",
- .owner = THIS_MODULE,
- },
+err_unregister_dai:
+ snd_soc_unregister_dai(dev);
+err:
+ return ret;
+}
- .probe = asoc_ssc_probe,
- .remove = __devexit_p(asoc_ssc_remove),
-};
+static void asoc_ssc_exit(struct device *dev)
+{
+ atmel_pcm_platform_unregister(dev);
+ snd_soc_unregister_dai(dev);
+}
/**
* atmel_ssc_set_audio - Allocate the specified SSC for audio use.
@@ -816,50 +716,32 @@ static struct platform_driver asoc_ssc_driver = {
int atmel_ssc_set_audio(int ssc_id)
{
struct ssc_device *ssc;
- static struct platform_device *dma_pdev;
- struct platform_device *ssc_pdev;
int ret;
- if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai))
- return -EINVAL;
-
- /* Allocate a dummy device for DMA if we don't have one already */
- if (!dma_pdev) {
- dma_pdev = platform_device_alloc("atmel-pcm-audio", -1);
- if (!dma_pdev)
- return -ENOMEM;
-
- ret = platform_device_add(dma_pdev);
- if (ret < 0) {
- platform_device_put(dma_pdev);
- dma_pdev = NULL;
- return ret;
- }
- }
-
- ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
- if (!ssc_pdev)
- return -ENOMEM;
-
/* If we can grab the SSC briefly to parent the DAI device off it */
ssc = ssc_request(ssc_id);
- if (IS_ERR(ssc))
- pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n",
+ if (IS_ERR(ssc)) {
+ pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",
PTR_ERR(ssc));
- else {
- ssc_pdev->dev.parent = &(ssc->pdev->dev);
- ssc_free(ssc);
+ return PTR_ERR(ssc);
+ } else {
+ ssc_info.ssc = ssc;
}
- ret = platform_device_add(ssc_pdev);
- if (ret < 0)
- platform_device_put(ssc_pdev);
+ ret = asoc_ssc_init(&ssc->pdev->dev);
return ret;
}
EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
-module_platform_driver(asoc_ssc_driver);
+void atmel_ssc_put_audio(void)
+{
+ struct ssc_device *ssc = ssc_info.ssc;
+
+ ssc_free(ssc);
+ asoc_ssc_exit(&ssc->pdev->dev);
+}
+EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
/* Module information */
MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou at atmel.com, www.atmel.com");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
index 5d4f0f9..70c66dd 100644
--- a/sound/soc/atmel/atmel_ssc_dai.h
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -118,5 +118,6 @@ struct atmel_ssc_info {
};
int atmel_ssc_set_audio(int ssc);
+void atmel_ssc_put_audio(void);
#endif /* _AT91_SSC_DAI_H */
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 228ca6a..eef6eed 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -179,10 +179,10 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
static struct snd_soc_dai_link at91sam9g20ek_dai = {
.name = "WM8731",
.stream_name = "WM8731 PCM",
- .cpu_dai_name = "atmel-ssc-dai.0",
+ .cpu_dai_name = "at91rm9200_ssc.0",
.codec_dai_name = "wm8731-hifi",
.init = at91sam9g20ek_wm8731_init,
- .platform_name = "atmel-pcm-audio",
+ .platform_name = "at91rm9200_ssc.0",
.codec_name = "wm8731.0-001b",
.ops = &at91sam9g20ek_ops,
};
@@ -204,6 +204,10 @@ static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
return -ENODEV;
+ ret = atmel_ssc_set_audio(pdev->id);
+ if (ret)
+ goto err;
+
/*
* Codec MCLK is supplied by PCK0 - set it up.
*/
@@ -211,7 +215,7 @@ static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
if (IS_ERR(mclk)) {
printk(KERN_ERR "ASoC: Failed to get MCLK\n");
ret = PTR_ERR(mclk);
- goto err;
+ goto err_ssc_put_audio;
}
pllb = clk_get(NULL, "pllb");
@@ -240,6 +244,8 @@ static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
err_mclk:
clk_put(mclk);
mclk = NULL;
+err_ssc_put_audio:
+ atmel_ssc_put_audio();
err:
return ret;
}
@@ -248,6 +254,7 @@ static int __devexit at91sam9g20ek_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
+ atmel_ssc_put_audio();
snd_soc_unregister_card(card);
clk_put(mclk);
mclk = NULL;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 10/10] ARM: dts: AM33XX: Add PWM backlight DT data to am335x-evm
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
PWM output from ecap0 uses as backlight source. Also adds low threshold
value to have a uniform divisions in brightness-levels scales.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 185d632... 9857050... M arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evm.dts | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index 185d632..9857050 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -18,6 +18,14 @@
reg = <0x80000000 0x10000000>; /* 256 MB */
};
+ am33xx_pinmux: pinmux at 44e10800 {
+ ecap0_pins: backlight_pins {
+ pinctrl-single,pins = <
+ 0x164 0x0 /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+ >;
+ };
+ };
+
ocp {
uart1: serial at 44e09000 {
status = "okay";
@@ -31,6 +39,12 @@
reg = <0x2d>;
};
};
+
+ ecap0: ecap at 48300100 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pins>;
+ };
};
vbat: fixedregulator at 0 {
@@ -40,6 +54,13 @@
regulator-max-microvolt = <5000000>;
regulator-boot-on;
};
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&ecap0 0 50000 0>;
+ brightness-levels = <0 51 53 56 62 75 101 152 255>;
+ default-brightness-level = <8>;
+ };
};
/include/ "tps65910.dtsi"
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 09/10] ARM: dts: AM33XX: Add PWMSS device tree nodes
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
Add PWMSS device tree nodes in relation with ECAP & EHRPWM DT nodes to
AM33XX SoC family. Also populates device tree nodes for ECAP & EHRPWM by
adding necessary properties like pwm-cells, base reg & set disabled as
status.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 bb31bff... cf5e049... M arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am33xx.dtsi | 90 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index bb31bff..cf5e049 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -210,5 +210,95 @@
interrupt-parent = <&intc>;
interrupts = <91>;
};
+
+ epwmss0: epwmss at 48300000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48300000 0x10
+ 0x48300100 0x80
+ 0x48300180 0x80
+ 0x48300200 0x80>;
+ ti,hwmods = "epwmss0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ ecap0: ecap at 48300100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48300100 0x80>;
+ ti,hwmods = "ecap0";
+ status = "disabled";
+ };
+
+ ehrpwm0: ehrpwm at 48300200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48300200 0x80>;
+ ti,hwmods = "ehrpwm0";
+ status = "disabled";
+ tbclkgating;
+ };
+ };
+
+ epwmss1: epwmss at 48302000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48302000 0x10
+ 0x48302100 0x80
+ 0x48302180 0x80
+ 0x48302200 0x80>;
+ ti,hwmods = "epwmss1";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ ecap1: ecap at 48302100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48302100 0x80>;
+ ti,hwmods = "ecap1";
+ status = "disabled";
+ };
+
+ ehrpwm1: ehrpwm at 48302200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48302200 0x80>;
+ ti,hwmods = "ehrpwm1";
+ status = "disabled";
+ tbclkgating;
+ };
+ };
+
+ epwmss2: epwmss at 48304000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48304000 0x10
+ 0x48304100 0x80
+ 0x48304180 0x80
+ 0x48304200 0x80>;
+ ti,hwmods = "epwmss2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ ecap2: ecap at 48304100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48304100 0x80>;
+ ti,hwmods = "ecap2";
+ status = "disabled";
+ };
+
+ ehrpwm2: ehrpwm at 48304200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48304200 0x80>;
+ ti,hwmods = "ehrpwm2";
+ status = "disabled";
+ tbclkgating;
+ };
+ };
};
};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 08/10] pwm: pwm-tiehrpwm: Adding TBCLK gating support.
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
Some platforms (like AM33XX) requires clock gating from control module
explicitly for TBCLK. Enabling of this clock required for the
functioning of the time base sub module in EHRPWM module. So adding
optional TBCLK handling if DT node populated with tbclkgating. This
helps the driver can coexist for Davinci platforms.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
---
Changes since v1:
- Moved TBCLK enable from probe to .pwm_enable & disable from
remove to .pwm_disable
:100644 100644 07911e6... 927a8ed... M drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/pwm-tiehrpwm.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index 07911e6..927a8ed 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -126,6 +126,7 @@ struct ehrpwm_pwm_chip {
void __iomem *mmio_base;
unsigned long period_cycles[NUM_PWM_CHANNEL];
enum pwm_polarity polarity[NUM_PWM_CHANNEL];
+ struct clk *tbclk;
};
static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
@@ -346,6 +347,13 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
/* Channels polarity can be configured from action qualifier module */
configure_polarity(pc, pwm->hwpwm);
+ /*
+ * Platforms require explicit clock enabling of TBCLK has
+ * to enable TBCLK explicitly before enabling PWM device
+ */
+ if (pc->tbclk)
+ clk_enable(pc->tbclk);
+
/* Enable time counter for free_run */
ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
return 0;
@@ -374,6 +382,10 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
+ /* Disabling TBCLK on PWM disable */
+ if (pc->tbclk)
+ clk_disable(pc->tbclk);
+
/* Stop Time base counter */
ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT);
@@ -464,6 +476,16 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
}
+
+ /* Some platforms require explicit tbclk gating */
+ if (of_property_read_bool(pdev->dev.of_node, "tbclkgating")) {
+ pc->tbclk = clk_get(&pdev->dev, "tbclk");
+ if (IS_ERR(pc->tbclk)) {
+ dev_err(&pdev->dev, "Could not get EHRPWM TBCLK\n");
+ return PTR_ERR(pc->tbclk);
+ }
+ }
+
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
if (!(pwmss_submodule_state_change(pdev->dev.parent, EPWMCLK_EN) &
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 07/10] pwm: pwm-tiehrpwm: pinctrl support
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
Enable pinctrl for pwm-tiehrpwm
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 fba7f9b... 07911e6... M drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/pwm-tiehrpwm.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index fba7f9b..07911e6 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -26,6 +26,7 @@
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include "tipwmss.h"
@@ -418,6 +419,11 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
struct resource *r;
struct clk *clk;
struct ehrpwm_pwm_chip *pc;
+ struct pinctrl *pinctrl;
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev, "failed to configure pins from driver\n");
pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
if (!pc) {
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 06/10] pwm: pwm-tiehrpwm: Add device-tree binding support for EHRPWM driver
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
This patch
1. Add support for device-tree binding for EHRWPM driver.
2. Set size of pwm-cells set to 3 to support PWM channel number, PWM
period & polarity configuration from device tree.
3. Add enable/disable clock gating in PWM subsystem common config space.
4. When here set .owner member in platform_driver structure to
THIS_MODULE.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
---
Changes since v1:
- Add separate patch for pinctrl support
- Add conditional check for PWM subsystem clock enable.
- Combined with HWMOD changes & DT bindings.
- Remove the custom of xlate support.
:000000 100644 0000000... aa2ed0a... A Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
:100644 100644 d3c1dff... fba7f9b... M drivers/pwm/pwm-tiehrpwm.c
.../devicetree/bindings/pwm/pwm-tiehrpwm.txt | 25 ++++++++++
drivers/pwm/pwm-tiehrpwm.c | 49 +++++++++++++++++++-
2 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
new file mode 100644
index 0000000..aa2ed0a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
@@ -0,0 +1,25 @@
+TI SOC EHRPWM based PWM controller
+
+Required properties:
+- compatible : Must be "ti,am33xx-ehrpwm"
+- #pwm-cells: Should be 3. Number of cells being used to specify PWM property.
+ First cell specifies the per-chip index of the PWM to use, the second
+ cell is the period cycle in nanoseconds and bit 0 in the third cell is
+ used to encode the polarity of PWM output.
+- reg: physical base address and size of the registers map.
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the EHRPWM:
+ "ehrpwm<x>", <x> being the 0-based instance number from the HW spec
+- tbclkgating: platforms require tbclk gating from control module
+ should populate
+
+Example:
+
+ehrpwm0: ehrpwm at 0 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48300200 0x100>;
+ ti,hwmods = "ehrpwm0";
+ tbclkgating;
+};
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index d3c1dff..fba7f9b 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -25,6 +25,9 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
+#include <linux/of_device.h>
+
+#include "tipwmss.h"
/* EHRPWM registers and bits definitions */
@@ -107,6 +110,13 @@
#define AQCSFRC_CSFA_FRCHIGH BIT(1)
#define AQCSFRC_CSFA_DISSWFRC (BIT(1) | BIT(0))
+#define EPWMCLK_EN BIT(8)
+#define EPWMCLK_STOP_REQ BIT(9)
+
+#define EPWMCLK_EN_ACK BIT(8)
+
+#define PWM_CELL_SIZE 3
+
#define NUM_PWM_CHANNEL 2 /* EHRPWM channels */
struct ehrpwm_pwm_chip {
@@ -392,6 +402,16 @@ static const struct pwm_ops ehrpwm_pwm_ops = {
.owner = THIS_MODULE,
};
+#ifdef CONFIG_OF
+static const struct of_device_id ehrpwm_of_match[] = {
+ {
+ .compatible = "ti,am33xx-ehrpwm",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ehrpwm_of_match);
+#endif
+
static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
{
int ret;
@@ -419,6 +439,7 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev;
pc->chip.ops = &ehrpwm_pwm_ops;
+ pc->chip.of_pwm_n_cells = PWM_CELL_SIZE;
pc->chip.base = -1;
pc->chip.npwm = NUM_PWM_CHANNEL;
@@ -437,16 +458,38 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
}
-
pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ if (!(pwmss_submodule_state_change(pdev->dev.parent, EPWMCLK_EN) &
+ EPWMCLK_EN_ACK)) {
+ dev_err(&pdev->dev, "PWMSS config space clock enable failure\n");
+ ret = -EINVAL;
+ goto pwmss_clk_failure;
+ }
+ pm_runtime_put_sync(&pdev->dev);
+
platform_set_drvdata(pdev, pc);
return 0;
+
+pwmss_clk_failure:
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pwmchip_remove(&pc->chip);
+ return ret;
}
static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev)
{
struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
+ pm_runtime_get_sync(&pdev->dev);
+ /*
+ * Due to hardware misbehaviour, acknowledge of the stop_req
+ * is missing. Hence checking of the status bit skipped.
+ */
+ pwmss_submodule_state_change(pdev->dev.parent, EPWMCLK_STOP_REQ);
+ pm_runtime_put_sync(&pdev->dev);
+
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return pwmchip_remove(&pc->chip);
@@ -454,7 +497,9 @@ static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev)
static struct platform_driver ehrpwm_pwm_driver = {
.driver = {
- .name = "ehrpwm",
+ .name = "ehrpwm",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ehrpwm_of_match),
},
.probe = ehrpwm_pwm_probe,
.remove = __devexit_p(ehrpwm_pwm_remove),
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 05/10] pwm: pwm-tiecap: pinctrl support
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
Enable pinctrl for pwm-tiecap
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 0d43266... 6071f7a... M drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiecap.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index 0d43266..6071f7a 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -26,6 +26,7 @@
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include "tipwmss.h"
@@ -210,6 +211,11 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev)
struct resource *r;
struct clk *clk;
struct ecap_pwm_chip *pc;
+ struct pinctrl *pinctrl;
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev, "failed to configure pins from driver\n");
pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
if (!pc) {
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 04/10] pwm: pwm-tiecap: Add device-tree binding support for APWM driver
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
This patch
1. Add support for device-tree binding for ECAP APWM driver.
2. Set size of pwm-cells set to 3 to support PWM channel number, PWM
period & polarity configuration from device tree.
3. Add enable/disable clock gating in PWM subsystem common config space.
4. When here set .owner member in platform_driver structure to
THIS_MODULE.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
---
Changes since v1:
- Add separate patch for pinctrl support
- Add conditional check for PWM subsystem clock enable.
- Combined with HWMOD changes & DT bindings.
- Remove the custom of xlate support.
:000000 100644 0000000... fe24cac... A Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
:100644 100644 d6d4cf0... 0d43266... M drivers/pwm/pwm-tiecap.c
.../devicetree/bindings/pwm/pwm-tiecap.txt | 22 +++++++++
drivers/pwm/pwm-tiecap.c | 48 +++++++++++++++++++-
2 files changed, 69 insertions(+), 1 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
new file mode 100644
index 0000000..fe24cac
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
@@ -0,0 +1,22 @@
+TI SOC ECAP based APWM controller
+
+Required properties:
+- compatible: Must be "ti,am33xx-ecap"
+- #pwm-cells: Should be 3. Number of cells being used to specify PWM property.
+ First cell specifies the per-chip index of the PWM to use, the second
+ cell is the period cycle in nanoseconds and bit 0 in the third cell is
+ used to encode the polarity of PWM output.
+- reg: physical base address and size of the registers map.
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the ECAP:
+ "ecap<x>", <x> being the 0-based instance number from the HW spec
+
+Example:
+
+ecap0: ecap at 0 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48300100 0x80>;
+ ti,hwmods = "ecap0";
+};
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index d6d4cf0..0d43266 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -25,6 +25,9 @@
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
+#include <linux/of_device.h>
+
+#include "tipwmss.h"
/* ECAP registers and bits definitions */
#define CAP1 0x08
@@ -37,6 +40,13 @@
#define ECCTL2_SYNC_SEL_DISA (BIT(7) | BIT(6))
#define ECCTL2_TSCTR_FREERUN BIT(4)
+#define ECAPCLK_EN BIT(0)
+#define ECAPCLK_STOP_REQ BIT(1)
+
+#define ECAPCLK_EN_ACK BIT(0)
+
+#define PWM_CELL_SIZE 3
+
struct ecap_pwm_chip {
struct pwm_chip chip;
unsigned int clk_rate;
@@ -184,6 +194,16 @@ static const struct pwm_ops ecap_pwm_ops = {
.owner = THIS_MODULE,
};
+#ifdef CONFIG_OF
+static const struct of_device_id ecap_of_match[] = {
+ {
+ .compatible = "ti,am33xx-ecap",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ecap_of_match);
+#endif
+
static int __devinit ecap_pwm_probe(struct platform_device *pdev)
{
int ret;
@@ -211,6 +231,7 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev;
pc->chip.ops = &ecap_pwm_ops;
+ pc->chip.of_pwm_n_cells = PWM_CELL_SIZE;
pc->chip.base = -1;
pc->chip.npwm = 1;
@@ -231,14 +252,37 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev)
}
pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ if (!(pwmss_submodule_state_change(pdev->dev.parent, ECAPCLK_EN) &
+ ECAPCLK_EN_ACK)) {
+ dev_err(&pdev->dev, "PWMSS config space clock enable failure\n");
+ ret = -EINVAL;
+ goto pwmss_clk_failure;
+ }
+ pm_runtime_put_sync(&pdev->dev);
+
platform_set_drvdata(pdev, pc);
return 0;
+
+pwmss_clk_failure:
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pwmchip_remove(&pc->chip);
+ return ret;
}
static int __devexit ecap_pwm_remove(struct platform_device *pdev)
{
struct ecap_pwm_chip *pc = platform_get_drvdata(pdev);
+ pm_runtime_get_sync(&pdev->dev);
+ /*
+ * Due to hardware misbehaviour, acknowledge of the stop_req
+ * is missing. Hence checking of the status bit skipped.
+ */
+ pwmss_submodule_state_change(pdev->dev.parent, ECAPCLK_STOP_REQ);
+ pm_runtime_put_sync(&pdev->dev);
+
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return pwmchip_remove(&pc->chip);
@@ -246,7 +290,9 @@ static int __devexit ecap_pwm_remove(struct platform_device *pdev)
static struct platform_driver ecap_pwm_driver = {
.driver = {
- .name = "ecap",
+ .name = "ecap",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ecap_of_match),
},
.probe = ecap_pwm_probe,
.remove = __devexit_p(ecap_pwm_remove),
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 03/10] ARM: OMAP: AM33xx hwmod: Add parent-child relationship for PWM subsystem
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
As part of PWM subsystem integration, PWM subsystem are sharing
resources like clock across submodules (ECAP, EQEP & EHRPWM).
To handle resource sharing & IP integration
1. Rework on parent child relation between PWMSS and
ECAP, EQEP & EHRPWM child devices to support runtime PM.
2. Add support for opt_clks in EHRPWM HWMOD entry to handle additional
clock gating from control module.
3. Add HWMOD entries for EQEP PWM submodule.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
Changes since v1:
- Remove ADDR_TYPE_RT for PWM sub module register entries.
:100644 100644 ad8d43b... de2301c... M arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 419 ++++++++++++++++++----------
1 files changed, 276 insertions(+), 143 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index ad8d43b..de2301c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -768,9 +768,7 @@ static struct omap_hwmod am33xx_elm_hwmod = {
},
};
-/*
- * 'epwmss' class: ecap0,1,2, ehrpwm0,1,2
- */
+/* pwmss */
static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = {
.rev_offs = 0x0,
.sysc_offs = 0x4,
@@ -786,18 +784,23 @@ static struct omap_hwmod_class am33xx_epwmss_hwmod_class = {
.sysc = &am33xx_epwmss_sysc,
};
-/* ehrpwm0 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm0_irqs[] = {
- { .name = "int", .irq = 86 + OMAP_INTC_START, },
- { .name = "tzint", .irq = 58 + OMAP_INTC_START, },
- { .irq = -1 },
+
+static struct omap_hwmod_class am33xx_ecap_hwmod_class = {
+ .name = "ecap",
};
-static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
- .name = "ehrpwm0",
+static struct omap_hwmod_class am33xx_eqep_hwmod_class = {
+ .name = "eqep",
+};
+
+static struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = {
+ .name = "ehrpwm",
+};
+/* epwmss0 */
+static struct omap_hwmod am33xx_epwmss0_hwmod = {
+ .name = "epwmss0",
.class = &am33xx_epwmss_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ehrpwm0_irqs,
.main_clk = "l4ls_gclk",
.prcm = {
.omap4 = {
@@ -807,63 +810,68 @@ static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
},
};
-/* ehrpwm1 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm1_irqs[] = {
- { .name = "int", .irq = 87 + OMAP_INTC_START, },
- { .name = "tzint", .irq = 59 + OMAP_INTC_START, },
+/* ecap0 */
+static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = {
+ { .irq = 31 + OMAP_INTC_START, },
{ .irq = -1 },
};
-static struct omap_hwmod am33xx_ehrpwm1_hwmod = {
- .name = "ehrpwm1",
- .class = &am33xx_epwmss_hwmod_class,
+static struct omap_hwmod am33xx_ecap0_hwmod = {
+ .name = "ecap0",
+ .class = &am33xx_ecap_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ehrpwm1_irqs,
+ .mpu_irqs = am33xx_ecap0_irqs,
.main_clk = "l4ls_gclk",
- .prcm = {
- .omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET,
- .modulemode = MODULEMODE_SWCTRL,
- },
- },
};
-/* ehrpwm2 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm2_irqs[] = {
- { .name = "int", .irq = 39 + OMAP_INTC_START, },
- { .name = "tzint", .irq = 60 + OMAP_INTC_START, },
+/* eqep0 */
+static struct omap_hwmod_irq_info am33xx_eqep0_irqs[] = {
+ { .irq = 79 + OMAP_INTC_START, },
{ .irq = -1 },
};
-static struct omap_hwmod am33xx_ehrpwm2_hwmod = {
- .name = "ehrpwm2",
- .class = &am33xx_epwmss_hwmod_class,
+static struct omap_hwmod am33xx_eqep0_hwmod = {
+ .name = "eqep0",
+ .class = &am33xx_eqep_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ehrpwm2_irqs,
+ .mpu_irqs = am33xx_eqep0_irqs,
.main_clk = "l4ls_gclk",
- .prcm = {
- .omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET,
- .modulemode = MODULEMODE_SWCTRL,
- },
- },
};
-/* ecap0 */
-static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = {
- { .irq = 31 + OMAP_INTC_START, },
+/* ehrpwm0 */
+static struct omap_hwmod_irq_info am33xx_ehrpwm0_irqs[] = {
+ { .name = "int", .irq = 86 + OMAP_INTC_START, },
+ { .name = "tzint", .irq = 58 + OMAP_INTC_START, },
{ .irq = -1 },
};
-static struct omap_hwmod am33xx_ecap0_hwmod = {
- .name = "ecap0",
+/*
+ * Optional clock entry is provided to support additional clock
+ * gating for EHRPWM module functional from control module.
+ */
+static struct omap_hwmod_opt_clk ehrpwm0_opt_clks[] = {
+ { .role = "tbclk", .clk = "ehrpwm0_tbclk" },
+};
+
+static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
+ .name = "ehrpwm0",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_ehrpwm0_irqs,
+ .main_clk = "l4ls_gclk",
+ .opt_clks = ehrpwm0_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(ehrpwm0_opt_clks),
+};
+
+/* epwmss1 */
+static struct omap_hwmod am33xx_epwmss1_hwmod = {
+ .name = "epwmss1",
.class = &am33xx_epwmss_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ecap0_irqs,
.main_clk = "l4ls_gclk",
.prcm = {
.omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET,
+ .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
@@ -877,13 +885,60 @@ static struct omap_hwmod_irq_info am33xx_ecap1_irqs[] = {
static struct omap_hwmod am33xx_ecap1_hwmod = {
.name = "ecap1",
- .class = &am33xx_epwmss_hwmod_class,
+ .class = &am33xx_ecap_hwmod_class,
.clkdm_name = "l4ls_clkdm",
.mpu_irqs = am33xx_ecap1_irqs,
.main_clk = "l4ls_gclk",
+};
+
+/* eqep1 */
+static struct omap_hwmod_irq_info am33xx_eqep1_irqs[] = {
+ { .irq = 88 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod am33xx_eqep1_hwmod = {
+ .name = "eqep1",
+ .class = &am33xx_eqep_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_eqep1_irqs,
+ .main_clk = "l4ls_gclk",
+};
+
+/* ehrpwm1 */
+static struct omap_hwmod_irq_info am33xx_ehrpwm1_irqs[] = {
+ { .name = "int", .irq = 87 + OMAP_INTC_START, },
+ { .name = "tzint", .irq = 59 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+/*
+ * Optional clock entry is provided to support additional clock
+ * gating for EHRPWM module functional from control module.
+ */
+static struct omap_hwmod_opt_clk ehrpwm1_opt_clks[] = {
+ { .role = "tbclk", .clk = "ehrpwm1_tbclk" },
+};
+
+static struct omap_hwmod am33xx_ehrpwm1_hwmod = {
+ .name = "ehrpwm1",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_ehrpwm1_irqs,
+ .main_clk = "l4ls_gclk",
+ .opt_clks = ehrpwm1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(ehrpwm1_opt_clks),
+};
+
+/* epwmss2 */
+static struct omap_hwmod am33xx_epwmss2_hwmod = {
+ .name = "epwmss2",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
.prcm = {
.omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET,
+ .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
@@ -897,16 +952,49 @@ static struct omap_hwmod_irq_info am33xx_ecap2_irqs[] = {
static struct omap_hwmod am33xx_ecap2_hwmod = {
.name = "ecap2",
+ .class = &am33xx_ecap_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
.mpu_irqs = am33xx_ecap2_irqs,
- .class = &am33xx_epwmss_hwmod_class,
+ .main_clk = "l4ls_gclk",
+};
+
+/* eqep2 */
+static struct omap_hwmod_irq_info am33xx_eqep2_irqs[] = {
+ { .irq = 89 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod am33xx_eqep2_hwmod = {
+ .name = "eqep2",
+ .class = &am33xx_eqep_hwmod_class,
.clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_eqep2_irqs,
.main_clk = "l4ls_gclk",
- .prcm = {
- .omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET,
- .modulemode = MODULEMODE_SWCTRL,
- },
- },
+};
+
+/* ehrpwm2 */
+static struct omap_hwmod_irq_info am33xx_ehrpwm2_irqs[] = {
+ { .name = "int", .irq = 39 + OMAP_INTC_START, },
+ { .name = "tzint", .irq = 60 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+/*
+ * Optional clock entry is provided to support additional clock
+ * gating for EHRPWM module functional from control module.
+ */
+static struct omap_hwmod_opt_clk ehrpwm2_opt_clks[] = {
+ { .role = "tbclk", .clk = "ehrpwm2_tbclk" },
+};
+
+static struct omap_hwmod am33xx_ehrpwm2_hwmod = {
+ .name = "ehrpwm2",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_ehrpwm2_irqs,
+ .main_clk = "l4ls_gclk",
+ .opt_clks = ehrpwm2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(ehrpwm2_opt_clks),
};
/*
@@ -2518,162 +2606,201 @@ static struct omap_hwmod_ocp_if am33xx_l4_ls__elm = {
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = {
{
.pa_start = 0x48300000,
.pa_end = 0x48300000 + SZ_16 - 1,
.flags = ADDR_TYPE_RT
},
- {
- .pa_start = 0x48300200,
- .pa_end = 0x48300200 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT
- },
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm0 = {
+static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = {
.master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ehrpwm0_hwmod,
+ .slave = &am33xx_epwmss0_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ehrpwm0_addr_space,
+ .addr = am33xx_epwmss0_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = {
- {
- .pa_start = 0x48302000,
- .pa_end = 0x48302000 + SZ_16 - 1,
- .flags = ADDR_TYPE_RT
- },
+static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = {
{
- .pa_start = 0x48302200,
- .pa_end = 0x48302200 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT
+ .pa_start = 0x48300100,
+ .pa_end = 0x48300100 + SZ_128 - 1,
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm1 = {
- .master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ehrpwm1_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_ecap0_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ehrpwm1_addr_space,
+ .addr = am33xx_ecap0_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_eqep0_addr_space[] = {
{
- .pa_start = 0x48304000,
- .pa_end = 0x48304000 + SZ_16 - 1,
- .flags = ADDR_TYPE_RT
- },
- {
- .pa_start = 0x48304200,
- .pa_end = 0x48304200 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT
+ .pa_start = 0x48300180,
+ .pa_end = 0x48300180 + SZ_128 - 1,
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm2 = {
- .master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ehrpwm2_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_eqep0_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ehrpwm2_addr_space,
+ .addr = am33xx_eqep0_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = {
- {
- .pa_start = 0x48300000,
- .pa_end = 0x48300000 + SZ_16 - 1,
- .flags = ADDR_TYPE_RT
- },
+static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = {
{
- .pa_start = 0x48300100,
- .pa_end = 0x48300100 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT
+ .pa_start = 0x48300200,
+ .pa_end = 0x48300200 + SZ_128 - 1,
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap0 = {
- .master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ecap0_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_ehrpwm0_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ecap0_addr_space,
+ .addr = am33xx_ehrpwm0_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = {
{
.pa_start = 0x48302000,
.pa_end = 0x48302000 + SZ_16 - 1,
.flags = ADDR_TYPE_RT
},
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_epwmss1_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_epwmss1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = {
{
.pa_start = 0x48302100,
- .pa_end = 0x48302100 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT
+ .pa_end = 0x48302100 + SZ_128 - 1,
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap1 = {
- .master = &am33xx_l4_ls_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = {
+ .master = &am33xx_epwmss1_hwmod,
.slave = &am33xx_ecap1_hwmod,
.clk = "l4ls_gclk",
.addr = am33xx_ecap1_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_eqep1_addr_space[] = {
+ {
+ .pa_start = 0x48302180,
+ .pa_end = 0x48302180 + SZ_128 - 1,
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_eqep1_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_eqep1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = {
+ {
+ .pa_start = 0x48302200,
+ .pa_end = 0x48302200 + SZ_128 - 1,
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_ehrpwm1_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_ehrpwm1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = {
{
.pa_start = 0x48304000,
.pa_end = 0x48304000 + SZ_16 - 1,
.flags = ADDR_TYPE_RT
},
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_epwmss2_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_epwmss2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = {
{
.pa_start = 0x48304100,
- .pa_end = 0x48304100 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT
+ .pa_end = 0x48304100 + SZ_128 - 1,
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap2 = {
- .master = &am33xx_l4_ls_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = {
+ .master = &am33xx_epwmss2_hwmod,
.slave = &am33xx_ecap2_hwmod,
.clk = "l4ls_gclk",
.addr = am33xx_ecap2_addr_space,
.user = OCP_USER_MPU,
};
+static struct omap_hwmod_addr_space am33xx_eqep2_addr_space[] = {
+ {
+ .pa_start = 0x48304180,
+ .pa_end = 0x48304180 + SZ_128 - 1,
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = {
+ .master = &am33xx_epwmss2_hwmod,
+ .slave = &am33xx_eqep2_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_eqep2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = {
+ {
+ .pa_start = 0x48304200,
+ .pa_end = 0x48304200 + SZ_128 - 1,
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
+ .master = &am33xx_epwmss2_hwmod,
+ .slave = &am33xx_ehrpwm2_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_ehrpwm2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
/* l3s cfg -> gpmc */
static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = {
{
@@ -3356,12 +3483,18 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_l4_ls__uart6,
&am33xx_l4_ls__spinlock,
&am33xx_l4_ls__elm,
- &am33xx_l4_ls__ehrpwm0,
- &am33xx_l4_ls__ehrpwm1,
- &am33xx_l4_ls__ehrpwm2,
- &am33xx_l4_ls__ecap0,
- &am33xx_l4_ls__ecap1,
- &am33xx_l4_ls__ecap2,
+ &am33xx_l4_ls__epwmss0,
+ &am33xx_epwmss0__ecap0,
+ &am33xx_epwmss0__eqep0,
+ &am33xx_epwmss0__ehrpwm0,
+ &am33xx_l4_ls__epwmss1,
+ &am33xx_epwmss1__ecap1,
+ &am33xx_epwmss1__eqep1,
+ &am33xx_epwmss1__ehrpwm1,
+ &am33xx_l4_ls__epwmss2,
+ &am33xx_epwmss2__ecap2,
+ &am33xx_epwmss2__eqep2,
+ &am33xx_epwmss2__ehrpwm2,
&am33xx_l3_s__gpmc,
&am33xx_l3_main__lcdc,
&am33xx_l4_ls__mcspi0,
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 02/10] ARM: am33xx: clk: Add optional clock for EHRPWM
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
EHRPWM module requires explicit clock gating from control module.
Hence add clock node in clock tree for EHRPWM modules.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 17e3de5... 833260f... M arch/arm/mach-omap2/clock33xx_data.c
:100644 100644 a89e825... c0e34e6... M arch/arm/mach-omap2/control.h
arch/arm/mach-omap2/clock33xx_data.c | 37 ++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/control.h | 8 +++++++
2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
index 17e3de5..833260f 100644
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ b/arch/arm/mach-omap2/clock33xx_data.c
@@ -995,6 +995,40 @@ static struct clk wdt1_fck = {
};
/*
+ * PWMSS Time based module clock node. This node is
+ * requred to enable clock gating for EHRPWM TBCLK.
+ */
+static struct clk ehrpwm0_tbclk = {
+ .name = "ehrpwm0_tbclk",
+ .clkdm_name = "l4ls_clkdm",
+ .enable_reg = AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+ .enable_bit = AM33XX_PWMSS0_TBCLKEN_SHIFT,
+ .ops = &clkops_omap2_dflt,
+ .parent = &l4ls_gclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ehrpwm1_tbclk = {
+ .name = "ehrpwm1_tbclk",
+ .clkdm_name = "l4ls_clkdm",
+ .enable_reg = AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+ .enable_bit = AM33XX_PWMSS1_TBCLKEN_SHIFT,
+ .ops = &clkops_omap2_dflt,
+ .parent = &l4ls_gclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ehrpwm2_tbclk = {
+ .name = "ehrpwm2_tbclk",
+ .clkdm_name = "l4ls_clkdm",
+ .enable_reg = AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+ .enable_bit = AM33XX_PWMSS2_TBCLKEN_SHIFT,
+ .ops = &clkops_omap2_dflt,
+ .parent = &l4ls_gclk,
+ .recalc = &followparent_recalc,
+};
+
+/*
* clkdev
*/
static struct omap_clk am33xx_clks[] = {
@@ -1074,6 +1108,9 @@ static struct omap_clk am33xx_clks[] = {
CLK(NULL, "clkout2_ck", &clkout2_ck, CK_AM33XX),
CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX),
CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX),
+ CLK(NULL, "ehrpwm0_tbclk", &ehrpwm0_tbclk, CK_AM33XX),
+ CLK(NULL, "ehrpwm1_tbclk", &ehrpwm1_tbclk, CK_AM33XX),
+ CLK(NULL, "ehrpwm2_tbclk", &ehrpwm2_tbclk, CK_AM33XX),
};
int __init am33xx_clk_init(void)
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a89e825..c0e34e6 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -357,6 +357,14 @@
#define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH 0x2
#define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK (0x3 << 22)
+/* AM33XX PWMSS Control register */
+#define AM33XX_PWMSS_TBCLK_CLKCTRL 0x664
+
+/* AM33XX PWMSS Control bitfields */
+#define AM33XX_PWMSS0_TBCLKEN_SHIFT 0
+#define AM33XX_PWMSS1_TBCLKEN_SHIFT 1
+#define AM33XX_PWMSS2_TBCLKEN_SHIFT 2
+
/* CONTROL OMAP STATUS register to identify OMAP3 features */
#define OMAP3_CONTROL_OMAP_STATUS 0x044c
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 01/10] PWMSS: Add PWM Subsystem driver for parent<->child relationship
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352361197-27442-1-git-send-email-avinashphilip@ti.com>
In some platforms (like am33xx), PWM sub modules (ECAP, EHRPWM, EQEP)
are integrated to PWM subsystem. These PWM submodules has resources
shared and only one register bit-field is provided to control
module/clock enable/disable, makes it difficult to handle common
resources from independent PWMSS submodule drivers.
So the solution here implemented in this patch is, to create driver for
PWMSS and take the role of parent driver for PWM submodules. PWMSS
parent driver enumerates all the child nodes under PWMSS module. Also
symbol "pwmss_submodule_state_change" exported to enable clock gating
for individual PWMSS submodules, and submodule drivers has to enable
clock gating from their drivers.
As this is only supported during DT boot, the parent<->child relationship
is created and populated in DT execution flow. The only required change
is inside DTS file, making EHRPWM & ECAP as a child to PWMSS node.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
Changes since v1:
- Add conditional check for PWM susbsystem clock enabling.
- Add context save/restore for PWM subsystem clock config register.
:000000 100644 0000000... b6c2814... A Documentation/devicetree/bindings/pwm/tipwmss.txt
:100644 100644 6e556c7... 384a346... M drivers/pwm/Kconfig
:100644 100644 3b3f4c9a.. 55f6fb2... M drivers/pwm/Makefile
:000000 100644 0000000... c188348... A drivers/pwm/tipwmss.c
:000000 100644 0000000... f9cb2e2... A drivers/pwm/tipwmss.h
Documentation/devicetree/bindings/pwm/tipwmss.txt | 30 +++++
drivers/pwm/Kconfig | 11 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/tipwmss.c | 142 +++++++++++++++++++++
drivers/pwm/tipwmss.h | 30 +++++
5 files changed, 214 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/tipwmss.txt b/Documentation/devicetree/bindings/pwm/tipwmss.txt
new file mode 100644
index 0000000..b6c2814
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/tipwmss.txt
@@ -0,0 +1,30 @@
+TI SOC based PWM Subsystem
+
+Required properties:
+- compatible: Must be "ti,am33xx-pwmss";
+- reg: physical base address and size of the registers map. For am33xx,
+ 4 set of register maps present, PWMSS config space, ECAP register space,
+ EQEP register space, EHRPWM register space.
+- address-cells: Specify the number of u32 entries needed in child nodes.
+ Should set to 1.
+- size-cells: specify inumber of u32 entries needed to specify child nodes size
+ in reg property. Should set to 1.
+- ranges: describes the address mapping of a memory-mapped bus. Should set to empty
+ as parent and child address space is identical.
+
+Also child nodes should also populated under PWMSS DT node.
+Example:
+pwmss0: pwmss at 48300000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48300000 0x10
+ 0x48300100 0x80
+ 0x48300180 0x80
+ 0x48300200 0x80>;
+ ti,hwmods = "epwmss0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ /* child nodes go here */
+};
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 6e556c7..384a346 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -136,6 +136,7 @@ config PWM_TEGRA
config PWM_TIECAP
tristate "ECAP PWM support"
depends on SOC_AM33XX
+ select PWM_TIPWMSS
help
PWM driver support for the ECAP APWM controller found on AM33XX
TI SOC
@@ -146,6 +147,7 @@ config PWM_TIECAP
config PWM_TIEHRPWM
tristate "EHRPWM PWM support"
depends on SOC_AM33XX
+ select PWM_TIPWMSS
help
PWM driver support for the EHRPWM controller found on AM33XX
TI SOC
@@ -153,6 +155,15 @@ config PWM_TIEHRPWM
To compile this driver as a module, choose M here: the module
will be called pwm-tiehrpwm.
+config PWM_TIPWMSS
+ tristate "TI PWM Subsytem parent support"
+ depends on SOC_AM33XX && (PWM_TIEHRPWM || PWM_TIECAP)
+ help
+ PWM Subsystem driver support for AM33xx SOC.
+
+ PWM submodules require PWM config space access from submodule
+ drivers and require common parent driver support.
+
config PWM_TWL6030
tristate "TWL6030 PWM support"
depends on TWL4030_CORE
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 3b3f4c9..55f6fb2 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,5 +12,6 @@ obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
+obj-$(CONFIG_PWM_TIPWMSS) += tipwmss.o
obj-$(CONFIG_PWM_TWL6030) += pwm-twl6030.o
obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
diff --git a/drivers/pwm/tipwmss.c b/drivers/pwm/tipwmss.c
new file mode 100644
index 0000000..c188348
--- /dev/null
+++ b/drivers/pwm/tipwmss.c
@@ -0,0 +1,142 @@
+/*
+ * TI PWM Subsystem driver
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/of_device.h>
+
+#include "tipwmss.h"
+
+#define PWMSS_CLKCONFIG 0x8 /* Clock gaitng reg, for PWM submodules */
+#define PWMSS_CLKSTATUS 0xc /* Clock gating status reg */
+
+struct pwmss_info {
+ void __iomem *mmio_base;
+ struct mutex pwmss_lock;
+ u16 pwmss_clkconfig;
+};
+
+u16 pwmss_submodule_state_change(struct device *dev, int set)
+{
+ struct pwmss_info *info = dev_get_drvdata(dev);
+ u16 val;
+
+ val = readw(info->mmio_base + PWMSS_CLKCONFIG);
+ val |= set;
+ mutex_lock(&info->pwmss_lock);
+ writew(val , info->mmio_base + PWMSS_CLKCONFIG);
+ mutex_unlock(&info->pwmss_lock);
+ return readw(info->mmio_base + PWMSS_CLKSTATUS);
+}
+EXPORT_SYMBOL(pwmss_submodule_state_change);
+
+static const struct of_device_id pwmss_of_match[] = {
+ {
+ .compatible = "ti,am33xx-pwmss",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, pwmss_of_match);
+
+static int __devinit pwmss_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *r;
+ struct pwmss_info *info;
+ struct device_node *node = pdev->dev.of_node;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ mutex_init(&info->pwmss_lock);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ return -ENODEV;
+ }
+
+ info->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
+ if (!info->mmio_base)
+ return -EADDRNOTAVAIL;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ platform_set_drvdata(pdev, info);
+
+ /* Populate all the child nodes here... */
+ ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
+ if (ret)
+ dev_warn(&pdev->dev, "Doesn't have any child node\n");
+
+ return ret;
+}
+
+static int __devexit pwmss_remove(struct platform_device *pdev)
+{
+ struct pwmss_info *info = platform_get_drvdata(pdev);
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ mutex_destroy(&info->pwmss_lock);
+ return 0;
+}
+
+static int pwmss_suspend(struct device *dev)
+{
+ struct pwmss_info *info = dev_get_drvdata(dev);
+
+ info->pwmss_clkconfig = readw(info->mmio_base + PWMSS_CLKCONFIG);
+ pm_runtime_put_sync(dev);
+ return 0;
+}
+
+static int pwmss_resume(struct device *dev)
+{
+ struct pwmss_info *info = dev_get_drvdata(dev);
+
+ pm_runtime_get_sync(dev);
+ writew(info->pwmss_clkconfig, info->mmio_base + PWMSS_CLKCONFIG);
+ return 0;
+}
+
+static const struct dev_pm_ops pwmss_pm_ops = {
+ .suspend = pwmss_suspend,
+ .resume = pwmss_resume,
+};
+
+static struct platform_driver pwmss_driver = {
+ .driver = {
+ .name = "pwmss",
+ .owner = THIS_MODULE,
+ .pm = &pwmss_pm_ops,
+ .of_match_table = of_match_ptr(pwmss_of_match),
+ },
+ .probe = pwmss_probe,
+ .remove = __devexit_p(pwmss_remove),
+};
+
+module_platform_driver(pwmss_driver);
+
+MODULE_DESCRIPTION("pwmss driver");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/tipwmss.h b/drivers/pwm/tipwmss.h
new file mode 100644
index 0000000..f9cb2e2
--- /dev/null
+++ b/drivers/pwm/tipwmss.h
@@ -0,0 +1,30 @@
+/*
+ * TI PWM Subsystem driver
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __TIPWMSS_H
+#define __TIPWMSS_H
+
+#ifdef CONFIG_PWM_TIPWMSS
+extern u16 pwmss_submodule_state_change(struct device *dev, int set);
+#else
+static inline u16 pwmss_submodule_state_change(struct device *dev, int set)
+{
+ /* return success status value */
+ return 0xFFFF;
+}
+#endif
+#endif /* __TIPWMSS_H */
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 00/10] Support for AM33xx PWM Susbsytem
From: Philip, Avinash @ 2012-11-08 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In AM33xx PWM sub modules like ECAP, EHRPWM & EQEP are integrated to
PWM subsystem. All these submodules shares the resources (clock) & has
a clock gating register in PWM Subsystem. This patch series creates a
parent PWM Subsystem driver to handle access synchronization of shared
resources & clock gating from PWM Subsystem configuration space.
Also Device tree nodes populated to support parent child relation
between PWMSS, ECAP & EHRPWM submodules.
In addition EHRPWM module requires explicit clock gating from control
module & is handled by patch #2 & 8.
Patch #4 & 5 submitted is a second revision as suggested by Thierry
for handling clock gating with a global function . This requires config
space handling done independent from driver and is done at parent driver.
So the parent<->child relation adopted to handle
1. pm runtime synchronization
2. PWM subsystem common config space clock gating for PWM submodules.
Patches supports
- Driver support for parent child relation handled patch #1
- Optional EHRPWM tb clock in patch #2
- Parent child in HWMOD handled at patch #3
- Device tree binding support handled in patch #4, 6 &8
- pinctrl support in patch #5 & 7.
- DT node populated in patch #9 & 10.
This patch series based on linux-next/20121031 and tested on AM33xx.
It depends on [1]
1. https://lkml.org/lkml/2012/10/29/589
pwm: Device tree support for PWM polarity
Philip, Avinash (10):
PWMSS: Add PWM Subsystem driver for parent<->child relationship
ARM: am33xx: clk: Add optional clock for EHRPWM
ARM: OMAP: AM33xx hwmod: Add parent-child relationship for PWM
subsystem
pwm: pwm-tiecap: Add device-tree binding support for APWM driver
pwm: pwm-tiecap: pinctrl support
pwm: pwm-tiehrpwm: Add device-tree binding support for EHRPWM driver
pwm: pwm-tiehrpwm: pinctrl support
pwm: pwm-tiehrpwm: Adding TBCLK gating support.
ARM: dts: AM33XX: Add PWMSS device tree nodes
ARM: dts: AM33XX: Add PWM backlight DT data to am335x-evm
.../devicetree/bindings/pwm/pwm-tiecap.txt | 22 +
.../devicetree/bindings/pwm/pwm-tiehrpwm.txt | 25 ++
Documentation/devicetree/bindings/pwm/tipwmss.txt | 30 ++
arch/arm/boot/dts/am335x-evm.dts | 21 +
arch/arm/boot/dts/am33xx.dtsi | 90 +++++
arch/arm/mach-omap2/clock33xx_data.c | 37 ++
arch/arm/mach-omap2/control.h | 8 +
arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 419 +++++++++++++-------
drivers/pwm/Kconfig | 11 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-tiecap.c | 54 +++-
drivers/pwm/pwm-tiehrpwm.c | 75 ++++-
drivers/pwm/tipwmss.c | 142 +++++++
drivers/pwm/tipwmss.h | 30 ++
14 files changed, 820 insertions(+), 145 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
create mode 100644 Documentation/devicetree/bindings/pwm/tipwmss.txt
create mode 100644 drivers/pwm/tipwmss.c
create mode 100644 drivers/pwm/tipwmss.h
^ permalink raw reply
* [PATCH 7/7] ARM: dma-mapping: remove init_consistent_dma_size() stub
From: Marek Szyprowski @ 2012-11-08 7:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352360783-17523-1-git-send-email-m.szyprowski@samsung.com>
Since commit e9da6e9905e639b0 ("ARM: dma-mapping: remove custom consistent
dma region") setting consistent dma memory size is not longer required. All
calls to this function has been already removed, so the
init_consistent_dma_size() stub can also be gone.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/include/asm/dma-mapping.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 2300484..8ea02ac 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -211,13 +211,6 @@ static inline void dma_free_writecombine(struct device *dev, size_t size,
extern void __init init_dma_coherent_pool_size(unsigned long size);
/*
- * This can be called during boot to increase the size of the consistent
- * DMA region above it's default value of 2MB. It must be called before the
- * memory allocator is initialised, i.e. before any core_initcall.
- */
-static inline void init_consistent_dma_size(unsigned long size) { }
-
-/*
* For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
* and utilize bounce buffers as needed to work around limited DMA windows.
*
--
1.7.9.5
^ permalink raw reply related
* [PATCH 6/7] ARM: u300: remove obsoleted init_consistent_dma_size()
From: Marek Szyprowski @ 2012-11-08 7:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352360783-17523-1-git-send-email-m.szyprowski@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
CC: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/mach-u300/core.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index b8efac4..d8632eb 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -82,8 +82,6 @@ static struct map_desc u300_io_desc[] __initdata = {
static void __init u300_map_io(void)
{
iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
- /* We enable a real big DMA buffer if need be. */
- init_consistent_dma_size(SZ_4M);
}
/*
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox