Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/2] ARM: OMAP2+: Add device-tree support for 32kHz counter
From: Jon Hunter @ 2012-10-19 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds device-tree support for the 32kHz counter on OMAP2+ devices,
which is used as the default kernel clock-source for OMAP devices.

Boot tested on OMAP2420 H4, OMAP3430 Beagle Board and OMAP4430 Panda Board
with and without device-tree present.

Based and dependent upon OMAP2+ series that adds device-tree support for
DMTIMERs [1].

V2 changes:
- Updated counter name in binding per Benoit Cousson's feedback

[1] http://marc.info/?l=linux-omap&m=135065875808614&w=2

Jon Hunter (2):
  ARM: dts: OMAP: Add counter-32k nodes
  ARM: OMAP2+: Add device-tree support for 32kHz counter

 .../devicetree/bindings/arm/omap/counter.txt       |   15 +++++++++++
 arch/arm/boot/dts/omap2420.dtsi                    |    6 +++++
 arch/arm/boot/dts/omap2430.dtsi                    |    6 +++++
 arch/arm/boot/dts/omap3.dtsi                       |    6 +++++
 arch/arm/boot/dts/omap4.dtsi                       |    6 +++++
 arch/arm/mach-omap2/timer.c                        |   28 +++++++++++++++++++-
 6 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/omap/counter.txt

-- 
1.7.9.5

^ permalink raw reply

* [PATCH V4 1/5] ARM: dts: OMAP: Add timer nodes
From: Rob Herring @ 2012-10-19 15:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350658744-13509-2-git-send-email-jon-hunter@ti.com>

On 10/19/2012 09:59 AM, Jon Hunter wrote:
> Add the 12 GP timers nodes present in OMAP2.
> Add the 12 GP timers nodes present in OMAP3.
> Add the 11 GP timers nodes present in OMAP4.
> Add the 7 GP timers nodes present in AM33xx.
> 
> Add documentation for timer properties specific to OMAP.
> 
> Thanks to Vaibhav Hiremath for creating the AM33xx timer nodes. I have modified
> Vaibhav's original nodes adding information on which timers support a PWM
> output.
> 
> Cc: Benoit Cousson <b-cousson@ti.com>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---

The binding looks good, so:

Acked-by: Rob Herring <rob.herring@calxeda.com>

>  .../devicetree/bindings/arm/omap/timer.txt         |   34 +++++++
>  arch/arm/boot/dts/am33xx.dtsi                      |   61 +++++++++++
>  arch/arm/boot/dts/omap2.dtsi                       |   96 ++++++++++++++++++
>  arch/arm/boot/dts/omap2420.dtsi                    |    9 ++
>  arch/arm/boot/dts/omap2430.dtsi                    |    9 ++
>  arch/arm/boot/dts/omap3.dtsi                       |  107 ++++++++++++++++++++
>  arch/arm/boot/dts/omap4.dtsi                       |   97 ++++++++++++++++++
>  7 files changed, 413 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/omap/timer.txt b/Documentation/devicetree/bindings/arm/omap/timer.txt
> new file mode 100644
> index 0000000..f31d803
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/omap/timer.txt
> @@ -0,0 +1,34 @@
> +OMAP Timer bindings
> +
> +Required properties:
> +- compatible:		Must be "ti,omap2-timer" for OMAP2+ controllers.
> +- reg:			Contains timer register address range (base address and
> +			length).
> +- interrupts: 		Contains the interrupt information for the timer. The
> +			format is being dependent on which interrupt controller
> +			the OMAP device uses.
> +- interrupt-parent	The phandle for the interrupt controller that services
> +			interrupts for this device.
> +- ti,hwmods:		Name of the hwmod associated to the timer, "timer<X>",
> +			where <X> is the instance number of the timer from the
> +			HW spec.
> +
> +Optional properties:
> +- ti,timer-alwon:	Indicates the timer is in an alway-on power domain.
> +- ti,timer-dsp:		Indicates the timer can interrupt the on-chip DSP in
> +			addition to the ARM CPU.
> +- ti,timer-pwm: 	Indicates the timer can generate a PWM output.
> +- ti,timer-secure: 	Indicates the timer is reserved on a secure OMAP device
> +			and therefore cannot be used by the kernel.
> +
> +Example:
> +
> +timer12: timer at 48304000 {
> +	compatible = "ti,omap2-timer";
> +	reg = <0x48304000 0xfff>;
> +	interrupts = <95>;
> +	interrupt-parent = <&intc>;
> +	ti,hwmods = "timer12"
> +	ti,timer-alwon;
> +	ti,timer-secure;
> +};
> diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
> index bb31bff..fd5074c 100644
> --- a/arch/arm/boot/dts/am33xx.dtsi
> +++ b/arch/arm/boot/dts/am33xx.dtsi
> @@ -210,5 +210,66 @@
>  			interrupt-parent = <&intc>;
>  			interrupts = <91>;
>  		};
> +
> +		timer1: timer at 44e31000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x44e31000 0x1000>;
> +			interrupt-parent = <&intc>;
> +			interrupts = <67>;
> +			ti,hwmods = "timer1";
> +			ti,timer-alwon;
> +		};
> +
> +		timer2: timer at 48040000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48040000 0x1000>;
> +			interrupt-parent = <&intc>;
> +			interrupts = <68>;
> +			ti,hwmods = "timer2";
> +		};
> +
> +		timer3: timer at 48042000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48042000 0x1000>;
> +			interrupt-parent = <&intc>;
> +			interrupts = <69>;
> +			ti,hwmods = "timer3";
> +		};
> +
> +		timer4: timer at 48044000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48044000 0x1000>;
> +			interrupt-parent = <&intc>;
> +			interrupts = <92>;
> +			ti,hwmods = "timer4";
> +			ti,timer-pwm;
> +		};
> +
> +		timer5: timer at 48046000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48046000 0x1000>;
> +			interrupt-parent = <&intc>;
> +			interrupts = <93>;
> +			ti,hwmods = "timer5";
> +			ti,timer-pwm;
> +		};
> +
> +		timer6: timer at 48048000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48048000 0x1000>;
> +			interrupt-parent = <&intc>;
> +			interrupts = <94>;
> +			ti,hwmods = "timer6";
> +			ti,timer-pwm;
> +		};
> +
> +		timer7: timer at 4804a000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4804a000 0x1000>;
> +			interrupt-parent = <&intc>;
> +			interrupts = <95>;
> +			ti,hwmods = "timer7";
> +			ti,timer-pwm;
> +		};
>  	};
>  };
> diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi
> index 581cb08..4e57138 100644
> --- a/arch/arm/boot/dts/omap2.dtsi
> +++ b/arch/arm/boot/dts/omap2.dtsi
> @@ -65,5 +65,101 @@
>  			ti,hwmods = "uart3";
>  			clock-frequency = <48000000>;
>  		};
> +
> +		timer2: timer at 4802a000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4802a000 0xfff>;
> +			interrupts = <38>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer2";
> +		};
> +
> +		timer3: timer at 48078000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48078000 0xfff>;
> +			interrupts = <39>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer3";
> +		};
> +
> +		timer4: timer at 4807a000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4807a000 0xfff>;
> +			interrupts = <40>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer4";
> +		};
> +
> +		timer5: timer at 4807c000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4807c000 0xfff>;
> +			interrupts = <41>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer5";
> +			ti,timer-dsp;
> +		};
> +
> +		timer6: timer at 4807e000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4807e000 0xfff>;
> +			interrupts = <42>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer6";
> +			ti,timer-dsp;
> +		};
> +
> +		timer7: timer at 48080000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48080000 0xfff>;
> +			interrupts = <43>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer7";
> +			ti,timer-dsp;
> +		};
> +
> +		timer8: timer at 48082000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48082000 0xfff>;
> +			interrupts = <44>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer8";
> +			ti,timer-dsp;
> +		};
> +
> +		timer9: timer at 48084000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48084000 0xfff>;
> +			interrupts = <45>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer9";
> +			ti,timer-pwm;
> +		};
> +
> +		timer10: timer at 48086000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48086000 0xfff>;
> +			interrupts = <46>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer10";
> +			ti,timer-pwm;
> +		};
> +
> +		timer11: timer at 48088000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48088000 0xfff>;
> +			interrupts = <47>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer11";
> +			ti,timer-pwm;
> +		};
> +
> +		timer12: timer at 4808a000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4808a000 0xfff>;
> +			interrupts = <48>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer12";
> +			ti,timer-pwm;
> +		};
>  	};
>  };
> diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi
> index bfd76b4..13cfa2c 100644
> --- a/arch/arm/boot/dts/omap2420.dtsi
> +++ b/arch/arm/boot/dts/omap2420.dtsi
> @@ -44,5 +44,14 @@
>  			interrupt-parent = <&intc>;
>  			ti,hwmods = "mcbsp2";
>  		};
> +
> +		timer1: timer at 48028000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48028000 0xfff>;
> +			interrupts = <37>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer1";
> +			ti,timer-alwon;
> +		};
>  	};
>  };
> diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi
> index 4565d97..886b825 100644
> --- a/arch/arm/boot/dts/omap2430.dtsi
> +++ b/arch/arm/boot/dts/omap2430.dtsi
> @@ -88,5 +88,14 @@
>  			ti,buffer-size = <128>;
>  			ti,hwmods = "mcbsp5";
>  		};
> +
> +		timer1: timer at 49018000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x49018000 0xfff>;
> +			interrupts = <37>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer1";
> +			ti,timer-alwon;
> +		};
>  	};
>  };
> diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
> index f38ea87..1fba998 100644
> --- a/arch/arm/boot/dts/omap3.dtsi
> +++ b/arch/arm/boot/dts/omap3.dtsi
> @@ -300,5 +300,112 @@
>  			ti,buffer-size = <128>;
>  			ti,hwmods = "mcbsp5";
>  		};
> +
> +		timer1: timer at 48318000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48318000 0xfff>;
> +			interrupts = <37>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer1";
> +			ti,timer-alwon;
> +		};
> +
> +		timer2: timer at 49032000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x49032000 0xfff>;
> +			interrupts = <38>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer2";
> +		};
> +
> +		timer3: timer at 49034000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x49034000 0xfff>;
> +			interrupts = <39>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer3";
> +		};
> +
> +		timer4: timer at 49036000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x49036000 0xfff>;
> +			interrupts = <40>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer4";
> +		};
> +
> +		timer5: timer at 49038000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x49038000 0xfff>;
> +			interrupts = <41>;
> +			ti,hwmods = "timer5";
> +			interrupt-parent = <&intc>;
> +			ti,timer-dsp;
> +		};
> +
> +		timer6: timer at 4903a000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4903a000 0xfff>;
> +			interrupts = <42>;
> +			ti,hwmods = "timer6";
> +			interrupt-parent = <&intc>;
> +			ti,timer-dsp;
> +		};
> +
> +		timer7: timer at 4903c000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4903c000 0xfff>;
> +			interrupts = <43>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer7";
> +			ti,timer-dsp;
> +		};
> +
> +		timer8: timer at 4903e000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4903e000 0xfff>;
> +			interrupts = <44>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer8";
> +			ti,timer-pwm;
> +			ti,timer-dsp;
> +		};
> +
> +		timer9: timer at 49040000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x49040000 0xfff>;
> +			interrupts = <45>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer9";
> +			ti,timer-pwm;
> +		};
> +
> +		timer10: timer at 48086000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48086000 0xfff>;
> +			interrupts = <46>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer10";
> +			ti,timer-pwm;
> +		};
> +
> +		timer11: timer at 48088000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48088000 0xfff>;
> +			interrupts = <47>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer11";
> +			ti,timer-pwm;
> +		};
> +
> +		timer12: timer at 48304000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48304000 0xfff>;
> +			interrupts = <95>;
> +			interrupt-parent = <&intc>;
> +			ti,hwmods = "timer12";
> +			ti,timer-alwon;
> +			ti,timer-secure;
> +		};
>  	};
>  };
> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
> index 3883f94..f9572bf 100644
> --- a/arch/arm/boot/dts/omap4.dtsi
> +++ b/arch/arm/boot/dts/omap4.dtsi
> @@ -438,5 +438,102 @@
>  			ranges;
>  			ti,hwmods = "ocp2scp_usb_phy";
>  		};
> +
> +		timer1: timer at 4a318000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4a318000 0x7f>;
> +			interrupts = <0 37 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer1";
> +			ti,timer-alwon;
> +		};
> +
> +		timer2: timer at 48032000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48032000 0x7f>;
> +			interrupts = <0 38 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer2";
> +		};
> +
> +		timer3: timer at 48034000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48034000 0x7f>;
> +			interrupts = <0 39 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer3";
> +		};
> +
> +		timer4: timer at 48036000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48036000 0x7f>;
> +			interrupts = <0 40 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer4";
> +		};
> +
> +		timer5: timer at 49038000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x49038000 0x7f>;
> +			interrupts = <0 41 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer5";
> +			ti,timer-dsp;
> +		};
> +
> +		timer6: timer at 4903a000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4903a000 0x7f>;
> +			interrupts = <0 42 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer6";
> +			ti,timer-dsp;
> +		};
> +
> +		timer7: timer at 4903c000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4903c000 0x7f>;
> +			interrupts = <0 43 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer7";
> +			ti,timer-dsp;
> +		};
> +
> +		timer8: timer at 4903e000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4903e000 0x7f>;
> +			interrupts = <0 44 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer8";
> +			ti,timer-pwm;
> +			ti,timer-dsp;
> +		};
> +
> +		timer9: timer at 4803e000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x4803e000 0x7f>;
> +			interrupts = <0 45 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer9";
> +			ti,timer-pwm;
> +		};
> +
> +		timer10: timer at 48086000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48086000 0x7f>;
> +			interrupts = <0 46 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer10";
> +			ti,timer-pwm;
> +		};
> +
> +		timer11: timer at 48088000 {
> +			compatible = "ti,omap2-timer";
> +			reg = <0x48088000 0x7f>;
> +			interrupts = <0 47 0x4>;
> +			interrupt-parent = <&gic>;
> +			ti,hwmods = "timer11";
> +			ti,timer-pwm;
> +		};
>  	};
>  };
> 

^ permalink raw reply

* [PATCH V4 5/5] ARM: OMAP: Add DT support for timer driver
From: Jon Hunter @ 2012-10-19 14:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350658744-13509-1-git-send-email-jon-hunter@ti.com>

In order to add device-tree support to the timer driver the following changes
were made ...

1. Allocate system timers (used for clock-events and clock-source) based upon
   timer properties rather than using an hard-coded timer instance ID. To allow
   this a new helper function called omap_dmtimer_find_by_property() has been
   added for finding a timer with the particular properties in the device-tree
   blob. Please note that this is an internal helper function for system timers
   only to find a timer in the device-tree blob. This cannot be used by device
   drivers, another API has been added for that (see below). Timers that are
   allocated for system timers are dynamically disabled at boot time by adding
   a status property with the value "disabled" to the timer's device-tree node.

   Please note that when allocating system timers we now pass a timer ID and
   timer property. The timer ID is only be used for allocating a timer when
   booting without device-tree. Once device-tree migration is complete, all
   the timer ID references will be removed.

2. System timer resources (memory and interrupts) are directly obtained from
   the device-tree timer node when booting with device-tree, so that system
   timers are no longer reliant upon the OMAP HWMOD framework to provide these
   resources.

3. If DT blob is present, then let device-tree create the timer devices
   dynamically.

4. When device-tree is present the "id" field in the platform_device structure
   (pdev->id) is initialised to -1 and hence cannot be used to identify a timer
   instance. Due to this the following changes were made ...
   a). The API omap_dm_timer_request_specific() is not supported when using
       device-tree, because it uses the device ID to request a specific timer.
       This function will return an error if called when device-tree is present.
       Users of this API should use omap_dm_timer_request_by_cap() instead.
   b). When removing the DMTIMER driver, the timer "id" was used to identify the
       timer instance. The remove function has been modified to use the device
       name instead of the "id".

5. When device-tree is present the platform_data structure will be NULL and so
   check for this.

6. The OMAP timer device tree binding has the following optional parameters ...
   a). ti,timer-alwon  --> Timer is in an always-on power domain
   b). ti,timer-dsp    --> Timer can generate an interrupt to the on-chip DSP
   c). ti,timer-pwm    --> Timer can generate a PWM output
   d). ti,timer-secure --> Timer is reserved on a secure OMAP device
   Search for the above parameters and set the appropriate timer attribute
   flags.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/timer.c  |  147 +++++++++++++++++++++++++++++++-----------
 arch/arm/plat-omap/dmtimer.c |   41 ++++++++++--
 2 files changed, 146 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 96d26f2..9a47f3d 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -37,6 +37,8 @@
 #include <linux/clockchips.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
 #include <asm/smp_twd.h>
@@ -66,11 +68,13 @@
 #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 REALTIME_COUNTER_BASE				0x48243200
@@ -156,6 +160,40 @@ static struct of_device_id omap_timer_match[] __initdata = {
 };
 
 /**
+ * omap_get_timer_dt - get a timer using device-tree
+ * @match	- device-tree match structure for matching a device type
+ * @property	- optional timer property to match
+ *
+ * Helper function to get a timer during early boot using device-tree for use
+ * as kernel system timer. Optionally, the property argument can be used to
+ * select a timer with a specific property. Once a timer is found then mark
+ * the timer node in device-tree as disabled, to prevent the kernel from
+ * registering this timer as a platform device and so no one else can use it.
+ */
+static struct device_node * __init omap_get_timer_dt(struct of_device_id *match,
+						     const char *property)
+{
+	struct device_node *np;
+
+	for_each_matching_node(np, match) {
+		if (!of_device_is_available(np)) {
+			of_node_put(np);
+			continue;
+		}
+
+		if (property && !of_get_property(np, property, NULL)) {
+			of_node_put(np);
+			continue;
+		}
+
+		prom_add_property(np, &device_disabled);
+		return np;
+	}
+
+	return NULL;
+}
+
+/**
  * omap_dmtimer_init - initialisation function when device tree is used
  *
  * For secure OMAP3 devices, timers with device type "timer-secure" cannot
@@ -172,43 +210,74 @@ void __init omap_dmtimer_init(void)
 
 	/* If we are a secure device, remove any secure timer nodes */
 	if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) {
-		for_each_matching_node(np, omap_timer_match) {
-			if (of_get_property(np, "ti,timer-secure", NULL))
-				prom_add_property(np, &device_disabled);
-		}
+		np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure");
+		if (np)
+			of_node_put(np);
 	}
 }
 
 static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 						int gptimer_id,
-						const char *fck_source)
+						const char *fck_source,
+						const char *property)
 {
 	char name[10]; /* 10 = sizeof("gptXX_Xck0") */
+	const char *oh_name;
+	struct device_node *np;
 	struct omap_hwmod *oh;
 	struct resource irq_rsrc, mem_rsrc;
 	size_t size;
 	int res = 0;
 	int r;
 
-	sprintf(name, "timer%d", gptimer_id);
-	omap_hwmod_setup_one(name);
-	oh = omap_hwmod_lookup(name);
+	if (of_have_populated_dt()) {
+		np = omap_get_timer_dt(omap_timer_match, NULL);
+		if (!np)
+			return -ENODEV;
+
+		of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
+		if (!oh_name)
+			return -ENODEV;
+
+		timer->irq = irq_of_parse_and_map(np, 0);
+		if (!timer->irq)
+			return -ENXIO;
+
+		timer->io_base = of_iomap(np, 0);
+
+		of_node_put(np);
+	} else {
+		if (omap_dm_timer_reserve_systimer(gptimer_id))
+			return -ENODEV;
+
+		sprintf(name, "timer%d", gptimer_id);
+		oh_name = name;
+	}
+
+	omap_hwmod_setup_one(oh_name);
+	oh = omap_hwmod_lookup(oh_name);
+
 	if (!oh)
 		return -ENODEV;
 
-	r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, &irq_rsrc);
-	if (r)
-		return -ENXIO;
-	timer->irq = irq_rsrc.start;
-
-	r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, &mem_rsrc);
-	if (r)
-		return -ENXIO;
-	timer->phys_base = mem_rsrc.start;
-	size = mem_rsrc.end - mem_rsrc.start;
+	if (!of_have_populated_dt()) {
+		r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,
+						   &irq_rsrc);
+		if (r)
+			return -ENXIO;
+		timer->irq = irq_rsrc.start;
+
+		r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL,
+						   &mem_rsrc);
+		if (r)
+			return -ENXIO;
+		timer->phys_base = mem_rsrc.start;
+		size = mem_rsrc.end - mem_rsrc.start;
+
+		/* Static mapping, never released */
+		timer->io_base = ioremap(timer->phys_base, size);
+	}
 
-	/* Static mapping, never released */
-	timer->io_base = ioremap(timer->phys_base, size);
 	if (!timer->io_base)
 		return -ENXIO;
 
@@ -219,9 +288,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 
 	omap_hwmod_enable(oh);
 
-	if (omap_dm_timer_reserve_systimer(gptimer_id))
-		return -ENODEV;
-
+	/* FIXME: Need to remove hard-coded test on timer ID */
 	if (gptimer_id != 12) {
 		struct clk *src;
 
@@ -231,8 +298,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 		} else {
 			res = __omap_dm_timer_set_source(timer->fclk, src);
 			if (IS_ERR_VALUE(res))
-				pr_warning("%s: timer%i cannot set source\n",
-						__func__, gptimer_id);
+				pr_warn("%s: %s cannot set source\n",
+					__func__, oh->name);
 			clk_put(src);
 		}
 	}
@@ -248,11 +315,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 }
 
 static void __init omap2_gp_clockevent_init(int gptimer_id,
-						const char *fck_source)
+						const char *fck_source,
+						const char *property)
 {
 	int res;
 
-	res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source);
+	res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property);
 	BUG_ON(res);
 
 	omap2_gp_timer_irq.dev_id = &clkev;
@@ -356,7 +424,7 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
 {
 	int res;
 
-	res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source);
+	res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL);
 	BUG_ON(res);
 
 	__omap_dm_timer_load_start(&clksrc,
@@ -468,12 +536,12 @@ static inline void __init realtime_counter_init(void)
 {}
 #endif
 
-#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src,			\
+#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop,	\
 				clksrc_nr, clksrc_src)			\
 static void __init omap##name##_timer_init(void)			\
 {									\
 	omap_dmtimer_init();						\
-	omap2_gp_clockevent_init((clkev_nr), clkev_src);		\
+	omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop);	\
 	omap2_clocksource_init((clksrc_nr), clksrc_src);		\
 }
 
@@ -483,20 +551,23 @@ struct sys_timer omap##name##_timer = {					\
 };
 
 #ifdef CONFIG_ARCH_OMAP2
-OMAP_SYS_TIMER_INIT(2, 1, OMAP2_CLKEV_SOURCE, 2, OMAP2_MPU_SOURCE)
+OMAP_SYS_TIMER_INIT(2, 1, OMAP2_CLKEV_SOURCE, "ti,timer-alwon",
+		    2, OMAP2_MPU_SOURCE)
 OMAP_SYS_TIMER(2)
 #endif
 
 #ifdef CONFIG_ARCH_OMAP3
-OMAP_SYS_TIMER_INIT(3, 1, OMAP3_CLKEV_SOURCE, 2, OMAP3_MPU_SOURCE)
+OMAP_SYS_TIMER_INIT(3, 1, OMAP3_CLKEV_SOURCE, "ti,timer-alwon",
+		    2, OMAP3_MPU_SOURCE)
 OMAP_SYS_TIMER(3)
 OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE,
-			2, OMAP3_MPU_SOURCE)
+			TIMER_PROP_SECURE, 2, OMAP3_MPU_SOURCE)
 OMAP_SYS_TIMER(3_secure)
 #endif
 
 #ifdef CONFIG_SOC_AM33XX
-OMAP_SYS_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, 2, OMAP4_MPU_SOURCE)
+OMAP_SYS_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon",
+		    2, OMAP4_MPU_SOURCE)
 OMAP_SYS_TIMER(3_am33xx)
 #endif
 
@@ -508,7 +579,7 @@ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
 
 static void __init omap4_timer_init(void)
 {
-	omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
+	omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE, "ti,timer-alwon");
 	omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
 #ifdef CONFIG_LOCAL_TIMERS
 	/* Local timers are not supprted on OMAP4430 ES1.0 */
@@ -534,7 +605,7 @@ static void __init omap5_timer_init(void)
 {
 	int err;
 
-	omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
+	omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE, "ti,timer-alwon");
 	omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
 	realtime_counter_init();
 
@@ -619,6 +690,10 @@ static int __init omap2_dm_timer_init(void)
 {
 	int ret;
 
+	/* If dtb is there, the devices will be created dynamically */
+	if (of_have_populated_dt())
+		return -ENODEV;
+
 	ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL);
 	if (unlikely(ret)) {
 		pr_err("%s: device registration failed.\n", __func__);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 2574b86..b09e556 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -40,6 +40,8 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <plat/dmtimer.h>
 #include <plat/omap-pm.h>
@@ -212,6 +214,13 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 	unsigned long flags;
 	int ret = 0;
 
+	/* Requesting timer by ID is not supported when device tree is used */
+	if (of_have_populated_dt()) {
+		pr_warn("%s: Please use omap_dm_timer_request_by_cap()\n",
+			__func__);
+		return NULL;
+	}
+
 	spin_lock_irqsave(&dm_timer_lock, flags);
 	list_for_each_entry(t, &omap_timer_list, node) {
 		if (t->pdev->id == id && !t->reserved) {
@@ -466,7 +475,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 	 * use the clock framework to set the parent clock. To be removed
 	 * once OMAP1 migrated to using clock framework for dmtimers
 	 */
-	if (pdata->set_timer_src)
+	if (pdata && pdata->set_timer_src)
 		return pdata->set_timer_src(timer->pdev, source);
 
 	fclk = clk_get(&timer->pdev->dev, "fck");
@@ -747,7 +756,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
 
-	if (!pdata) {
+	if (!pdata && !dev->of_node) {
 		dev_err(dev, "%s: no platform data.\n", __func__);
 		return -ENODEV;
 	}
@@ -776,11 +785,23 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	timer->id = pdev->id;
+	if (dev->of_node) {
+		if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
+			timer->capability |= OMAP_TIMER_ALWON;
+		if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
+			timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
+		if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
+			timer->capability |= OMAP_TIMER_HAS_PWM;
+		if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
+			timer->capability |= OMAP_TIMER_SECURE;
+	} else {
+		timer->id = pdev->id;
+		timer->capability = pdata->timer_capability;
+		timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
+	}
+
 	timer->irq = irq->start;
-	timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
 	timer->pdev = pdev;
-	timer->capability = pdata->timer_capability;
 
 	/* Skip pm_runtime_enable for OMAP1 */
 	if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
@@ -820,7 +841,8 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
 
 	spin_lock_irqsave(&dm_timer_lock, flags);
 	list_for_each_entry(timer, &omap_timer_list, node)
-		if (timer->pdev->id == pdev->id) {
+		if (!strcmp(dev_name(&timer->pdev->dev),
+			    dev_name(&pdev->dev))) {
 			list_del(&timer->node);
 			ret = 0;
 			break;
@@ -830,11 +852,18 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
 	return ret;
 }
 
+static const struct of_device_id omap_timer_match[] = {
+	{ .compatible = "ti,omap2-timer", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, omap_timer_match);
+
 static struct platform_driver omap_dm_timer_driver = {
 	.probe  = omap_dm_timer_probe,
 	.remove = __devexit_p(omap_dm_timer_remove),
 	.driver = {
 		.name   = "omap_timer",
+		.of_match_table = of_match_ptr(omap_timer_match),
 	},
 };
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V4 4/5] ARM: OMAP3: Add generic machine descriptor for boards with OMAP3 GP devices
From: Jon Hunter @ 2012-10-19 14:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350658744-13509-1-git-send-email-jon-hunter@ti.com>

OMAP3 devices may or may not have security features enabled. Security enabled
devices are known as high-secure (HS) and devices without security are known as
general purpose (GP).

Some OMAP3 boards, such as the OMAP3 beagle board, only use GP devices and for
GP devices there is a 12th timer available on-chip that can operate at 32kHz.
The clock for 12th timer is generated by an internal oscillator and is unique
this timer. Boards such as the beagle board use this timer as a 32kHz based
clock-events timer because early versions of the board had a hardware problem
preventing them from using other on-chip timers clocked by a external 32kHz
clock.

When booting with device-tree all OMAP3 devices use timer 1 by default for
the clock-events timer. Therefore, add a generic machine descriptor for boards
with OMAP3 GP devices so that they can use the 12th timer as the clock-events
timer instead of the default.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/board-generic.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 601ecdf..d690180 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -97,6 +97,23 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
 	.dt_compat	= omap3_boards_compat,
 	.restart	= omap_prcm_restart,
 MACHINE_END
+
+static const char *omap3_gp_boards_compat[] __initdata = {
+	"ti,omap3-beagle",
+	NULL,
+};
+
+DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
+	.reserve	= omap_reserve,
+	.map_io		= omap3_map_io,
+	.init_early	= omap3430_init_early,
+	.init_irq	= omap_intc_of_init,
+	.handle_irq	= omap3_intc_handle_irq,
+	.init_machine	= omap_generic_init,
+	.timer		= &omap3_secure_timer,
+	.dt_compat	= omap3_gp_boards_compat,
+	.restart	= omap_prcm_restart,
+MACHINE_END
 #endif
 
 #ifdef CONFIG_SOC_AM33XX
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V4 3/5] ARM: OMAP: Add function to request a timer by capability
From: Jon Hunter @ 2012-10-19 14:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350658744-13509-1-git-send-email-jon-hunter@ti.com>

Currently OMAP timers can be requested by requesting any available or by a
numerical device ID. If a specific timer is required because it has a particular
capability, such as can interrupt the on-chip DSP in addition to the ARM CPU,
then the user needs to know the device ID of the timer with this feature.
Therefore, add a new API called omap_dm_timer_request_by_cap() that allows
drivers to request a timer by capability.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/plat-omap/dmtimer.c              |   52 +++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/dmtimer.h |    1 +
 2 files changed, 53 insertions(+)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 938b50a..2574b86 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -237,6 +237,58 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
+/**
+ * omap_dm_timer_request_by_cap - Request a timer by capability
+ * @cap:	Bit mask of capabilities to match
+ *
+ * Find a timer based upon capabilities bit mask. Callers of this function
+ * should use the definitions found in the plat/dmtimer.h file under the
+ * comment "timer capabilities used in hwmod database". Returns pointer to
+ * timer handle on success and a NULL pointer on failure.
+ */
+struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
+{
+	struct omap_dm_timer *timer = NULL, *t;
+	unsigned long flags;
+
+	if (!cap)
+		return NULL;
+
+	spin_lock_irqsave(&dm_timer_lock, flags);
+	list_for_each_entry(t, &omap_timer_list, node) {
+		if ((!t->reserved) && ((t->capability & cap) == cap)) {
+			/*
+			 * If timer is not NULL, we have already found one timer
+			 * but it was not an exact match because it had more
+			 * capabilites that what was required. Therefore,
+			 * unreserve the last timer found and see if this one
+			 * is a better match.
+			 */
+			if (timer)
+				timer->reserved = 0;
+
+			timer = t;
+			timer->reserved = 1;
+
+			/* Exit loop early if we find an exact match */
+			if (t->capability == cap)
+				break;
+		}
+	}
+	spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+	if (timer && omap_dm_timer_prepare(timer)) {
+		timer->reserved = 0;
+		timer = NULL;
+	}
+
+	if (!timer)
+		pr_debug("%s: timer request failed!\n", __func__);
+
+	return timer;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
+
 int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer))
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 85868e9..348f855 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -99,6 +99,7 @@ struct dmtimer_platform_data {
 int omap_dm_timer_reserve_systimer(int id);
 struct omap_dm_timer *omap_dm_timer_request(void);
 struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
+struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
 int omap_dm_timer_free(struct omap_dm_timer *timer);
 void omap_dm_timer_enable(struct omap_dm_timer *timer);
 void omap_dm_timer_disable(struct omap_dm_timer *timer);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V4 2/5] ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
From: Jon Hunter @ 2012-10-19 14:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350658744-13509-1-git-send-email-jon-hunter@ti.com>

OMAP3 devices may or may not have security features enabled. Security enabled
devices are known as high-secure (HS) and devices without security are known as
general purpose (GP).

For OMAP3 devices there are 12 general purpose timers available. On secure
devices the 12th timer is reserved for secure usage and so cannot be used by
the kernel, where as for a GP device it is available. We can detect the OMAP
device type, secure or GP, at runtime via an on-chip register. Today, when not
using DT, we do not register the 12th timer as a linux device if the device is
secure.

When using device tree, device tree is going to register all the timer devices
it finds in the device tree blob. To prevent device tree from registering 12th
timer on a secure OMAP3 device we can add a status property to the timer
binding with the value "disabled" at boot time. Note that timer 12 on a OMAP3
device has a property "ti,timer-secure" to indicate that it will not be
available on a secure device and so for secure OMAP3 devices, we search for
timers with this property and then disable them. Using the prom_add_property()
function to dynamically add a property was a recommended approach suggested by
Rob Herring [1].

I have tested this on an OMAP3 GP device and faking it to pretend to be a
secure device to ensure that any timers marked with "ti,timer-secure" are not
registered on boot. I have also made sure that all timers are registered as
expected on a GP device by default.

[1] http://comments.gmane.org/gmane.linux.ports.arm.omap/79203

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/timer.c |   36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 44f9aa7..96d26f2 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -144,6 +144,41 @@ static struct clock_event_device clockevent_gpt = {
 	.set_mode	= omap2_gp_timer_set_mode,
 };
 
+static struct property device_disabled = {
+	.name = "status",
+	.length = sizeof("disabled"),
+	.value = "disabled",
+};
+
+static struct of_device_id omap_timer_match[] __initdata = {
+	{ .compatible = "ti,omap2-timer", },
+	{ }
+};
+
+/**
+ * omap_dmtimer_init - initialisation function when device tree is used
+ *
+ * For secure OMAP3 devices, timers with device type "timer-secure" cannot
+ * be used by the kernel as they are reserved. Therefore, to prevent the
+ * kernel registering these devices remove them dynamically from the device
+ * tree on boot.
+ */
+void __init omap_dmtimer_init(void)
+{
+	struct device_node *np;
+
+	if (!cpu_is_omap34xx())
+		return;
+
+	/* If we are a secure device, remove any secure timer nodes */
+	if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+		for_each_matching_node(np, omap_timer_match) {
+			if (of_get_property(np, "ti,timer-secure", NULL))
+				prom_add_property(np, &device_disabled);
+		}
+	}
+}
+
 static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 						int gptimer_id,
 						const char *fck_source)
@@ -437,6 +472,7 @@ static inline void __init realtime_counter_init(void)
 				clksrc_nr, clksrc_src)			\
 static void __init omap##name##_timer_init(void)			\
 {									\
+	omap_dmtimer_init();						\
 	omap2_gp_clockevent_init((clkev_nr), clkev_src);		\
 	omap2_clocksource_init((clksrc_nr), clksrc_src);		\
 }
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V4 1/5] ARM: dts: OMAP: Add timer nodes
From: Jon Hunter @ 2012-10-19 14:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350658744-13509-1-git-send-email-jon-hunter@ti.com>

Add the 12 GP timers nodes present in OMAP2.
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.
Add the 7 GP timers nodes present in AM33xx.

Add documentation for timer properties specific to OMAP.

Thanks to Vaibhav Hiremath for creating the AM33xx timer nodes. I have modified
Vaibhav's original nodes adding information on which timers support a PWM
output.

Cc: Benoit Cousson <b-cousson@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 .../devicetree/bindings/arm/omap/timer.txt         |   34 +++++++
 arch/arm/boot/dts/am33xx.dtsi                      |   61 +++++++++++
 arch/arm/boot/dts/omap2.dtsi                       |   96 ++++++++++++++++++
 arch/arm/boot/dts/omap2420.dtsi                    |    9 ++
 arch/arm/boot/dts/omap2430.dtsi                    |    9 ++
 arch/arm/boot/dts/omap3.dtsi                       |  107 ++++++++++++++++++++
 arch/arm/boot/dts/omap4.dtsi                       |   97 ++++++++++++++++++
 7 files changed, 413 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txt

diff --git a/Documentation/devicetree/bindings/arm/omap/timer.txt b/Documentation/devicetree/bindings/arm/omap/timer.txt
new file mode 100644
index 0000000..f31d803
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/timer.txt
@@ -0,0 +1,34 @@
+OMAP Timer bindings
+
+Required properties:
+- compatible:		Must be "ti,omap2-timer" for OMAP2+ controllers.
+- reg:			Contains timer register address range (base address and
+			length).
+- interrupts: 		Contains the interrupt information for the timer. The
+			format is being dependent on which interrupt controller
+			the OMAP device uses.
+- interrupt-parent	The phandle for the interrupt controller that services
+			interrupts for this device.
+- ti,hwmods:		Name of the hwmod associated to the timer, "timer<X>",
+			where <X> is the instance number of the timer from the
+			HW spec.
+
+Optional properties:
+- ti,timer-alwon:	Indicates the timer is in an alway-on power domain.
+- ti,timer-dsp:		Indicates the timer can interrupt the on-chip DSP in
+			addition to the ARM CPU.
+- ti,timer-pwm: 	Indicates the timer can generate a PWM output.
+- ti,timer-secure: 	Indicates the timer is reserved on a secure OMAP device
+			and therefore cannot be used by the kernel.
+
+Example:
+
+timer12: timer at 48304000 {
+	compatible = "ti,omap2-timer";
+	reg = <0x48304000 0xfff>;
+	interrupts = <95>;
+	interrupt-parent = <&intc>;
+	ti,hwmods = "timer12"
+	ti,timer-alwon;
+	ti,timer-secure;
+};
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index bb31bff..fd5074c 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -210,5 +210,66 @@
 			interrupt-parent = <&intc>;
 			interrupts = <91>;
 		};
+
+		timer1: timer at 44e31000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x44e31000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <67>;
+			ti,hwmods = "timer1";
+			ti,timer-alwon;
+		};
+
+		timer2: timer at 48040000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48040000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <68>;
+			ti,hwmods = "timer2";
+		};
+
+		timer3: timer at 48042000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48042000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <69>;
+			ti,hwmods = "timer3";
+		};
+
+		timer4: timer at 48044000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48044000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <92>;
+			ti,hwmods = "timer4";
+			ti,timer-pwm;
+		};
+
+		timer5: timer at 48046000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48046000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <93>;
+			ti,hwmods = "timer5";
+			ti,timer-pwm;
+		};
+
+		timer6: timer at 48048000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48048000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <94>;
+			ti,hwmods = "timer6";
+			ti,timer-pwm;
+		};
+
+		timer7: timer at 4804a000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4804a000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <95>;
+			ti,hwmods = "timer7";
+			ti,timer-pwm;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi
index 581cb08..4e57138 100644
--- a/arch/arm/boot/dts/omap2.dtsi
+++ b/arch/arm/boot/dts/omap2.dtsi
@@ -65,5 +65,101 @@
 			ti,hwmods = "uart3";
 			clock-frequency = <48000000>;
 		};
+
+		timer2: timer at 4802a000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4802a000 0xfff>;
+			interrupts = <38>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer2";
+		};
+
+		timer3: timer at 48078000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48078000 0xfff>;
+			interrupts = <39>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer3";
+		};
+
+		timer4: timer at 4807a000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4807a000 0xfff>;
+			interrupts = <40>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer4";
+		};
+
+		timer5: timer at 4807c000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4807c000 0xfff>;
+			interrupts = <41>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer5";
+			ti,timer-dsp;
+		};
+
+		timer6: timer at 4807e000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4807e000 0xfff>;
+			interrupts = <42>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer6";
+			ti,timer-dsp;
+		};
+
+		timer7: timer at 48080000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48080000 0xfff>;
+			interrupts = <43>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer7";
+			ti,timer-dsp;
+		};
+
+		timer8: timer at 48082000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48082000 0xfff>;
+			interrupts = <44>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer8";
+			ti,timer-dsp;
+		};
+
+		timer9: timer at 48084000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48084000 0xfff>;
+			interrupts = <45>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer9";
+			ti,timer-pwm;
+		};
+
+		timer10: timer at 48086000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48086000 0xfff>;
+			interrupts = <46>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer10";
+			ti,timer-pwm;
+		};
+
+		timer11: timer at 48088000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48088000 0xfff>;
+			interrupts = <47>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer11";
+			ti,timer-pwm;
+		};
+
+		timer12: timer at 4808a000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4808a000 0xfff>;
+			interrupts = <48>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer12";
+			ti,timer-pwm;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi
index bfd76b4..13cfa2c 100644
--- a/arch/arm/boot/dts/omap2420.dtsi
+++ b/arch/arm/boot/dts/omap2420.dtsi
@@ -44,5 +44,14 @@
 			interrupt-parent = <&intc>;
 			ti,hwmods = "mcbsp2";
 		};
+
+		timer1: timer at 48028000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48028000 0xfff>;
+			interrupts = <37>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer1";
+			ti,timer-alwon;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi
index 4565d97..886b825 100644
--- a/arch/arm/boot/dts/omap2430.dtsi
+++ b/arch/arm/boot/dts/omap2430.dtsi
@@ -88,5 +88,14 @@
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp5";
 		};
+
+		timer1: timer at 49018000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x49018000 0xfff>;
+			interrupts = <37>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer1";
+			ti,timer-alwon;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index f38ea87..1fba998 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -300,5 +300,112 @@
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp5";
 		};
+
+		timer1: timer at 48318000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48318000 0xfff>;
+			interrupts = <37>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer1";
+			ti,timer-alwon;
+		};
+
+		timer2: timer at 49032000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x49032000 0xfff>;
+			interrupts = <38>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer2";
+		};
+
+		timer3: timer at 49034000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x49034000 0xfff>;
+			interrupts = <39>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer3";
+		};
+
+		timer4: timer at 49036000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x49036000 0xfff>;
+			interrupts = <40>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer4";
+		};
+
+		timer5: timer at 49038000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x49038000 0xfff>;
+			interrupts = <41>;
+			ti,hwmods = "timer5";
+			interrupt-parent = <&intc>;
+			ti,timer-dsp;
+		};
+
+		timer6: timer at 4903a000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4903a000 0xfff>;
+			interrupts = <42>;
+			ti,hwmods = "timer6";
+			interrupt-parent = <&intc>;
+			ti,timer-dsp;
+		};
+
+		timer7: timer at 4903c000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4903c000 0xfff>;
+			interrupts = <43>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer7";
+			ti,timer-dsp;
+		};
+
+		timer8: timer at 4903e000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4903e000 0xfff>;
+			interrupts = <44>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer8";
+			ti,timer-pwm;
+			ti,timer-dsp;
+		};
+
+		timer9: timer at 49040000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x49040000 0xfff>;
+			interrupts = <45>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer9";
+			ti,timer-pwm;
+		};
+
+		timer10: timer at 48086000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48086000 0xfff>;
+			interrupts = <46>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer10";
+			ti,timer-pwm;
+		};
+
+		timer11: timer at 48088000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48088000 0xfff>;
+			interrupts = <47>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer11";
+			ti,timer-pwm;
+		};
+
+		timer12: timer at 48304000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48304000 0xfff>;
+			interrupts = <95>;
+			interrupt-parent = <&intc>;
+			ti,hwmods = "timer12";
+			ti,timer-alwon;
+			ti,timer-secure;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 3883f94..f9572bf 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -438,5 +438,102 @@
 			ranges;
 			ti,hwmods = "ocp2scp_usb_phy";
 		};
+
+		timer1: timer at 4a318000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4a318000 0x7f>;
+			interrupts = <0 37 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer1";
+			ti,timer-alwon;
+		};
+
+		timer2: timer at 48032000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48032000 0x7f>;
+			interrupts = <0 38 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer2";
+		};
+
+		timer3: timer at 48034000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48034000 0x7f>;
+			interrupts = <0 39 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer3";
+		};
+
+		timer4: timer at 48036000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48036000 0x7f>;
+			interrupts = <0 40 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer4";
+		};
+
+		timer5: timer at 49038000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x49038000 0x7f>;
+			interrupts = <0 41 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer5";
+			ti,timer-dsp;
+		};
+
+		timer6: timer at 4903a000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4903a000 0x7f>;
+			interrupts = <0 42 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer6";
+			ti,timer-dsp;
+		};
+
+		timer7: timer at 4903c000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4903c000 0x7f>;
+			interrupts = <0 43 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer7";
+			ti,timer-dsp;
+		};
+
+		timer8: timer at 4903e000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4903e000 0x7f>;
+			interrupts = <0 44 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer8";
+			ti,timer-pwm;
+			ti,timer-dsp;
+		};
+
+		timer9: timer at 4803e000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x4803e000 0x7f>;
+			interrupts = <0 45 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer9";
+			ti,timer-pwm;
+		};
+
+		timer10: timer at 48086000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48086000 0x7f>;
+			interrupts = <0 46 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer10";
+			ti,timer-pwm;
+		};
+
+		timer11: timer at 48088000 {
+			compatible = "ti,omap2-timer";
+			reg = <0x48088000 0x7f>;
+			interrupts = <0 47 0x4>;
+			interrupt-parent = <&gic>;
+			ti,hwmods = "timer11";
+			ti,timer-pwm;
+		};
 	};
 };
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V4 0/5] ARM: OMAP2+: Add device-tree support for timers
From: Jon Hunter @ 2012-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds device-tree support for the timers on OMAP2+ devices
including AM33xx. Based upon v3.7-rc1.

Testing:
1. I have booted tested this series on OMAP2420 H4, OMAP3430 Beagle, OMAP4430
   Panda and AM335x Beagle Bone with/without ...
   a). device-tree present
   b). CONFIG_OMAP_32K_TIMER set
   c). kernel boot parameter "clocksource=gp_timer" present
2. I have tested the all the timers (not used by the kernel as sys-timers) on
   OMAP2420 H4, OMAP3430 Beagle and OMAP4430 Panda with/without device-tree with
   this series. The testing includes ...
   a. Configuring, starting a timer and checking the counter value is
      incrementing.
   b. Testing timer overflow interrupt when timer expires.
   c. Using different clock sources to operate the timer with.

V4 changes:
- Update timer binding to make "interrupt-parent" a required property. After
  reviewing the of_irq_find_parent() function it became apparent that it is
  much more efficient, in terms of parsing the DT blob, to have the interrupt
  parent defined in the timer binding than globally.

V3 changes:
- Removed definition "TIMER_PROP_ALWON" per Rob Herring's feedback
- Updated OMAP system timer (clock-events and clock-source) code so that
  HWMOD is NOT used for getting resource (memory and interrupt) information
  when device-tree is present.

V2 changes:
- Remove use of device-tree alias property
- Migrate OMAP timers to request timers by property instead of device ID
- Include OMAP2 support

Jon Hunter (5):
  ARM: dts: OMAP: Add timer nodes
  ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
  ARM: OMAP: Add function to request a timer by capability
  ARM: OMAP3: Add generic machine descriptor for boards with OMAP3 GP
    devices
  ARM: OMAP: Add DT support for timer driver

 .../devicetree/bindings/arm/omap/timer.txt         |   34 ++++
 arch/arm/boot/dts/am33xx.dtsi                      |   61 +++++++
 arch/arm/boot/dts/omap2.dtsi                       |   96 +++++++++++
 arch/arm/boot/dts/omap2420.dtsi                    |    9 +
 arch/arm/boot/dts/omap2430.dtsi                    |    9 +
 arch/arm/boot/dts/omap3.dtsi                       |  107 ++++++++++++
 arch/arm/boot/dts/omap4.dtsi                       |   97 +++++++++++
 arch/arm/mach-omap2/board-generic.c                |   17 ++
 arch/arm/mach-omap2/timer.c                        |  175 ++++++++++++++++----
 arch/arm/plat-omap/dmtimer.c                       |   93 ++++++++++-
 arch/arm/plat-omap/include/plat/dmtimer.h          |    1 +
 11 files changed, 661 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txt

-- 
1.7.9.5

^ permalink raw reply

* [PATCH v2] pinctrl: reserve pins when states are activated
From: Jean-Nicolas GRAUX @ 2012-10-19 14:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350651909-5337-1-git-send-email-linus.walleij@stericsson.com>

Tested-by: Jean Nicolas Graux <jean-nicolas.graux@stericsson.com>

Le 10/19/2012 03:05 PM, Linus WALLEIJ a ?crit :
> From: Linus Walleij<linus.walleij@linaro.org>
>
> This switches the way that pins are reserved for multiplexing:
>
> We used to do this when the map was parsed, at the creation of
> the settings inside the pinctrl handle, in pinmux_map_to_setting().
>
> However this does not work for us, because we want to use the
> same set of pins with different devices at different times: the
> current code assumes that the pin groups in a pinmux state will
> only be used with one single device, albeit different groups can
> be active at different times. For example if a single I2C driver
> block is used to drive two different busses located on two
> pin groups A and B, then the pins for all possible states of a
> function are reserved when fetching the pinctrl handle: the
> I2C bus can choose either set A or set B by a mux state at
> runtime, but all pins in both group A and B (the superset) are
> effectively reserved for that I2C function and mapped to the
> device. Another device can never get in and use the pins in
> group A, even if the device/function is using group B at the
> moment.
>
> Instead: let use reserve the pins when the state is activated
> and drop them when the state is disabled, i.e. when we move to
> another state. This way different devices/functions can use the
> same pins at different times.
>
> We know that this is an odd way of doing things, but we really
> need to switch e.g. an SD-card slot to become a tracing output
> sink at runtime: we plug in a special "tracing card" then mux
> the pins that used to be an SD slot around to the tracing
> unit and push out tracing data there instead of SD-card
> traffic.
>
> As a side effect pinmux_free_setting() is unused and gets
> deleted.
>
> Cc: Patrice Chotard<patrice.chotard@st.com>
> Cc: Jean Nicolas Graux<jean-nicolas.graux@stericsson.com>
> Cc: Loic Pallardy<loic.pallardy@st.com>
> Signed-off-by: Linus Walleij<linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - The code was already accounting for the case where the setting
>    was not active and called pinmux_disable_setting()
>    from the core, so skip this and delete the now empty
>    pinmux_free_setting() altogether.
> ---
>   Documentation/pinctrl.txt |  4 ++-
>   drivers/pinctrl/core.c    |  3 +-
>   drivers/pinctrl/core.h    |  2 ++
>   drivers/pinctrl/pinmux.c  | 70 ++++++++++++++---------------------------------
>   drivers/pinctrl/pinmux.h  |  5 ----
>   5 files changed, 28 insertions(+), 56 deletions(-)
>
> diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt
> index 3b4ee53..a1cd2f9 100644
> --- a/Documentation/pinctrl.txt
> +++ b/Documentation/pinctrl.txt
> @@ -1193,4 +1193,6 @@ foo_switch()
>   	...
>   }
>   
> -The above has to be done from process context.
> +The above has to be done from process context. The reservation of the pins
> +will be done when the state is activated, so in effect one specific pin
> +can be used by different functions at different times on a running system.
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> index 0f1ec9e..bbd930e 100644
> --- a/drivers/pinctrl/core.c
> +++ b/drivers/pinctrl/core.c
> @@ -563,6 +563,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
>   		return -EPROBE_DEFER;
>   	}
>   
> +	setting->dev_name = map->dev_name;
> +
>   	switch (map->type) {
>   	case PIN_MAP_TYPE_MUX_GROUP:
>   		ret = pinmux_map_to_setting(map, setting);
> @@ -689,7 +691,6 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist)
>   			case PIN_MAP_TYPE_MUX_GROUP:
>   				if (state == p->state)
>   					pinmux_disable_setting(setting);
> -				pinmux_free_setting(setting);
>   				break;
>   			case PIN_MAP_TYPE_CONFIGS_PIN:
>   			case PIN_MAP_TYPE_CONFIGS_GROUP:
> diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
> index 1f40ff6..12f5694 100644
> --- a/drivers/pinctrl/core.h
> +++ b/drivers/pinctrl/core.h
> @@ -105,12 +105,14 @@ struct pinctrl_setting_configs {
>    * @type: the type of setting
>    * @pctldev: pin control device handling to be programmed. Not used for
>    *   PIN_MAP_TYPE_DUMMY_STATE.
> + * @dev_name: the name of the device using this state
>    * @data: Data specific to the setting type
>    */
>   struct pinctrl_setting {
>   	struct list_head node;
>   	enum pinctrl_map_type type;
>   	struct pinctrl_dev *pctldev;
> +	const char *dev_name;
>   	union {
>   		struct pinctrl_setting_mux mux;
>   		struct pinctrl_setting_configs configs;
> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> index 9301a7a..0ecdf54 100644
> --- a/drivers/pinctrl/pinmux.c
> +++ b/drivers/pinctrl/pinmux.c
> @@ -314,14 +314,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
>   {
>   	struct pinctrl_dev *pctldev = setting->pctldev;
>   	const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
> -	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
>   	char const * const *groups;
>   	unsigned num_groups;
>   	int ret;
>   	const char *group;
>   	int i;
> -	const unsigned *pins;
> -	unsigned num_pins;
>   
>   	if (!pmxops) {
>   		dev_err(pctldev->dev, "does not support mux function\n");
> @@ -376,55 +373,9 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
>   	}
>   	setting->data.mux.group = ret;
>   
> -	ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins,
> -				      &num_pins);
> -	if (ret) {
> -		dev_err(pctldev->dev,
> -			"could not get pins for device %s group selector %d\n",
> -			pinctrl_dev_get_name(pctldev), setting->data.mux.group);
> -			return -ENODEV;
> -	}
> -
> -	/* Try to allocate all pins in this group, one by one */
> -	for (i = 0; i < num_pins; i++) {
> -		ret = pin_request(pctldev, pins[i], map->dev_name, NULL);
> -		if (ret) {
> -			dev_err(pctldev->dev,
> -				"could not request pin %d on device %s\n",
> -				pins[i], pinctrl_dev_get_name(pctldev));
> -			/* On error release all taken pins */
> -			i--; /* this pin just failed */
> -			for (; i >= 0; i--)
> -				pin_free(pctldev, pins[i], NULL);
> -			return -ENODEV;
> -		}
> -	}
> -
>   	return 0;
>   }
>   
> -void pinmux_free_setting(struct pinctrl_setting const *setting)
> -{
> -	struct pinctrl_dev *pctldev = setting->pctldev;
> -	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
> -	const unsigned *pins;
> -	unsigned num_pins;
> -	int ret;
> -	int i;
> -
> -	ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
> -				      &pins, &num_pins);
> -	if (ret) {
> -		dev_err(pctldev->dev,
> -			"could not get pins for device %s group selector %d\n",
> -			pinctrl_dev_get_name(pctldev), setting->data.mux.group);
> -		return;
> -	}
> -
> -	for (i = 0; i < num_pins; i++)
> -		pin_free(pctldev, pins[i], NULL);
> -}
> -
>   int pinmux_enable_setting(struct pinctrl_setting const *setting)
>   {
>   	struct pinctrl_dev *pctldev = setting->pctldev;
> @@ -446,6 +397,22 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting)
>   		num_pins = 0;
>   	}
>   
> +	/* Try to allocate all pins in this group, one by one */
> +	for (i = 0; i < num_pins; i++) {
> +		ret = pin_request(pctldev, pins[i], setting->dev_name, NULL);
> +		if (ret) {
> +			dev_err(pctldev->dev,
> +				"could not request pin %d on device %s\n",
> +				pins[i], pinctrl_dev_get_name(pctldev));
> +			/* On error release all taken pins */
> +			i--; /* this pin just failed */
> +			for (; i >= 0; i--)
> +				pin_free(pctldev, pins[i], NULL);
> +			return -ENODEV;
> +		}
> +	}
> +
> +	/* Now that we have acquired the pins, encode the mux setting */
>   	for (i = 0; i < num_pins; i++) {
>   		desc = pin_desc_get(pctldev, pins[i]);
>   		if (desc == NULL) {
> @@ -482,6 +449,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
>   		num_pins = 0;
>   	}
>   
> +	/* Flag the descs that no setting is active */
>   	for (i = 0; i < num_pins; i++) {
>   		desc = pin_desc_get(pctldev, pins[i]);
>   		if (desc == NULL) {
> @@ -493,6 +461,10 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
>   		desc->mux_setting = NULL;
>   	}
>   
> +	/* And release the pins */
> +	for (i = 0; i < num_pins; i++)
> +		pin_free(pctldev, pins[i], NULL);
> +
>   	if (ops->disable)
>   		ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
>   }
> diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
> index d1a98b1..3c2aafa 100644
> --- a/drivers/pinctrl/pinmux.h
> +++ b/drivers/pinctrl/pinmux.h
> @@ -27,7 +27,6 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
>   
>   int pinmux_map_to_setting(struct pinctrl_map const *map,
>   			  struct pinctrl_setting *setting);
> -void pinmux_free_setting(struct pinctrl_setting const *setting);
>   int pinmux_enable_setting(struct pinctrl_setting const *setting);
>   void pinmux_disable_setting(struct pinctrl_setting const *setting);
>   
> @@ -69,10 +68,6 @@ static inline int pinmux_map_to_setting(struct pinctrl_map const *map,
>   	return 0;
>   }
>   
> -static inline void pinmux_free_setting(struct pinctrl_setting const *setting)
> -{
> -}
> -
>   static inline int pinmux_enable_setting(struct pinctrl_setting const *setting)
>   {
>   	return 0;

^ permalink raw reply

* [PATCH v2 1/2] ARM: multi_v7_defconfig: Add ARCH_MXC
From: Rob Herring @ 2012-10-19 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350605046-21358-1-git-send-email-festevam@gmail.com>

Adding Arnd and Olof.

On 10/18/2012 07:04 PM, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
> 
> Let ARCH_MXC be covered by multi_v7_defconfig.
> 
> Allow booting mx6 via NFS.

Now we can start debating what should or shouldn't be in shared
defconfigs. :)

My intent with this defconfig was to only enable required options and
all drivers for platforms and leave features to their defaults. I don't
feel that strongly about it. We should have some general guideline here
so it's not a free for all. You can still have a defconfig for your
platform as well.

Rob

> 
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> Changes since v1:
> - Provide a more complete config that allows booting mx6 via NFS
> 
>  arch/arm/configs/multi_v7_defconfig |   13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 159f75f..df1e563 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -5,6 +5,8 @@ CONFIG_ARCH_MVEBU=y
>  CONFIG_MACH_ARMADA_370=y
>  CONFIG_MACH_ARMADA_XP=y
>  CONFIG_ARCH_HIGHBANK=y
> +CONFIG_ARCH_MXC=y
> +CONFIG_SOC_IMX6Q=y
>  CONFIG_ARCH_SOCFPGA=y
>  # CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
>  CONFIG_ARM_ERRATA_754322=y
> @@ -17,18 +19,29 @@ CONFIG_ARM_APPENDED_DTB=y
>  CONFIG_VFP=y
>  CONFIG_NEON=y
>  CONFIG_NET=y
> +CONFIG_PACKET=y
> +CONFIG_UNIX=y
> +CONFIG_INET=y
> +CONFIG_IP_PNP=y
> +CONFIG_IP_PNP_DHCP=y
>  CONFIG_ATA=y
>  CONFIG_SATA_HIGHBANK=y
>  CONFIG_NETDEVICES=y
>  CONFIG_NET_CALXEDA_XGMAC=y
>  CONFIG_SMSC911X=y
>  CONFIG_STMMAC_ETH=y
> +CONFIG_NFS_FS=y
> +CONFIG_NFS_V3_ACL=y
> +CONFIG_NFS_V4=y
> +CONFIG_ROOT_NFS=y
>  CONFIG_SERIO_AMBAKMI=y
>  CONFIG_SERIAL_8250=y
>  CONFIG_SERIAL_8250_CONSOLE=y
>  CONFIG_SERIAL_8250_DW=y
>  CONFIG_SERIAL_AMBA_PL011=y
>  CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
> +CONFIG_SERIAL_IMX=y
> +CONFIG_SERIAL_IMX_CONSOLE=y
>  CONFIG_SERIAL_OF_PLATFORM=y
>  CONFIG_IPMI_HANDLER=y
>  CONFIG_IPMI_SI=y
> 

^ permalink raw reply

* RT throttling and suspend/resume (was Re: [PATCH] i2c: omap: revert "i2c: omap: switch to threaded IRQ support")
From: Peter Zijlstra @ 2012-10-19 14:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121018055136.GF11137@arwen.pp.htv.fi>

On Thu, 2012-10-18 at 08:51 +0300, Felipe Balbi wrote:
> > So the primary question remains: is RT runtime supposed to include the
> > time spent suspended?  I suspect not. 
> 
> you might be right there, though we need Thomas or Peter to answer :-s 

re, sorry both tglx and I have been traveling, he still is, I'm trying
to play catch-up :-)

Anyway, yeah I'm somewhat surprised the clock is 'running' when the
machine isn't. From what I could gather, this is !x86 hardware, right?

x86 explicitly makes sure our clocks are 'stopped' during suspend, see
commit cd7240c0b900eb6d690ccee088a6c9b46dae815a.

Can you do something similar for ARM? A quick look at
arch/arm/kernel/sched_clock.c shows there's already suspend/resume
hooks, do they do the wrong thing?

^ permalink raw reply

* [PATCH v2] arm/dts: AM33XX: Add SPI device tree data
From: Matt Porter @ 2012-10-19 13:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50814A5A.8070206@ti.com>

On Fri, Oct 19, 2012 at 02:40:58PM +0200, Benoit Cousson wrote:
> Hi Matt,
> 
> On 10/19/2012 01:30 PM, Matt Porter wrote:
> > On Fri, Oct 19, 2012 at 10:24:15AM +0200, Benoit Cousson wrote:
> >> Hi Avinash,
> >>
> >> This look good to me except the: status = "disabled".
> >>
> >> The "disabled" should be reserved for variant that does not contain the IP.
> >> Is it the case here?
> > 
> > http://comments.gmane.org/gmane.linux.drivers.devicetree/18968 is what
> > I've been going by with the DTS support in the EDMA dmaengine series. It
> > does make the most sense to only enable what you need in the
> > <board>.dts.
> 
> Thanks, I missed that thread. That being said, there is no real rational
> :-)
> It seems to be a preference more than anything else.

Ok, agreed. Here's an example to attempt to illustrate why the one true
preference is to default to disabled. :) Let's say I'm a system developer
with a custom board in the default enabled model. My board makes use of,
say, mmc1 and uart1 on am33xx (oh yes, we must fix the numbering that
doesn't match the TRM) only. In that case, I develop a board.dts
with:

	uart2: serial at foo {
		status = "disabled";
	};
	.
	.
	.
	uart6: serial at bar {
		status = "disabled";
	};

	&mmc1 {
        	vmmc-supply = <&ldo3_reg>;
	};

	&mmc2 {
		status = "disabled";
	};

	&mmc3 {
		status = "disabled";
	};

In the "positive logic" case I would have a board.dts with:

	uart1: serial at foo {
		status = "okay";
	};

	&mmc1 {
		status = "okay";
        	vmmc-supply = <&ldo3_reg>;
	};
	
In the first case, the fact that there's a board specific property
present for mmc1 can almost get lost in the sea of disabled peripherals.
Extend that out to all the other devices that would be disabled in a
full board.dts and it becomes clear (at least to me) as to how ugly the
board.dts will become. My concern is that this hardware description will
quickly become unreadable to a human.

You might say it's unnecessary to disable everything, but in a
production system the developer is not going to want all these
unused devices to be instantiated. They may have a common family of
boards with a common kernel image, all with a separate dtb so they
can precisely control which items are enabled such that unused drivers
are not loaded.

So then look at the second case. At least for me, I can look at that in
the board.dts and I know that this board uses uart1 and mmc1...and
nothing else. That's a clear and concise hardware description at a
board level, but I understand that can be just considered a
preference.

> I'm curious now, why powerpc was not really using that approach?

Good question.

> I'd rather explicitly disable an IP than assuming than it is disabled by
> default and then enabling it in the board file. But again it is just a
> different view point, since at the end it will have the same effect.

Well, there's functionality then there's production usability. I'm
pointing out that there are many cases where the readability (and
therefore) usability for someone creating a new board is reduced when
devices default to enabled.

> If we really want the disabled state to be the default state, why is it
> not disabled in the DT fmwk by default?

I think it's simply answered by the fact that powerpc always took the
negative logic approach.

-Matt

> >> On 09/18/2012 07:30 AM, Philip, Avinash wrote:
> >>> Add McSPI data node to AM33XX device tree file. The McSPI module (and so
> >>> as the driver) is reused from OMAP4.
> >>>
> >>> Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
> >>> Tested-by: Matt Porter <mporter@ti.com>
> >>> ---
> >>> Changes since v1:
> >>>         - Corrected reg offset in reg DT entry.
> >>>
> >>> :100644 100644 ff3badb... 065fd54... M	arch/arm/boot/dts/am33xx.dtsi
> >>>  arch/arm/boot/dts/am33xx.dtsi |   25 +++++++++++++++++++++++++
> >>>  1 files changed, 25 insertions(+), 0 deletions(-)
> >>>
> >>> diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
> >>> index ff3badb..065fd54 100644
> >>> --- a/arch/arm/boot/dts/am33xx.dtsi
> >>> +++ b/arch/arm/boot/dts/am33xx.dtsi
> >>> @@ -219,5 +219,30 @@
> >>>  			interrupt-parent = <&intc>;
> >>>  			interrupts = <91>;
> >>>  		};
> >>> +
> >>> +		spi0: spi at 48030000 {
> >>> +			compatible = "ti,omap4-mcspi";
> >>> +			#address-cells = <1>;
> >>> +			#size-cells = <0>;
> >>> +			reg = <0x48030000 0x400>;
> >>> +			interrupt-parent = <&intc>;
> >>> +			interrupt = <65>;
> >>> +			ti,spi-num-cs = <2>;
> >>> +			ti,hwmods = "spi0";
> >>> +			status = "disabled";
> >>> +
> >>> +		};
> >>> +
> >>> +		spi1: spi at 481a0000 {
> >>> +			compatible = "ti,omap4-mcspi";
> >>> +			#address-cells = <1>;
> >>> +			#size-cells = <0>;
> >>> +			reg = <0x481a0000 0x400>;
> >>> +			interrupt-parent = <&intc>;
> >>> +			interrupt = <125>;
> >>> +			ti,spi-num-cs = <2>;
> >>> +			ti,hwmods = "spi1";
> >>> +			status = "disabled";
> >>> +		};
> >>>  	};
> >>>  };
> >>>
> >>
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> >> the body of a message to majordomo at vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >> Please read the FAQ at  http://www.tux.org/lkml/
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 2/2] ASoC: Ux500: Fixup compile error
From: Ulf Hansson @ 2012-10-19 13:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350653427-28611-1-git-send-email-ulf.hansson@stericsson.com>

From: Ulf Hansson <ulf.hansson@linaro.org>

The below commit introduced a compile error for a missing include file.
ASoC: ux500_msp_i2s: better use devm functions and fix error return code

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 sound/soc/ux500/ux500_msp_i2s.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index e6ff328..ba15351 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -18,6 +18,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <linux/of.h>
 
 #include <mach/hardware.h>
-- 
1.7.10

^ permalink raw reply related

* [PATCH 1/2] ASoC: Ux500: Fixup complile errors due to merge
From: Ulf Hansson @ 2012-10-19 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ulf Hansson <ulf.hansson@linaro.org>

Likely during merge of the below commits ended up breaking compilation:
ASoC: Ux500: Enable ux500 MSP driver for Device Tree
ASoC: ux500_msp_i2s: better use devm functions and fix error return code

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 sound/soc/ux500/ux500_msp_i2s.c |   18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index b7c996e..e6ff328 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -692,19 +692,15 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
 	if (!msp)
 		return -ENOMEM;
 
-	if (np) {
-		if (!platform_data) {
-			platform_data = devm_kzalloc(&pdev->dev,
-				sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
-			if (!platform_data)
-				ret = -ENOMEM;
-		}
-	} else
+	if (np && !platform_data) {
+		platform_data = devm_kzalloc(&pdev->dev,
+			sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
 		if (!platform_data)
-			ret = -EINVAL;
+			return -ENOMEM;
+	}
 
-	if (ret)
-		goto err_res;
+	if (!platform_data)
+		return -EINVAL;
 
 	dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
 		pdev->name, platform_data->id);
-- 
1.7.10

^ permalink raw reply related

* [RFC] media: mx3: Add support for missing video formats
From: Laurent Pinchart @ 2012-10-19 13:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1556117578.7042626.1350477684664.JavaMail.root@advansee.com>

Hi Beno?t,

On Wednesday 17 October 2012 14:41:24 Beno?t Th?baudeau wrote:
> Hi all,
> 
> This is an RFC for a patch completing full video capture support on i.MX3x.
> 
> It adds missing video formats and automatic format associations according to
> the underlying sensor capabilities.
> 
> It also fixes a spurious IPU interrupt issue that I have encountered on
> i.MX31 with earlier kernel versions. This might already have been fixed by
> some of the changes that occurred in the IPU driver since then, but I still
> have to test if my fix is still useful or not. Anyway, this should of
> course be split away to a separate patch.
> 
> This patch has been successfully tested with i.MX35 and MT9M131, as well as
> some not yet mainline OmniVision sensor drivers, using all
> sensor-and-SoC-supported formats.
> 
> This patch still has to be rebased against the latest kernel and refactored
> in the following way:
>  1. Media formats.
>  2. IPU formats.
>  3. IPU spurious interrupt fix (if still required).
>  4. mx3_camera formats.
> 
> Comments are welcome, especially regarding possible conflicts with other IPU
> users.
> 
> Best regards,
> Beno?t
> 
> Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
> Cc: <linux-media@vger.kernel.org>
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: <linux-arm-kernel@lists.infradead.org>
> Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
> ---
>  .../arch/arm/plat-mxc/include/mach/ipu.h           |   16 +-
>  .../drivers/dma/ipu/ipu_idmac.c                    |  241 ++++++++++++++---
>  .../drivers/media/video/mx3_camera.c               |  264 +++++++++++------
>  .../drivers/media/video/soc_mediabus.c             |  276 ++++++++++++-----
>  .../include/linux/v4l2-mediabus.h                  |   11 +-
>  .../include/media/soc_mediabus.h                   |   30 ++-

Could you please split this patch in 3 patches ? The first one should add the 
missing formats in include/linux/v4l2-mediabus.h, the second one in 
drivers/media/video/soc_mediabus.c and include/media/soc_mediabus.h, and the 
third one would include the mx3 changes. That will make review easier.

Please also update Documentation/DocBook/media/v4l/subdev-formats.xml with a 
description of the new media bus formats.

>  6 files changed, 626 insertions(+), 212 deletions(-)

[snip]

> diff --git linux-3.4.5.orig/include/linux/v4l2-mediabus.h
> linux-3.4.5/include/linux/v4l2-mediabus.h index 5ea7f75..57a9fc9 100644
> --- linux-3.4.5.orig/include/linux/v4l2-mediabus.h
> +++ linux-3.4.5/include/linux/v4l2-mediabus.h
> @@ -37,7 +37,8 @@
>  enum v4l2_mbus_pixelcode {
>  	V4L2_MBUS_FMT_FIXED = 0x0001,
> 
> -	/* RGB - next is 0x1009 */
> +	/* RGB - next is 0x100c */
> +	V4L2_MBUS_FMT_RGB332_1X8 = 0x1009,
>  	V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001,
>  	V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002,
>  	V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003,
> @@ -46,8 +47,10 @@ enum v4l2_mbus_pixelcode {
>  	V4L2_MBUS_FMT_BGR565_2X8_LE = 0x1006,
>  	V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007,
>  	V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008,
> +	V4L2_MBUS_FMT_RGB24_3X8_BE = 0x100a,
> +	V4L2_MBUS_FMT_RGB24_3X8_LE = 0x100b,

I think I would call those V4L2_MBUS_FMT_RGB24_3X8 and V4L2_MBUS_FMT_BGR24_3X8 
instead.

> -	/* YUV (including grey) - next is 0x2014 */
> +	/* YUV (including grey) - next is 0x2015 */
>  	V4L2_MBUS_FMT_Y8_1X8 = 0x2001,
>  	V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002,
>  	V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003,
> @@ -65,10 +68,11 @@ enum v4l2_mbus_pixelcode {
>  	V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010,
>  	V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011,
>  	V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012,
> +	V4L2_MBUS_FMT_Y16_1X16 = 0x2014,
>  	V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d,
>  	V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e,
> 
> -	/* Bayer - next is 0x3015 */
> +	/* Bayer - next is 0x3016 */
>  	V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001,
>  	V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013,
>  	V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002,
> @@ -89,6 +93,7 @@ enum v4l2_mbus_pixelcode {
>  	V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010,
>  	V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011,
>  	V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012,
> +	V4L2_MBUS_FMT_SBGGR16_1X16 = 0x3015,

What about the other 3 Bayer patterns ?

>  	/* JPEG compressed formats - next is 0x4002 */
>  	V4L2_MBUS_FMT_JPEG_1X8 = 0x4001,

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH v2] pinctrl: reserve pins when states are activated
From: Linus Walleij @ 2012-10-19 13:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Linus Walleij <linus.walleij@linaro.org>

This switches the way that pins are reserved for multiplexing:

We used to do this when the map was parsed, at the creation of
the settings inside the pinctrl handle, in pinmux_map_to_setting().

However this does not work for us, because we want to use the
same set of pins with different devices at different times: the
current code assumes that the pin groups in a pinmux state will
only be used with one single device, albeit different groups can
be active at different times. For example if a single I2C driver
block is used to drive two different busses located on two
pin groups A and B, then the pins for all possible states of a
function are reserved when fetching the pinctrl handle: the
I2C bus can choose either set A or set B by a mux state at
runtime, but all pins in both group A and B (the superset) are
effectively reserved for that I2C function and mapped to the
device. Another device can never get in and use the pins in
group A, even if the device/function is using group B at the
moment.

Instead: let use reserve the pins when the state is activated
and drop them when the state is disabled, i.e. when we move to
another state. This way different devices/functions can use the
same pins at different times.

We know that this is an odd way of doing things, but we really
need to switch e.g. an SD-card slot to become a tracing output
sink at runtime: we plug in a special "tracing card" then mux
the pins that used to be an SD slot around to the tracing
unit and push out tracing data there instead of SD-card
traffic.

As a side effect pinmux_free_setting() is unused and gets
deleted.

Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Jean Nicolas Graux <jean-nicolas.graux@stericsson.com>
Cc: Loic Pallardy <loic.pallardy@st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- The code was already accounting for the case where the setting
  was not active and called pinmux_disable_setting()
  from the core, so skip this and delete the now empty
  pinmux_free_setting() altogether.
---
 Documentation/pinctrl.txt |  4 ++-
 drivers/pinctrl/core.c    |  3 +-
 drivers/pinctrl/core.h    |  2 ++
 drivers/pinctrl/pinmux.c  | 70 ++++++++++++++---------------------------------
 drivers/pinctrl/pinmux.h  |  5 ----
 5 files changed, 28 insertions(+), 56 deletions(-)

diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt
index 3b4ee53..a1cd2f9 100644
--- a/Documentation/pinctrl.txt
+++ b/Documentation/pinctrl.txt
@@ -1193,4 +1193,6 @@ foo_switch()
 	...
 }
 
-The above has to be done from process context.
+The above has to be done from process context. The reservation of the pins
+will be done when the state is activated, so in effect one specific pin
+can be used by different functions at different times on a running system.
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 0f1ec9e..bbd930e 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -563,6 +563,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
 		return -EPROBE_DEFER;
 	}
 
+	setting->dev_name = map->dev_name;
+
 	switch (map->type) {
 	case PIN_MAP_TYPE_MUX_GROUP:
 		ret = pinmux_map_to_setting(map, setting);
@@ -689,7 +691,6 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist)
 			case PIN_MAP_TYPE_MUX_GROUP:
 				if (state == p->state)
 					pinmux_disable_setting(setting);
-				pinmux_free_setting(setting);
 				break;
 			case PIN_MAP_TYPE_CONFIGS_PIN:
 			case PIN_MAP_TYPE_CONFIGS_GROUP:
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 1f40ff6..12f5694 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -105,12 +105,14 @@ struct pinctrl_setting_configs {
  * @type: the type of setting
  * @pctldev: pin control device handling to be programmed. Not used for
  *   PIN_MAP_TYPE_DUMMY_STATE.
+ * @dev_name: the name of the device using this state
  * @data: Data specific to the setting type
  */
 struct pinctrl_setting {
 	struct list_head node;
 	enum pinctrl_map_type type;
 	struct pinctrl_dev *pctldev;
+	const char *dev_name;
 	union {
 		struct pinctrl_setting_mux mux;
 		struct pinctrl_setting_configs configs;
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 9301a7a..0ecdf54 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -314,14 +314,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
 {
 	struct pinctrl_dev *pctldev = setting->pctldev;
 	const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
-	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
 	char const * const *groups;
 	unsigned num_groups;
 	int ret;
 	const char *group;
 	int i;
-	const unsigned *pins;
-	unsigned num_pins;
 
 	if (!pmxops) {
 		dev_err(pctldev->dev, "does not support mux function\n");
@@ -376,55 +373,9 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
 	}
 	setting->data.mux.group = ret;
 
-	ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins,
-				      &num_pins);
-	if (ret) {
-		dev_err(pctldev->dev,
-			"could not get pins for device %s group selector %d\n",
-			pinctrl_dev_get_name(pctldev), setting->data.mux.group);
-			return -ENODEV;
-	}
-
-	/* Try to allocate all pins in this group, one by one */
-	for (i = 0; i < num_pins; i++) {
-		ret = pin_request(pctldev, pins[i], map->dev_name, NULL);
-		if (ret) {
-			dev_err(pctldev->dev,
-				"could not request pin %d on device %s\n",
-				pins[i], pinctrl_dev_get_name(pctldev));
-			/* On error release all taken pins */
-			i--; /* this pin just failed */
-			for (; i >= 0; i--)
-				pin_free(pctldev, pins[i], NULL);
-			return -ENODEV;
-		}
-	}
-
 	return 0;
 }
 
-void pinmux_free_setting(struct pinctrl_setting const *setting)
-{
-	struct pinctrl_dev *pctldev = setting->pctldev;
-	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
-	const unsigned *pins;
-	unsigned num_pins;
-	int ret;
-	int i;
-
-	ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
-				      &pins, &num_pins);
-	if (ret) {
-		dev_err(pctldev->dev,
-			"could not get pins for device %s group selector %d\n",
-			pinctrl_dev_get_name(pctldev), setting->data.mux.group);
-		return;
-	}
-
-	for (i = 0; i < num_pins; i++)
-		pin_free(pctldev, pins[i], NULL);
-}
-
 int pinmux_enable_setting(struct pinctrl_setting const *setting)
 {
 	struct pinctrl_dev *pctldev = setting->pctldev;
@@ -446,6 +397,22 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting)
 		num_pins = 0;
 	}
 
+	/* Try to allocate all pins in this group, one by one */
+	for (i = 0; i < num_pins; i++) {
+		ret = pin_request(pctldev, pins[i], setting->dev_name, NULL);
+		if (ret) {
+			dev_err(pctldev->dev,
+				"could not request pin %d on device %s\n",
+				pins[i], pinctrl_dev_get_name(pctldev));
+			/* On error release all taken pins */
+			i--; /* this pin just failed */
+			for (; i >= 0; i--)
+				pin_free(pctldev, pins[i], NULL);
+			return -ENODEV;
+		}
+	}
+
+	/* Now that we have acquired the pins, encode the mux setting */
 	for (i = 0; i < num_pins; i++) {
 		desc = pin_desc_get(pctldev, pins[i]);
 		if (desc == NULL) {
@@ -482,6 +449,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
 		num_pins = 0;
 	}
 
+	/* Flag the descs that no setting is active */
 	for (i = 0; i < num_pins; i++) {
 		desc = pin_desc_get(pctldev, pins[i]);
 		if (desc == NULL) {
@@ -493,6 +461,10 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
 		desc->mux_setting = NULL;
 	}
 
+	/* And release the pins */
+	for (i = 0; i < num_pins; i++)
+		pin_free(pctldev, pins[i], NULL);
+
 	if (ops->disable)
 		ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
 }
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
index d1a98b1..3c2aafa 100644
--- a/drivers/pinctrl/pinmux.h
+++ b/drivers/pinctrl/pinmux.h
@@ -27,7 +27,6 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
 
 int pinmux_map_to_setting(struct pinctrl_map const *map,
 			  struct pinctrl_setting *setting);
-void pinmux_free_setting(struct pinctrl_setting const *setting);
 int pinmux_enable_setting(struct pinctrl_setting const *setting);
 void pinmux_disable_setting(struct pinctrl_setting const *setting);
 
@@ -69,10 +68,6 @@ static inline int pinmux_map_to_setting(struct pinctrl_map const *map,
 	return 0;
 }
 
-static inline void pinmux_free_setting(struct pinctrl_setting const *setting)
-{
-}
-
 static inline int pinmux_enable_setting(struct pinctrl_setting const *setting)
 {
 	return 0;
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH] pinctrl: reserve pins when states are activated
From: Linus Walleij @ 2012-10-19 12:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508091C4.9080008@wwwdotorg.org>

On Fri, Oct 19, 2012 at 1:33 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 10/18/2012 04:01 AM, Linus Walleij wrote:
>> This switches the way that pins are reserved for multiplexing:
>
> The conceptual change makes perfect sense to me.

Thanks...

>> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
>
>>  void pinmux_free_setting(struct pinctrl_setting const *setting)
> ...
>> +     /*
>> +      * If a setting is active, disable it so that all pins are released
>> +      */
>> +     pinmux_disable_setting(setting);
>
> "*If* a setting is active ..." implies there should be a C if statement
> here to check if the setting is actually active before trying to disable it?

Spot on.

Actually in core.c we're already checking this:

	case PIN_MAP_TYPE_MUX_GROUP:
		if (state == p->state)
			pinmux_disable_setting(setting);
		pinmux_free_setting(setting);
		break;

So this is just buggy driving the refcount down to negative.
(I think Jean-Nicolas noticed this phenomenon...)

I should just delete pinmux_free_setting().

Yours,
Linus Walleij

Yours,
Linus Walleij

^ permalink raw reply

* [RFC] dmaengine: omap-dma: Allow DMA controller to prefetch data
From: Péter Ujfalusi @ 2012-10-19 12:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121018233335.GC28061@n2100.arm.linux.org.uk>

Hi,

On 10/19/2012 01:33 AM, Russell King - ARM Linux wrote:
> I would suggest getting some feedback from the ASoC people first, before
> trying to invent new APIs to work around this stuff.  If they can live
> with having prefetch enabled on OMAP then there isn't an issue here.  If
> not, we need a solution to this.
> 
> I do not believe that precisely stopping and starting playback across a
> suspend/resume event is really necessary (it's desirable but the world
> doesn't collapse if you miss a few samples.)  It could be more of an
> issue for pause/resume though, but as I say, that's for ASoC people to
> comment on.

There is another issue with the prefetch in audio:
we tend to like to know the position of the DMA and also to know how much data
we have stored in buffers, FIFOs. This information is used by userspace to do
echo cancellation and also used by PA for example to do runtime mixing
directly in the audio buffer. We have means to extract this information from
McBSP for example (and from tlv320dac33 codec) but AFAIK this information can
not be retrieved from sDMA.
We could assume that the sDMA FIFO is kept full and report that as a 'delay'
or do not account this information.

For now I think the cyclic mode should not set the prefetch. If I recall right
the cyclic mode is only used by audio at the moment.

> I'm merely pointing out here that we need their feedback here before
> deciding if there's anything further that needs to happen.

Thanks Russell, I'll take a look at the implication of the prefetch for audio.

-- 
P?ter

^ permalink raw reply

* [PATCH v2] arm/dts: AM33XX: Add SPI device tree data
From: Benoit Cousson @ 2012-10-19 12:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121019113016.GE25164@beef>

Hi Matt,

On 10/19/2012 01:30 PM, Matt Porter wrote:
> On Fri, Oct 19, 2012 at 10:24:15AM +0200, Benoit Cousson wrote:
>> Hi Avinash,
>>
>> This look good to me except the: status = "disabled".
>>
>> The "disabled" should be reserved for variant that does not contain the IP.
>> Is it the case here?
> 
> http://comments.gmane.org/gmane.linux.drivers.devicetree/18968 is what
> I've been going by with the DTS support in the EDMA dmaengine series. It
> does make the most sense to only enable what you need in the
> <board>.dts.

Thanks, I missed that thread. That being said, there is no real rational
:-)
It seems to be a preference more than anything else.
I'm curious now, why powerpc was not really using that approach?

I'd rather explicitly disable an IP than assuming than it is disabled by
default and then enabling it in the board file. But again it is just a
different view point, since at the end it will have the same effect.

If we really want the disabled state to be the default state, why is it
not disabled in the DT fmwk by default?

Regards,
Benoit

> 
> -Matt
> 
>> On 09/18/2012 07:30 AM, Philip, Avinash wrote:
>>> Add McSPI data node to AM33XX device tree file. The McSPI module (and so
>>> as the driver) is reused from OMAP4.
>>>
>>> Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
>>> Tested-by: Matt Porter <mporter@ti.com>
>>> ---
>>> Changes since v1:
>>>         - Corrected reg offset in reg DT entry.
>>>
>>> :100644 100644 ff3badb... 065fd54... M	arch/arm/boot/dts/am33xx.dtsi
>>>  arch/arm/boot/dts/am33xx.dtsi |   25 +++++++++++++++++++++++++
>>>  1 files changed, 25 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
>>> index ff3badb..065fd54 100644
>>> --- a/arch/arm/boot/dts/am33xx.dtsi
>>> +++ b/arch/arm/boot/dts/am33xx.dtsi
>>> @@ -219,5 +219,30 @@
>>>  			interrupt-parent = <&intc>;
>>>  			interrupts = <91>;
>>>  		};
>>> +
>>> +		spi0: spi at 48030000 {
>>> +			compatible = "ti,omap4-mcspi";
>>> +			#address-cells = <1>;
>>> +			#size-cells = <0>;
>>> +			reg = <0x48030000 0x400>;
>>> +			interrupt-parent = <&intc>;
>>> +			interrupt = <65>;
>>> +			ti,spi-num-cs = <2>;
>>> +			ti,hwmods = "spi0";
>>> +			status = "disabled";
>>> +
>>> +		};
>>> +
>>> +		spi1: spi at 481a0000 {
>>> +			compatible = "ti,omap4-mcspi";
>>> +			#address-cells = <1>;
>>> +			#size-cells = <0>;
>>> +			reg = <0x481a0000 0x400>;
>>> +			interrupt-parent = <&intc>;
>>> +			interrupt = <125>;
>>> +			ti,spi-num-cs = <2>;
>>> +			ti,hwmods = "spi1";
>>> +			status = "disabled";
>>> +		};
>>>  	};
>>>  };
>>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* [PATCH] ARM: ux500: Introduce cpu_is_u8580()
From: Linus Walleij @ 2012-10-19 12:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Maxime Coquelin <maxime.coquelin@stericsson.com>

Detect the subrevision v1 of U8540 and U8580.

DB8580 is the FDSOI variant of DB8540. Some differences
with DB8540 related to clocks will need to be checked with
a cpu_is_u8580() function.

Signed-off-by: Maxime Coquelin <maxime.coquelin@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ux500/include/mach/id.h | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h
index 9c42642..bcc58a8 100644
--- a/arch/arm/mach-ux500/include/mach/id.h
+++ b/arch/arm/mach-ux500/include/mach/id.h
@@ -61,9 +61,14 @@ static inline bool __attribute_const__ cpu_is_u8540(void)
 	return dbx500_partnumber() == 0x8540;
 }
 
+static inline bool __attribute_const__ cpu_is_u8580(void)
+{
+	return dbx500_partnumber() == 0x8580;
+}
+
 static inline bool cpu_is_ux540_family(void)
 {
-	return cpu_is_u9540() || cpu_is_u8540();
+	return cpu_is_u9540() || cpu_is_u8540() || cpu_is_u8580();
 }
 
 /*
@@ -115,6 +120,20 @@ static inline bool cpu_is_u8500v20_or_later(void)
 	return (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11());
 }
 
+/*
+ * 8540 revisions
+ */
+
+static inline bool __attribute_const__ cpu_is_u8540v10(void)
+{
+	return cpu_is_u8540() && dbx500_revision() == 0xA0;
+}
+
+static inline bool __attribute_const__ cpu_is_u8580v10(void)
+{
+	return cpu_is_u8580() && dbx500_revision() == 0xA0;
+}
+
 static inline bool ux500_is_svp(void)
 {
 	return false;
-- 
1.7.11.3

^ permalink raw reply related

* [PATCH v2 RESEND] ARM: pxa: hx4700: Fix backlight PWM device number
From: Paul Parsons @ 2012-10-19 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

Recent changes to PXA PWM support changed the PXA27X PWM device
numbering scheme.

The linux-3.5 PXA PWM driver followed the hardware numbering scheme for
the 4 PWMs, while the linux-3.6-rc1 PXA PWM driver has adopted a linear
numbering scheme:

Address		Hardware	3.5 pwm_id	3.6-rc1 pwm_id
0x40b00000	PWM0		0		0
0x40b00010	PWM2		2		1
0x40c00000	PWM1		1		2
0x40c00010	PWM3		3		3

The hx4700 backlight uses PWM1 at 0x40c00000. Consequently the pwm_id
must be changed from 1 to 2.

This patch fixes the backlight PWM device number and at the same time
moves from the legacy PWM API (pwm_id) to the new PWM API (pwm_lookup).

Signed-off-by: Paul Parsons <lost.distance@yahoo.com>
Cc: Thierry Reding <thierry.reding@avionic-design.de>
---

V2: Switch from legacy PWM API to new PWM API.

 arch/arm/mach-pxa/hx4700.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index e631198..d66f9f9 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -28,6 +28,7 @@
 #include <linux/mfd/asic3.h>
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/gpio-regulator.h>
@@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = {
  */
 
 static struct platform_pwm_backlight_data backlight_data = {
-	.pwm_id         = 1,
+	.pwm_id         = -1,	/* Superseded by pwm_lookup */
 	.max_brightness = 200,
 	.dft_brightness = 100,
 	.pwm_period_ns  = 30923,
@@ -571,6 +572,10 @@ static struct platform_device backlight = {
 	},
 };
 
+static struct pwm_lookup hx4700_pwm_lookup[] = {
+	PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL),
+};
+
 /*
  * USB "Transceiver"
  */
@@ -872,6 +877,7 @@ static void __init hx4700_init(void)
 	pxa_set_stuart_info(NULL);
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
 
 	pxa_set_ficp_info(&ficp_info);
 	pxa27x_set_i2c_power_info(NULL);
-- 
1.7.8.6

^ permalink raw reply related

* [RFC PATCH v3 00/16] DMA Engine support for AM33XX
From: Bedia, Vaibhav @ 2012-10-19 12:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121019111558.GD25164@beef>

On Fri, Oct 19, 2012 at 16:45:58, Porter, Matt wrote:
> On Fri, Oct 19, 2012 at 10:26:20AM +0000, Bedia, Vaibhav wrote:
[...]
> > 
> > I didn't see all the patches that you posted on edma-dmaengine-v3
> > but I do seem them on edma-dmaengine-am33xx-v3 branch.
> 
> I see I referenced the wrong branch in the cover letter. Thanks for
> testing and noticing this. Sorry to make you hunt for the correct
> branch in that repo. ;) 
> 

No problem.

> https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v3
> is indeed the correct branch for those wanting to pull this in or
> grab some of the not-to-be-merged drivers I used for testing.
> 
> > I added a couple of patches to enable earlyprintk and build the DTB
> > appended kernel image uImage-dtb.am335x-evm
> > 
> > Here's what i see
> > 
> > [...]
> 
> <snip>
> 
> > [    0.175354] edma: probe of 49000000.edma failed with error -16
> 
> I missed an uninitialized pdata case in the bug fixes mentioned in
> the changelog and the folks previously failing the same way didn't
> hit the case I suspect you are hitting. Can you try this and let me
> know how it works?
> 

That doesn't help :(

Looking at the original crash log, I suspect something is not correct
with the irq portion, probably in the DT or the driver. 

"genirq: Flags mismatch irq 28. 00000000 (edma) vs. 00000000 (edma)"

The warning below that is coming due to fail case in edma_probe not tracking
the request_irq status properly and but IMO that's a separate issue.

BTW, I am trying this on the EVM.

Regards,
Vaibhav

^ permalink raw reply

* [PATCH RFC 02/15 v5] gpio: Add sysfs support to block GPIO API
From: Roland Stigge @ 2012-10-19 11:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkda35jKs9YVNDAo96=0QzdMi+jkvJAzM=nX+HCK-d5+e9Q@mail.gmail.com>

On 10/19/2012 12:35 PM, Linus Walleij wrote:
> On Thu, Oct 18, 2012 at 12:07 PM, Roland Stigge <stigge@antcom.de> wrote:
>> On 10/17/2012 09:05 PM, Greg KH wrote:
>>>>
>>>> +    if (value != exported) {
>>>> +            if (value)
>>>> +                    status = gpio_block_value_export(block);
>>>> +            else
>>>> +                    status = gpio_block_value_unexport(block);
>>>
>>> That looks like a recipie for disaster.  Why do you allow userspace to
>>> do this?
>>
>> Exporting for gpio blocks is done as follows: writing "1" to the
>> "exported" _device_ attribute of the gpio block creates the "values"
>> attribute and at the same time requests the whole block (including all
>> of its gpios) as "sysfs".
> 
> To me it reads like Greg's comment is basically pinpointing a flaw
> in Brownell's initial design of gpio sysfs: that new sysfs files are
> created and destroyed by writing into sysfs */export files from
> userspace?
> 
> See commit: d8f388d8dc8d4f36539dd37c1fff62cc404ea0fc
> 
> The block GPIO stuff is just following that design pattern.

So what do you think about my just proposed idea of always having the
"value" argument present, but only useable when "exported" is "1"? Now
only talking about the block gpios, but later maybe also for gpios?

But I would only do this if you and Greg consider it reasonable.

Thanks in advance,

Roland

^ permalink raw reply

* pxa:spitz_pm.c: commit b6eede11 breaks spitz resume under certain conditions.
From: Marko Katić @ 2012-10-19 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHod+GcwNr6r_ZQFq-btPJ3E_keWKJhkCb2jP4CES6JTSyn8ow@mail.gmail.com>

On Thu, Oct 18, 2012 at 11:28 AM, Marko Kati? <dromede@gmail.com> wrote:
>> Almost there, but I guess we could do this better and less confusing by having
>> another array, e.g. tosa_gpio18_config[], which is tosa specific, and only
>> initialize that MFP setting in the tosa path.
>>
>>>
>>> I also looked at the original sharp kernel sources.
>>> Only tosa used the RDY signal for it's tc6393tx chip, other machines simply
>>> configured gpio18 as output in their suspend routines.
>
>
> Actually, tosa doesn't use sharpsl_pm. Tosa uses the pda-power framework.
> I said that only tosa uses the RDY signal to point out that we
> probably don't need
> the mfp-config line in postsuspend. That being said, i still think
> that the array ordering
> fix is adequate. Maybe later we may remove the mfp-config line from
> postsuspend when
> we're absolutely sure it isn't necessary for devices that use spitz_pm.c.

So Eric what do you think, is the simple gpio array reordering patch
an adequate fix for this bug?

^ permalink raw reply

* [PATCH v2] arm/dts: AM33XX: Add SPI device tree data
From: Matt Porter @ 2012-10-19 11:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50810E2F.5@ti.com>

On Fri, Oct 19, 2012 at 10:24:15AM +0200, Benoit Cousson wrote:
> Hi Avinash,
> 
> This look good to me except the: status = "disabled".
> 
> The "disabled" should be reserved for variant that does not contain the IP.
> Is it the case here?

http://comments.gmane.org/gmane.linux.drivers.devicetree/18968 is what
I've been going by with the DTS support in the EDMA dmaengine series. It
does make the most sense to only enable what you need in the
<board>.dts.

-Matt

> On 09/18/2012 07:30 AM, Philip, Avinash wrote:
> > Add McSPI data node to AM33XX device tree file. The McSPI module (and so
> > as the driver) is reused from OMAP4.
> > 
> > Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
> > Tested-by: Matt Porter <mporter@ti.com>
> > ---
> > Changes since v1:
> >         - Corrected reg offset in reg DT entry.
> > 
> > :100644 100644 ff3badb... 065fd54... M	arch/arm/boot/dts/am33xx.dtsi
> >  arch/arm/boot/dts/am33xx.dtsi |   25 +++++++++++++++++++++++++
> >  1 files changed, 25 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
> > index ff3badb..065fd54 100644
> > --- a/arch/arm/boot/dts/am33xx.dtsi
> > +++ b/arch/arm/boot/dts/am33xx.dtsi
> > @@ -219,5 +219,30 @@
> >  			interrupt-parent = <&intc>;
> >  			interrupts = <91>;
> >  		};
> > +
> > +		spi0: spi at 48030000 {
> > +			compatible = "ti,omap4-mcspi";
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +			reg = <0x48030000 0x400>;
> > +			interrupt-parent = <&intc>;
> > +			interrupt = <65>;
> > +			ti,spi-num-cs = <2>;
> > +			ti,hwmods = "spi0";
> > +			status = "disabled";
> > +
> > +		};
> > +
> > +		spi1: spi at 481a0000 {
> > +			compatible = "ti,omap4-mcspi";
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +			reg = <0x481a0000 0x400>;
> > +			interrupt-parent = <&intc>;
> > +			interrupt = <125>;
> > +			ti,spi-num-cs = <2>;
> > +			ti,hwmods = "spi1";
> > +			status = "disabled";
> > +		};
> >  	};
> >  };
> > 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox