Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 3/3] ACPI / processor: Introduce map_gic_id() to get apic id from MADT or _MAT method
From: Hanjun Guo @ 2014-02-10  7:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392018542-10949-1-git-send-email-hanjun.guo@linaro.org>

Get apic id from MADT or _MAT method is not implemented on arm/arm64,
and ACPI 5.0 introduces GIC Structure for it, so this patch introduces
map_gic_id() to get apic id followed the ACPI 5.0 spec.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/processor_core.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 575c500..eaaeebc 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -71,6 +71,27 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
 	return 0;
 }
 
+static int map_gic_id(struct acpi_subtable_header *entry,
+		int device_declaration, u32 acpi_id, int *apic_id)
+{
+	struct acpi_madt_generic_interrupt *gic =
+		(struct acpi_madt_generic_interrupt *)entry;
+
+	if (!(gic->flags & ACPI_MADT_ENABLED))
+		return -ENODEV;
+
+	/* In the GIC interrupt model, logical processors are
+	 * required to have a Processor Device object in the DSDT,
+	 * so we should check device_declaration here
+	 */
+	if (device_declaration && (gic->uid == acpi_id)) {
+		*apic_id = gic->gic_id;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static int map_madt_entry(int type, u32 acpi_id)
 {
 	unsigned long madt_end, entry;
@@ -106,6 +127,9 @@ static int map_madt_entry(int type, u32 acpi_id)
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 			if (!map_lsapic_id(header, type, acpi_id, &apic_id))
 				break;
+		} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
+			if (!map_gic_id(header, type, acpi_id, &apic_id))
+				break;
 		}
 		entry += header->length;
 	}
@@ -136,6 +160,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
 		map_lapic_id(header, acpi_id, &apic_id);
 	} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 		map_lsapic_id(header, type, acpi_id, &apic_id);
+	} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
+		map_gic_id(header, type, acpi_id, &apic_id);
 	}
 
 exit:
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v2 2/2] Documentation: devicetree: Add boost-frequency binding to list boost mode frequency
From: Lukasz Majewski @ 2014-02-10  7:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAJuA9aj-LsdBiS2msOVmNRSe6mNj9QJsys9KjHZAk=9hrZOLzA@mail.gmail.com>

Hi Thomas, Sudeep,

> On Sat, Feb 8, 2014 at 1:11 AM, Nishanth Menon <nm@ti.com> wrote:
> > On Fri, Feb 7, 2014 at 12:02 PM, Sudeep Holla
> > <Sudeep.Holla@arm.com> wrote:
> >> On 07/02/14 17:37, Nishanth Menon wrote:
> >>> On Fri, Feb 7, 2014 at 11:31 AM, Sudeep Holla
> >>> <Sudeep.Holla@arm.com> wrote:
> >>
> >> [...]
> >>
> >>>> Yes I think its counter-intuitive as it's visible to the
> >>>> userspace(list of frequencies and the boost parameters are
> >>>> exposed through sysfs)
> >>>
> >>> That will be a different problem -> as currently every single
> >>> frequency in the cpufreq list has ability to be marked as boost
> >>> frequency - if userspace does not maintain that, then, IMHO, fix
> >>> the userspace :D
> >>>
> >>
> >> /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies
> >> gives the list of frequencies based on the state of the boost
> >> feature at anytime.
> >>
> >> Intuitively the list without boost shouldn't have any frequency
> >> above the range when it's enabled :), that's what I was referring
> >> to. So I am not talking about any issue with user-space
> >> maintenance.
> > Fair enough - but i still think it has nothing to do with dt binding
> > itself -> and i think the discussion we've had should be good for
> > the binding provided in this patch.. I hope.. if documentation
> > needs a bit of better explanation to prevent a repeat of the same
> > discussion at a later point of time, now might be a good time to
> > add it in.
> 
> The term boost and over-clocking have been described in the bindings
> document as being the same. Since the term over-clocking refers to
> running a CPU beyond normal operating frequencies, I tend to agree
> with Sudeep that it is not intuitive if a normal operating frequency
> is greater than a boost mode frequency.
> 
> Otherwise, when userspace does "echo 1 >
> /sys/devices/system/cpu/cpufreq/boost", what is it supposed to mean. I
> think the original intent of boost mode patches was to allow CPU to
> operate at frequencies greater than the normal operating frequencies.
> 
> Lukasz, how would you want this to be handled?

Please consider an example:

normal-freqs: 1400000, 1200000, 1000000, 800000, 600000, 400000, 200000
[1]
boost-freqs: 1700000, 1600000, 1500000. [2]

All those freqs shall be represented as OPPs freq and voltage tuple.

Best would be to specify all the boost-freqs as:
boost-freqs = <1700000 1600000 1500000> to be prepared for future
quirks or problems (or special cases which might show up latter).
If anybody can foresee any potential threads - like platform on which
boost freqs are 1700000 and 1500000, but not 1600000, then please share
this information.

However, I think that it would be also acceptable to specify only:
boost-freq = <1500000> and mark all freqs greater or equal to it as
CPUFREQ_BOOST_FREQ.

If there aren't any potential problems, then I think the second option
would be a good solution (we would have only one BOOST attribute stored
at CPUs DTS node).

> 
> Thanks,
> Thomas.
> 
> >
> > Regards,
> > Nishanth Menon
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH v2] ARM: dts: i.MX51 babbage: Support diagnostic LED
From: Shawn Guo @ 2014-02-10  8:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392015946-22419-1-git-send-email-Ying.Liu@freescale.com>

On Mon, Feb 10, 2014 at 03:05:46PM +0800, Liu Ying wrote:
> The D25 LED controlled by gpio on the i.MX51 babbage
> board is a diagnostic LED according to the board design.
> This patch adds the relevant device tree nodes to the
> i.MX51 babbage device tree file to support this LED.
> 
> Signed-off-by: Liu Ying <Ying.Liu@freescale.com>

Applied, thanks.

^ permalink raw reply

* [PATCH v3 1/7] cpufreq: cpufreq-cpu0: allow use of optional boost mode frequencies
From: Lukasz Majewski @ 2014-02-10  8:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391788548-13056-2-git-send-email-thomas.ab@samsung.com>

Hi Thomas,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> Lookup for the optional boost-frequency property in cpu0 node and if
> available, enable support for boost mode frequencies. The frequencies
> usable in boost mode are determined while preparing the cpufreq table
> from the list of operating points available.
> 
> In addition to this, enable the CPU_FREQ_BOOST_SW config option for
> this driver by default. On platforms that do not support boost mode,
> the boost mode frequencies will not be specified in cpu0 node and
> hence the boost mode support will not be enabled. Since this driver
> anyways depends on THERMAL config option, it is safe to enable
> CPU_FREQ_BOOST_SW config option as default.

I think that you introduce some implicit dependency here.

I don't like the idea to enable CPU_FREQ_BOOST_SW by default and depend
on other option (THERMAL in this case).
 
I think that user shall feel free to explicitly enable or disable boost
from menuconfig.

> 
> Cc: Shawn Guo <shawn.guo@linaro.org>
> Cc: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
>  Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt |    2 ++
>  drivers/cpufreq/Kconfig                                    |    1 +
>  drivers/cpufreq/cpufreq-cpu0.c                             |    3 +++
>  3 files changed, 6 insertions(+)
> 
> diff --git
> a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
> b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt index
> f055515..60f321a 100644 ---
> a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt +++
> b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt @@ -19,6
> +19,8 @@ Optional properties:
>  - cooling-min-level:
>  - cooling-max-level:
>       Please refer to
> Documentation/devicetree/bindings/thermal/thermal.txt. +-
> boost-frequency:
> +     Please refer to
> Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt 
>  Examples:
>  
> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> index 4b029c0..52cc704 100644
> --- a/drivers/cpufreq/Kconfig
> +++ b/drivers/cpufreq/Kconfig
> @@ -187,6 +187,7 @@ config GENERIC_CPUFREQ_CPU0
>  	tristate "Generic CPU0 cpufreq driver"
>  	depends on HAVE_CLK && REGULATOR && OF && THERMAL &&
> CPU_THERMAL select PM_OPP
> +	select CPU_FREQ_BOOST_SW
>  	help
>  	  This adds a generic cpufreq driver for CPU0 frequency
> management. It supports both uniprocessor (UP) and symmetric
> multiprocessor (SMP) diff --git a/drivers/cpufreq/cpufreq-cpu0.c
> b/drivers/cpufreq/cpufreq-cpu0.c index 0c12ffc..06539eb 100644
> --- a/drivers/cpufreq/cpufreq-cpu0.c
> +++ b/drivers/cpufreq/cpufreq-cpu0.c
> @@ -195,6 +195,9 @@ static int cpu0_cpufreq_probe(struct
> platform_device *pdev) transition_latency += ret * 1000;
>  	}
>  
> +	if (of_find_property(cpu_dev->of_node, "boost-frequency",
> NULL))
> +		cpu0_cpufreq_driver.boost_supported = true;
> +

This is also a bit misleading. Here you assume, that boost is supported
when somebody define "boost-frequency" DTS attribute. Conceptually the
boost is supported when user explicitly selects
CONFIG_CPU_FREQ_BOOST_SW.


I would prefer to see approach similar to the one now found at
exynos-cpufreq.c exynos_driver struct:

static struct cpufreq_driver cpu0_cpufreq_driver = {
	.flags = CPUFREQ_STICKY,
	.verify = cpu0_verify_speed,
	.target = cpu0_set_target,
	.get = cpu0_get_speed,
#ifdef CONFIG_CPU_FREQ_BOOST_SW
	.boost_supported = true,
#endif
	... other fields ...

and also, please remove references to
CONFIG_ARM_EXYNOS_CPU_FREQ_BOOST_SW flag since it will not be used
after the exynos cpufreq clean up.

>  	ret = cpufreq_register_driver(&cpu0_cpufreq_driver);
>  	if (ret) {
>  		pr_err("failed register driver: %d\n", ret);


-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH] ARM: imx6q: support ptp and rmii clock from pad
From: Philippe De Muyter @ 2014-02-10  8:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210060321.GG9628@S2101-09.ap.freescale.net>

On Mon, Feb 10, 2014 at 02:03:23PM +0800, Shawn Guo wrote:
> On Fri, Feb 07, 2014 at 11:45:18AM +0100, Philippe De Muyter wrote:
> > Thanks, Shawn
> > 
> > your patch works perfectly.  I can now use the same kernel on my sabresd
> > board (RGMII, enet_ref_clock generated by the imx6q) and my custom board
> > (RMII, clock generated by the PHY).
> 
> That's great.
> 
> > 
> > some comments. though :
> > 
> > the patch did not apply cleanly in clk-imx6q.c on v3.13
> 
> The patch targets v3.14-rc1, and if you need it for v3.13 you will need
> to back port it.
> 
> > 
> > don't forget to complete Documentation/devicetree/bindings/
> 
> It requires change on device tree sources but not bindings.  Which part
> of Documentation/devicetree/bindings/ do you think we need to update?

Would Documentation/devicetree/bindings/net/fsl-fec.txt (perhaps also
Documentation/devicetree/bindings/clock/imx6q-clock.txt) not be a good place
for that ?

Philippe

> 
> Shawn
> 
> > 
> > But, again, many thanks for the support
> > 
> > Philippe
> > 
> > 
> > On Thu, Feb 06, 2014 at 01:53:38PM +0800, Shawn Guo wrote:
> > > On imx6qdl, the ENET RMII and PTP clock can come from either internal
> > > ANATOP/CCM or external clock source through pad GPIO_16.  But in case
> > > of the external clock source, bit IOMUXC_GPR1[21] needs to be cleared.
> > > 
> > > The patch adds the support for systems that use an external clock source
> > > and distinguishes above two cases by checking if the PTP clock specified
> > > in device tree is the one coming from the internal ANATOP/CCM.
> > > 
> > > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>

-- 
Philippe De Muyter +32 2 6101532 Macq SA rue de l'Aeronef 2 B-1140 Bruxelles

^ permalink raw reply

* [RFC PATCH] ARM: Add imprecise abort enable/disable macro
From: Fabrice Gasnier @ 2014-02-10  8:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140207170903.GT5976@mudshark.cambridge.arm.com>

On 02/07/2014 06:09 PM, Will Deacon wrote:
> On Fri, Feb 07, 2014 at 04:19:15PM +0000, Fabrice GASNIER wrote:
>> This patch adds imprecise abort enable/disable macros.
>> It also enables imprecise aborts when starting kernel.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>> ---
>>   arch/arm/include/asm/irqflags.h |   33 +++++++++++++++++++++++++++++++++
>>   arch/arm/kernel/smp.c           |    1 +
>>   arch/arm/kernel/traps.c         |    4 ++++
>>   3 files changed, 38 insertions(+)
>>
>> diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h
>> index 3b763d6..82e3834 100644
>> --- a/arch/arm/include/asm/irqflags.h
>> +++ b/arch/arm/include/asm/irqflags.h
>> @@ -51,6 +51,9 @@ static inline void arch_local_irq_disable(void)
>>   
>>   #define local_fiq_enable()  __asm__("cpsie f	@ __stf" : : : "memory", "cc")
>>   #define local_fiq_disable() __asm__("cpsid f	@ __clf" : : : "memory", "cc")
>> +
>> +#define local_abt_enable()  __asm__("cpsie a	@ __sta" : : : "memory", "cc")
>> +#define local_abt_disable() __asm__("cpsid a	@ __cla" : : : "memory", "cc")
>>   #else
>>   
>>   /*
>> @@ -130,6 +133,36 @@ static inline void arch_local_irq_disable(void)
>>   	: "memory", "cc");					\
>>   	})
>>   
>> +/*
>> + * Enable Aborts
>> + */
>> +#define local_abt_enable()					\
>> +	({							\
>> +		unsigned long temp;				\
>> +	__asm__ __volatile__(					\
>> +	"mrs	%0, cpsr		@ sta\n"		\
>> +"	bic	%0, %0, %1\n"					\
>> +"	msr	cpsr_c, %0"					\
>> +	: "=r" (temp)						\
>> +	: "r" (PSR_A_BIT)					\
> Can you use "i" instead of a register for this constant?
Hi,

Sure, I will change it in a future patch.
>
>> +	: "memory", "cc");					\
> You don't need the "cc" clobber.
That surprises me: I think "orr" and "bic" instruction might change N 
and Z bits, depending on the result.
So shouldn't "cc" be placed here ?
I also see that it is used in local_fiq_enable/disable macros just 
above, that are similar:
#define local_fiq_enable()                    \
     ({                            \
         unsigned long temp;                \
     __asm__ __volatile__(                    \
     "mrs    %0, cpsr        @ stf\n"        \
"    bic    %0, %0, #64\n"                    \
"    msr    cpsr_c, %0"                    \
     : "=r" (temp)                        \
     :                            \
     : "memory", "cc");                    \
     })
>>   #endif
>>   
>>   /*
>> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
>> index dc894ab..c2093cb 100644
>> --- a/arch/arm/kernel/smp.c
>> +++ b/arch/arm/kernel/smp.c
>> @@ -377,6 +377,7 @@ asmlinkage void secondary_start_kernel(void)
>>   
>>   	local_irq_enable();
>>   	local_fiq_enable();
>> +	local_abt_enable();
>>   
>>   	/*
>>   	 * OK, it's off to the idle thread for us
>> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
>> index 4636d56..ef15709 100644
>> --- a/arch/arm/kernel/traps.c
>> +++ b/arch/arm/kernel/traps.c
>> @@ -900,6 +900,10 @@ void __init early_trap_init(void *vectors_base)
>>   
>>   	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
>>   	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
>> +
>> +	/* Enable imprecise aborts */
>> +	local_abt_enable();
> Surely we want to enable this as early as possible? Now, putting this into
> head.S is ugly, as it duplicating it across all the proc*.S files, so why
> not setup_arch?
Sorry, I'm not sure to understand your last comment.
At least, I need it enabled before probing drivers (PCIe bus)
I've added imprecise abort enable code in traps.c, following Russel 
King's advice, please see:
http://archive.arm.linux.org.uk/lurker/message/20140131.170827.d752a1cc.en.html
As abort bit is local to a cpu, i've also added it in smp.c, but this 
may not be the right place ?

Please elaborate,

Thanks,
Fabrice
>
> Will

^ permalink raw reply

* [PATCH V5 0/8]PCI:Add SPEAr13xx PCie support
From: Mohit Kumar @ 2014-02-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

From: Pratyush Anand <pratyush.anand@st.com>

First three patches are improvement and fixes for SPEAr13xx support.
Patches 4-6 add miphy40lp skelten driver and support for spear1310/40 miphy
wrapper. Patch 7 add support for SPEAr13xx PCIe.

These pathes are tested with linux-3.14-rc1 with following patch on the top of
it:
Author: Balaji T K <balajitk@ti.com>
Date:   Mon Jan 20 16:41:27 2014 +0200

    ata: ahci_platform: Manage SATA PHY

Tested with SPEAr1310 evaluation board:
	- INTEL PRO 100/100 EP card
	- USB xhci gen2 card
 	- Above cards connected through LeCROY PTC switch

Modifications for SATA are tested with SPEAr1340-evb board

Changes since v4:
- Uses per device function pointers passed from .data field to
  the of_device_id instead of of_device_is_compatible.
- Incorporated other minor comments from v4

Changes since v3:
- Phy driver renamed to phy-miphy40lp
- ahci phy hook patch used as suggested by Arnd
- Incorporated other minor comments from v3

Changes since v2:
- Incorporated comments to move SPEAr13xx PCIe and SATA phy specific routines to
  the phy framework
- Modify ahci driver to include phy hooks
- phy-core driver modifications for subsys_initcall() 
 
Changes since v1:
- Few patches of the series are already accepted and applied to mainline e.g.
 pcie designware driver improvements,fixes for IO translation bug, PCIe dw
 driver maintainer. So dropped these from v2.
- Incorporated comment to move the common/reset PCIe code to the seperate driver
- PCIe and SATA share common PHY configuration registers, so move SATA
 platform code to the system config driver
Fourth patch is improves pcie designware driver and fixes the IO
translation bug. IO translation bug fix leads to the working of PCIe EP devices
connected to RC through switch.

PCIe driver support for SPEAr1310/40 platform board is added.

These patches are tested with SPEAr1310 evaluation board:
	- INTEL PRO 100/100 EP card
	- USB xhci gen2 card
 	- Above cards connected through LeCROY PTC switch

Cc: linux-arm-kernel at lists.infradead.org
Cc: devicetree at vger.kernel.org
Cc: linux-ide at vger.kernel.org
Cc: linux-pci at vger.kernel.org
Cc: spear-devel at list.st.com
Cc: linux-kernel at vger.kernel.org
Cc: linux-pm at vger.kernel.org


Mohit Kumar (2):
  SPEAr13xx: defconfig: Update
  MAINTAINERS: Add ST SPEAr13xx PCIe driver maintainer

Pratyush Anand (6):
  clk: SPEAr13xx: Fix pcie clock name
  SPEAr13xx: Fix static mapping table
  phy: st-miphy-40lp: Add skeleton driver
  SPEAr13xx: Fixup: Move SPEAr1340 SATA platform code to phy driver
  phy: st-miphy-40lp: Add SPEAr1310 and SPEAr1340 PCIe phy support
  pcie: SPEAr13xx: Add designware pcie support

 .../devicetree/bindings/arm/spear-misc.txt         |   4 +
 .../devicetree/bindings/pci/spear13xx-pcie.txt     |   7 +
 .../devicetree/bindings/phy/st-miphy40lp.txt       |  12 +
 MAINTAINERS                                        |   6 +
 arch/arm/boot/dts/spear1310-evb.dts                |   4 +
 arch/arm/boot/dts/spear1310.dtsi                   |  96 +++-
 arch/arm/boot/dts/spear1340-evb.dts                |   4 +
 arch/arm/boot/dts/spear1340.dtsi                   |  32 +-
 arch/arm/boot/dts/spear13xx.dtsi                   |  10 +-
 arch/arm/configs/spear13xx_defconfig               |  15 +
 arch/arm/mach-spear/Kconfig                        |   3 +
 arch/arm/mach-spear/include/mach/spear.h           |   4 +-
 arch/arm/mach-spear/spear1340.c                    | 127 +----
 arch/arm/mach-spear/spear13xx.c                    |   2 +-
 drivers/clk/spear/spear1310_clock.c                |   6 +-
 drivers/clk/spear/spear1340_clock.c                |   2 +-
 drivers/pci/host/Kconfig                           |   5 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pcie-spear13xx.c                  | 414 ++++++++++++++++
 drivers/phy/Kconfig                                |   6 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-miphy40lp.c                        | 538 +++++++++++++++++++++
 22 files changed, 1160 insertions(+), 139 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/spear-misc.txt
 create mode 100644 Documentation/devicetree/bindings/pci/spear13xx-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/phy/st-miphy40lp.txt
 create mode 100644 drivers/pci/host/pcie-spear13xx.c
 create mode 100644 drivers/phy/phy-miphy40lp.c

-- 
1.8.1.2

^ permalink raw reply

* [PATCH V5 1/8] clk: SPEAr13xx: Fix pcie clock name
From: Mohit Kumar @ 2014-02-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1391871170.git.pratyush.anand@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

Follow dt clock naming convention for PCIe clocks.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Mohit Kumar <mohit.kumar@st.com>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
---
 drivers/clk/spear/spear1310_clock.c | 6 +++---
 drivers/clk/spear/spear1340_clock.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c
index 65894f7..4daa597 100644
--- a/drivers/clk/spear/spear1310_clock.c
+++ b/drivers/clk/spear/spear1310_clock.c
@@ -742,19 +742,19 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
 	clk = clk_register_gate(NULL, "pcie_sata_0_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_0_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.0");
+	clk_register_clkdev(clk, NULL, "b1000000.pcie");
 	clk_register_clkdev(clk, NULL, "b1000000.ahci");
 
 	clk = clk_register_gate(NULL, "pcie_sata_1_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_1_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.1");
+	clk_register_clkdev(clk, NULL, "b1800000.pcie");
 	clk_register_clkdev(clk, NULL, "b1800000.ahci");
 
 	clk = clk_register_gate(NULL, "pcie_sata_2_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_2_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.2");
+	clk_register_clkdev(clk, NULL, "b4000000.pcie");
 	clk_register_clkdev(clk, NULL, "b4000000.ahci");
 
 	clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c
index fe835c1..5a5c664 100644
--- a/drivers/clk/spear/spear1340_clock.c
+++ b/drivers/clk/spear/spear1340_clock.c
@@ -839,7 +839,7 @@ void __init spear1340_clk_init(void __iomem *misc_base)
 	clk = clk_register_gate(NULL, "pcie_sata_clk", "ahb_clk", 0,
 			SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_PCIE_SATA_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie");
+	clk_register_clkdev(clk, NULL, "b1000000.pcie");
 	clk_register_clkdev(clk, NULL, "b1000000.ahci");
 
 	clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH V5 2/8] SPEAr13xx: Fix static mapping table
From: Mohit Kumar @ 2014-02-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1391871170.git.pratyush.anand@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

SPEAr13xx was using virtual address space 0xFE000000 to map physical address
space 0xB3000000. pci_remap_io uses 0xFEE00000 as virtual address. So
change 0xFE000000 to 0xF9000000.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Signed-off-by: Mohit Kumar <mohit.kumar@st.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: spear-devel at list.st.com
Cc: stable at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/mach-spear/include/mach/spear.h | 4 ++--
 arch/arm/mach-spear/spear13xx.c          | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h
index 5cdc53d..f2d6a01 100644
--- a/arch/arm/mach-spear/include/mach/spear.h
+++ b/arch/arm/mach-spear/include/mach/spear.h
@@ -52,10 +52,10 @@
 #ifdef CONFIG_ARCH_SPEAR13XX
 
 #define PERIP_GRP2_BASE				UL(0xB3000000)
-#define VA_PERIP_GRP2_BASE			IOMEM(0xFE000000)
+#define VA_PERIP_GRP2_BASE			IOMEM(0xF9000000)
 #define MCIF_SDHCI_BASE				UL(0xB3000000)
 #define SYSRAM0_BASE				UL(0xB3800000)
-#define VA_SYSRAM0_BASE				IOMEM(0xFE800000)
+#define VA_SYSRAM0_BASE				IOMEM(0xF9800000)
 #define SYS_LOCATION				(VA_SYSRAM0_BASE + 0x600)
 
 #define PERIP_GRP1_BASE				UL(0xE0000000)
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index 7aa6e8c..89212ff 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -52,7 +52,7 @@ void __init spear13xx_l2x0_init(void)
 /*
  * Following will create 16MB static virtual/physical mappings
  * PHYSICAL		VIRTUAL
- * 0xB3000000		0xFE000000
+ * 0xB3000000		0xF9000000
  * 0xE0000000		0xFD000000
  * 0xEC000000		0xFC000000
  * 0xED000000		0xFB000000
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH V5 3/8] SPEAr13xx: defconfig: Update
From: Mohit Kumar @ 2014-02-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1391871170.git.pratyush.anand@st.com>

Enable EABI, VFP and NFS configs in default configuration file for
SPEAr13xx.

Signed-off-by: Mohit Kumar <mohit.kumar@st.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Pratyush Anand <pratyush.anand@st.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/configs/spear13xx_defconfig | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
index 82eaa55..1e0bb6f 100644
--- a/arch/arm/configs/spear13xx_defconfig
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -14,10 +14,18 @@ CONFIG_MACH_SPEAR1340=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
 # CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_AEABI=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_VFP=y
 CONFIG_BINFMT_MISC=y
 CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_OF_PARTS=y
@@ -27,6 +35,7 @@ CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
 # CONFIG_SATA_PMP is not set
 CONFIG_SATA_AHCI_PLATFORM=y
@@ -66,6 +75,7 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SPEAR=y
@@ -79,11 +89,14 @@ CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_SECURITY=y
 CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
 CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=m
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH V5 4/8] phy: st-miphy-40lp: Add skeleton driver
From: Mohit Kumar @ 2014-02-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1391871170.git.pratyush.anand@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

ST miphy-40lp supports PCIe, SATA and Super Speed USB. This driver adds
skeleton support for the same.

This skeleton defines function corresponding to phy ops as well as sleep
pm ops. Any platform using this phy can add its own platform specific
ops(if needed) corresponding to each phy ops.

Phy specific modifications will require phy register space, which is
passed from DT as a resource. Currently only SPEAr1310 and SPEAr1340 are
known user of this phy, which do not need to modify phy registers
normally. Therefore we have not retrieved phy base address from DT and
hence not io-remapped it. However, same can be added in future if
required.

SoC specific modifications should be done in plat specific ops and phy
specific modifications should be done in phy ops itself. As a general
rule, follow the convention of modifying misc reg space in plat ops and
phy reg space in phy ops.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Tested-by: Mohit Kumar <mohit.kumar@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
---
 .../devicetree/bindings/phy/st-miphy40lp.txt       |  12 ++
 drivers/phy/Kconfig                                |   6 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-miphy40lp.c                        | 229 +++++++++++++++++++++
 4 files changed, 248 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/st-miphy40lp.txt
 create mode 100644 drivers/phy/phy-miphy40lp.c

diff --git a/Documentation/devicetree/bindings/phy/st-miphy40lp.txt b/Documentation/devicetree/bindings/phy/st-miphy40lp.txt
new file mode 100644
index 0000000..d0c7096
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st-miphy40lp.txt
@@ -0,0 +1,12 @@
+Required properties:
+- compatible : should be "st,miphy40lp-phy"
+	Other supported soc specific compatible:
+		"st,spear1310-miphy"
+		"st,spear1340-miphy"
+- reg : offset and length of the PHY register set.
+- misc: phandle for the syscon node to access misc registers
+- phy-id: Instance id of the phy.
+- #phy-cells : from the generic PHY bindings, must be 1.
+	- 1st cell: phandle to the phy node.
+	- 2nd cell: 0 if phy (in 1st cell) is to be used for SATA, 1 for PCIe
+	  and 2 for Super Speed USB.
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index afa2354..2f58993 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -64,4 +64,10 @@ config BCM_KONA_USB2_PHY
 	help
 	  Enable this to support the Broadcom Kona USB 2.0 PHY.
 
+config PHY_ST_MIPHY40LP
+	tristate "ST MIPHY 40LP driver"
+	help
+	  Support for ST MIPHY 40LP which can be used for PCIe, SATA and Super Speed USB.
+	select GENERIC_PHY
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index b57c253..c061091 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
 obj-$(CONFIG_PHY_MVEBU_SATA)		+= phy-mvebu-sata.o
 obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
+obj-$(CONFIG_PHY_ST_MIPHY40LP)		+= phy-miphy40lp.o
diff --git a/drivers/phy/phy-miphy40lp.c b/drivers/phy/phy-miphy40lp.c
new file mode 100644
index 0000000..3a9ada1
--- /dev/null
+++ b/drivers/phy/phy-miphy40lp.c
@@ -0,0 +1,229 @@
+/*
+ * ST MiPHY-40LP PHY driver
+ *
+ * Copyright (C) 2014 ST Microelectronics
+ * Pratyush Anand <pratyush.anand@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+
+enum phy_mode {
+	SATA,
+	PCIE,
+	SS_USB,
+};
+
+struct miphy40lp_priv;
+
+/* platform specific function struct */
+struct miphy40lp_plat_ops {
+	int	(*plat_init)(struct miphy40lp_priv *priv);
+	int	(*plat_exit)(struct miphy40lp_priv *priv);
+	int	(*plat_power_off)(struct miphy40lp_priv *priv);
+	int	(*plat_power_on)(struct miphy40lp_priv *priv);
+	int	(*plat_suspend)(struct miphy40lp_priv *priv);
+	int	(*plat_resume)(struct miphy40lp_priv *priv);
+};
+
+struct miphy40lp_priv {
+	/* regmap for any soc specific misc registers */
+	struct regmap			*misc;
+	/* phy struct pointer */
+	struct phy			*phy;
+	/* phy mode: 0 for SATA 1 for PCIe and 2 for SS-USB */
+	enum phy_mode			mode;
+	/* instance id of this phy */
+	u32				id;
+	/* platform specific callbacks */
+	struct miphy40lp_plat_ops	*plat_ops;
+};
+
+static int miphy40lp_init(struct phy *phy)
+{
+	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
+	struct miphy40lp_plat_ops *ops = priv->plat_ops;
+	int ret = 0;
+
+	if (ops && ops->plat_init)
+		ret = ops->plat_init(priv);
+
+	return ret;
+}
+
+static int miphy40lp_exit(struct phy *phy)
+{
+	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
+	struct miphy40lp_plat_ops *ops = priv->plat_ops;
+	int ret = 0;
+
+	if (ops && ops->plat_exit)
+		ret = ops->plat_exit(priv);
+
+	return ret;
+}
+
+static int miphy40lp_power_off(struct phy *phy)
+{
+	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
+	struct miphy40lp_plat_ops *ops = priv->plat_ops;
+	int ret = 0;
+
+	if (ops && ops->plat_init)
+		ret = ops->plat_init(priv);
+
+	return ret;
+}
+
+static int miphy40lp_power_on(struct phy *phy)
+{
+	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
+	struct miphy40lp_plat_ops *ops = priv->plat_ops;
+	int ret = 0;
+
+	if (ops && ops->plat_power_on)
+		ret = ops->plat_power_on(priv);
+
+	return ret;
+}
+
+static const struct of_device_id miphy40lp_of_match[] = {
+	{ .compatible = "st,miphy40lp-phy", .data = NULL },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, miphy40lp_of_match);
+
+static struct phy_ops miphy40lp_ops = {
+	.init = miphy40lp_init,
+	.exit = miphy40lp_exit,
+	.power_off = miphy40lp_power_off,
+	.power_on = miphy40lp_power_on,
+	.owner = THIS_MODULE,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int miphy40lp_suspend(struct device *dev)
+{
+	struct miphy40lp_priv *priv = dev_get_drvdata(dev);
+	struct miphy40lp_plat_ops *ops = priv->plat_ops;
+	int ret = 0;
+
+	if (ops && ops->plat_suspend)
+		ret = ops->plat_suspend(priv);
+
+	return ret;
+}
+
+static int miphy40lp_resume(struct device *dev)
+{
+	struct miphy40lp_priv *priv = dev_get_drvdata(dev);
+	struct miphy40lp_plat_ops *ops = priv->plat_ops;
+	int ret = 0;
+
+	if (ops && ops->plat_resume)
+		ret = ops->plat_resume(priv);
+
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(miphy40lp_pm_ops, miphy40lp_suspend,
+		miphy40lp_resume);
+
+static struct phy *miphy40lp_xlate(struct device *dev,
+					struct of_phandle_args *args)
+{
+	struct miphy40lp_priv *priv = dev_get_drvdata(dev);
+
+	if (args->args_count < 1) {
+		dev_err(dev, "DT did not pass correct no of args\n");
+		return NULL;
+	}
+
+	priv->mode = args->args[0];
+
+	return priv->phy;
+}
+
+static int __init miphy40lp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct miphy40lp_priv *priv;
+	struct phy_provider *phy_provider;
+	const struct of_device_id *of_id;
+
+	of_id = of_match_device(miphy40lp_of_match, dev);
+	if (!of_id) {
+		dev_err(dev, "can't find a matching platform\n");
+		return -EINVAL;
+	}
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(dev, "can't alloc miphy40lp private date memory\n");
+		return -ENOMEM;
+	}
+
+	priv->plat_ops = (struct miphy40lp_plat_ops *)of_id->data;
+
+	priv->misc =
+		syscon_regmap_lookup_by_phandle(dev->of_node, "misc");
+	if (IS_ERR(priv->misc)) {
+		dev_err(dev, "failed to find misc regmap\n");
+		return PTR_ERR(priv->misc);
+	}
+
+	if (of_property_read_u32(dev->of_node, "phy-id", &priv->id)) {
+		dev_err(dev, "failed to find phy id\n");
+		return -EINVAL;
+	}
+
+	priv->phy = devm_phy_create(dev, &miphy40lp_ops, NULL);
+	if (IS_ERR(priv->phy)) {
+		dev_err(dev, "failed to create SATA PCIe PHY\n");
+		return PTR_ERR(priv->phy);
+	}
+
+	dev_set_drvdata(dev, priv);
+	phy_set_drvdata(priv->phy, priv);
+
+	phy_provider = devm_of_phy_provider_register(dev, miphy40lp_xlate);
+	if (IS_ERR(phy_provider)) {
+		dev_err(dev, "failed to register phy provider\n");
+		return PTR_ERR(phy_provider);
+	}
+
+	return 0;
+}
+
+static struct platform_driver miphy40lp_driver = {
+	.driver = {
+		.name = "miphy40lp-phy",
+		.owner = THIS_MODULE,
+		.pm = &miphy40lp_pm_ops,
+		.of_match_table = of_match_ptr(miphy40lp_of_match),
+	},
+};
+
+static int __init miphy40lp_phy_init(void)
+{
+
+	return platform_driver_probe(&miphy40lp_driver,
+				miphy40lp_probe);
+}
+module_init(miphy40lp_phy_init);
+
+MODULE_DESCRIPTION("ST MIPHY-40LP driver");
+MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH V5 5/8] SPEAr13xx: Fixup: Move SPEAr1340 SATA platform code to phy driver
From: Mohit Kumar @ 2014-02-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1391871170.git.pratyush.anand@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

ahci driver needs some platform specific functions which are called at
init, exit, suspend and resume conditions. Till now these functions were
present in a platform driver with a fixme notes.

Similar functions modifying same set of registers will also be needed in
case of PCIe phy init/exit.

So move all these SATA platform code to phy-miphy40lp driver.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Tested-by: Mohit Kumar <mohit.kumar@st.com>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: devicetree at vger.kernel.org
Cc: linux-ide at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-pm at vger.kernel.org
---
 .../devicetree/bindings/arm/spear-misc.txt         |   4 +
 arch/arm/boot/dts/spear1310-evb.dts                |   4 +
 arch/arm/boot/dts/spear1310.dtsi                   |  39 +++++-
 arch/arm/boot/dts/spear1340-evb.dts                |   4 +
 arch/arm/boot/dts/spear1340.dtsi                   |  13 +-
 arch/arm/boot/dts/spear13xx.dtsi                   |   5 +
 arch/arm/mach-spear/Kconfig                        |   2 +
 arch/arm/mach-spear/spear1340.c                    | 127 +-----------------
 drivers/phy/phy-miphy40lp.c                        | 144 +++++++++++++++++++++
 9 files changed, 212 insertions(+), 130 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/spear-misc.txt

diff --git a/Documentation/devicetree/bindings/arm/spear-misc.txt b/Documentation/devicetree/bindings/arm/spear-misc.txt
new file mode 100644
index 0000000..aacd36a
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/spear-misc.txt
@@ -0,0 +1,4 @@
+* SPEAr Misc configuration
+** misc node required properties:
+- compatible Should be	"st,spear1340-misc", "syscon".
+- reg: Address range of misc space
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
index b56a801..d42c84b 100644
--- a/arch/arm/boot/dts/spear1310-evb.dts
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -106,6 +106,10 @@
 			status = "okay";
 		};
 
+		miphy at eb800000 {
+			status = "okay";
+		};
+
 		cf at b2800000 {
 			status = "okay";
 		};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
index 122ae94..64e7dd5 100644
--- a/arch/arm/boot/dts/spear1310.dtsi
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -29,24 +29,57 @@
 			#gpio-cells = <2>;
 		};
 
-		ahci at b1000000 {
+		miphy0: miphy at eb800000 {
+			compatible = "st,miphy", "st,spear1310-miphy";
+			reg = <0xeb800000 0x4000>;
+			misc = <&misc>;
+			phy-id = <0>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		miphy1: miphy at eb804000 {
+			compatible = "st,miphy", "st,spear1310-miphy";
+			reg = <0xeb804000 0x4000>;
+			misc = <&misc>;
+			phy-id = <1>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		miphy2: miphy at eb808000 {
+			compatible = "st,miphy", "st,spear1310-miphy";
+			reg = <0xeb808000 0x4000>;
+			misc = <&misc>;
+			phy-id = <2>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		ahci0: ahci at b1000000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb1000000 0x10000>;
 			interrupts = <0 68 0x4>;
+			phys = <&miphy0 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
-		ahci at b1800000 {
+		ahci1: ahci at b1800000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb1800000 0x10000>;
 			interrupts = <0 69 0x4>;
+			phys = <&miphy1 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
-		ahci at b4000000 {
+		ahci2: ahci at b4000000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb4000000 0x10000>;
 			interrupts = <0 70 0x4>;
+			phys = <&miphy2 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
index d6c30ae..b23e05e 100644
--- a/arch/arm/boot/dts/spear1340-evb.dts
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -122,6 +122,10 @@
 			status = "okay";
 		};
 
+		miphy at eb800000 {
+			status = "okay";
+		};
+
 		dma at ea800000 {
 			status = "okay";
 		};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index 54d128d..7e3a04b 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -31,10 +31,21 @@
 			status = "disabled";
 		};
 
-		ahci at b1000000 {
+		miphy0: miphy at eb800000 {
+			compatible = "st,miphy", "st,spear1340-miphy";
+			reg = <0xeb800000 0x4000>;
+			misc = <&misc>;
+			phy-id = <0>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		ahci0: ahci at b1000000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb1000000 0x10000>;
 			interrupts = <0 72 0x4>;
+			phys = <&miphy0 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
index 4382547..3a72508 100644
--- a/arch/arm/boot/dts/spear13xx.dtsi
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -220,6 +220,11 @@
 				  0xd8000000 0xd8000000 0x01000000
 				  0xe0000000 0xe0000000 0x10000000>;
 
+			misc: syscon at e0700000 {
+				compatible = "st,spear1340-misc", "syscon";
+				reg = <0xe0700000 0x1000>;
+			};
+
 			gpio0: gpio at e0600000 {
 				compatible = "arm,pl061", "arm,primecell";
 				reg = <0xe0600000 0x1000>;
diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
index ac1710e6..7e7f1b0 100644
--- a/arch/arm/mach-spear/Kconfig
+++ b/arch/arm/mach-spear/Kconfig
@@ -26,6 +26,8 @@ config ARCH_SPEAR13XX
 	select MIGHT_HAVE_CACHE_L2X0
 	select PINCTRL
 	select USE_OF
+	select MFD_SYSCON
+	select PHY_ST_MIPHY40LP
 	help
 	  Supports for ARM's SPEAR13XX family
 
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
index 3fb6834..8e27093 100644
--- a/arch/arm/mach-spear/spear1340.c
+++ b/arch/arm/mach-spear/spear1340.c
@@ -11,138 +11,13 @@
  * warranty of any kind, whether express or implied.
  */
 
-#define pr_fmt(fmt) "SPEAr1340: " fmt
-
-#include <linux/ahci_platform.h>
-#include <linux/amba/serial.h>
-#include <linux/delay.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include "generic.h"
-#include <mach/spear.h>
-
-/* FIXME: Move SATA PHY code into a standalone driver */
-
-/* Base addresses */
-#define SPEAR1340_SATA_BASE			UL(0xB1000000)
-
-/* Power Management Registers */
-#define SPEAR1340_PCM_CFG			(VA_MISC_BASE + 0x100)
-#define SPEAR1340_PCM_WKUP_CFG			(VA_MISC_BASE + 0x104)
-#define SPEAR1340_SWITCH_CTR			(VA_MISC_BASE + 0x108)
-
-#define SPEAR1340_PERIP1_SW_RST			(VA_MISC_BASE + 0x318)
-#define SPEAR1340_PERIP2_SW_RST			(VA_MISC_BASE + 0x31C)
-#define SPEAR1340_PERIP3_SW_RST			(VA_MISC_BASE + 0x320)
-
-/* PCIE - SATA configuration registers */
-#define SPEAR1340_PCIE_SATA_CFG			(VA_MISC_BASE + 0x424)
-	/* PCIE CFG MASks */
-	#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT	(1 << 11)
-	#define SPEAR1340_PCIE_CFG_POWERUP_RESET	(1 << 10)
-	#define SPEAR1340_PCIE_CFG_CORE_CLK_EN		(1 << 9)
-	#define SPEAR1340_PCIE_CFG_AUX_CLK_EN		(1 << 8)
-	#define SPEAR1340_SATA_CFG_TX_CLK_EN		(1 << 4)
-	#define SPEAR1340_SATA_CFG_RX_CLK_EN		(1 << 3)
-	#define SPEAR1340_SATA_CFG_POWERUP_RESET	(1 << 2)
-	#define SPEAR1340_SATA_CFG_PM_CLK_EN		(1 << 1)
-	#define SPEAR1340_PCIE_SATA_SEL_PCIE		(0)
-	#define SPEAR1340_PCIE_SATA_SEL_SATA		(1)
-	#define SPEAR1340_SATA_PCIE_CFG_MASK		0xF1F
-	#define SPEAR1340_PCIE_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_PCIE | \
-			SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
-			SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
-			SPEAR1340_PCIE_CFG_POWERUP_RESET | \
-			SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
-	#define SPEAR1340_SATA_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_SATA | \
-			SPEAR1340_SATA_CFG_PM_CLK_EN | \
-			SPEAR1340_SATA_CFG_POWERUP_RESET | \
-			SPEAR1340_SATA_CFG_RX_CLK_EN | \
-			SPEAR1340_SATA_CFG_TX_CLK_EN)
-
-#define SPEAR1340_PCIE_MIPHY_CFG		(VA_MISC_BASE + 0x428)
-	#define SPEAR1340_MIPHY_OSC_BYPASS_EXT		(1 << 31)
-	#define SPEAR1340_MIPHY_CLK_REF_DIV2		(1 << 27)
-	#define SPEAR1340_MIPHY_CLK_REF_DIV4		(2 << 27)
-	#define SPEAR1340_MIPHY_CLK_REF_DIV8		(3 << 27)
-	#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)	(x << 0)
-	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
-			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
-			SPEAR1340_MIPHY_CLK_REF_DIV2 | \
-			SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
-	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
-			(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
-	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
-			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
-			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
-
-/* SATA device registration */
-static int sata_miphy_init(struct device *dev, void __iomem *addr)
-{
-	writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
-	writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
-			SPEAR1340_PCIE_MIPHY_CFG);
-	/* Switch on sata power domain */
-	writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
-	msleep(20);
-	/* Disable PCIE SATA Controller reset */
-	writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
-			SPEAR1340_PERIP1_SW_RST);
-	msleep(20);
-
-	return 0;
-}
-
-void sata_miphy_exit(struct device *dev)
-{
-	writel(0, SPEAR1340_PCIE_SATA_CFG);
-	writel(0, SPEAR1340_PCIE_MIPHY_CFG);
-
-	/* Enable PCIE SATA Controller reset */
-	writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
-			SPEAR1340_PERIP1_SW_RST);
-	msleep(20);
-	/* Switch off sata power domain */
-	writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
-	msleep(20);
-}
-
-int sata_suspend(struct device *dev)
-{
-	if (dev->power.power_state.event == PM_EVENT_FREEZE)
-		return 0;
-
-	sata_miphy_exit(dev);
-
-	return 0;
-}
-
-int sata_resume(struct device *dev)
-{
-	if (dev->power.power_state.event == PM_EVENT_THAW)
-		return 0;
-
-	return sata_miphy_init(dev, NULL);
-}
-
-static struct ahci_platform_data sata_pdata = {
-	.init = sata_miphy_init,
-	.exit = sata_miphy_exit,
-	.suspend = sata_suspend,
-	.resume = sata_resume,
-};
-
-/* Add SPEAr1340 auxdata to pass platform data */
-static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
-	OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
-			&sata_pdata),
-	{}
-};
 
 static void __init spear1340_dt_init(void)
 {
-	of_platform_populate(NULL, of_default_bus_match_table,
-			spear1340_auxdata_lookup, NULL);
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static const char * const spear1340_dt_board_compat[] = {
diff --git a/drivers/phy/phy-miphy40lp.c b/drivers/phy/phy-miphy40lp.c
index 3a9ada1..0ee1972 100644
--- a/drivers/phy/phy-miphy40lp.c
+++ b/drivers/phy/phy-miphy40lp.c
@@ -8,8 +8,10 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
+ * 04/02/2014: Adding support of SATA mode for SPEAr1340.
  */
 
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/kernel.h>
@@ -19,6 +21,60 @@
 #include <linux/phy/phy.h>
 #include <linux/regmap.h>
 
+/* SPEAr1340 Registers */
+/* Power Management Registers */
+#define SPEAR1340_PCM_CFG			0x100
+	#define SPEAR1340_PCM_CFG_SATA_POWER_EN		BIT(11)
+#define SPEAR1340_PCM_WKUP_CFG			0x104
+#define SPEAR1340_SWITCH_CTR			0x108
+
+#define SPEAR1340_PERIP1_SW_RST			0x318
+	#define SPEAR1340_PERIP1_SW_RSATA		BIT(12)
+#define SPEAR1340_PERIP2_SW_RST			0x31C
+#define SPEAR1340_PERIP3_SW_RST			0x320
+
+/* PCIE - SATA configuration registers */
+#define SPEAR1340_PCIE_SATA_CFG			0x424
+	/* PCIE CFG MASks */
+	#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT	BIT(11)
+	#define SPEAR1340_PCIE_CFG_POWERUP_RESET	BIT(10)
+	#define SPEAR1340_PCIE_CFG_CORE_CLK_EN		BIT(9)
+	#define SPEAR1340_PCIE_CFG_AUX_CLK_EN		BIT(8)
+	#define SPEAR1340_SATA_CFG_TX_CLK_EN		BIT(4)
+	#define SPEAR1340_SATA_CFG_RX_CLK_EN		BIT(3)
+	#define SPEAR1340_SATA_CFG_POWERUP_RESET	BIT(2)
+	#define SPEAR1340_SATA_CFG_PM_CLK_EN		BIT(1)
+	#define SPEAR1340_PCIE_SATA_SEL_PCIE		(0)
+	#define SPEAR1340_PCIE_SATA_SEL_SATA		(1)
+	#define SPEAR1340_PCIE_SATA_CFG_MASK		0xF1F
+	#define SPEAR1340_PCIE_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_PCIE | \
+			SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
+			SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
+			SPEAR1340_PCIE_CFG_POWERUP_RESET | \
+			SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
+	#define SPEAR1340_SATA_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_SATA | \
+			SPEAR1340_SATA_CFG_PM_CLK_EN | \
+			SPEAR1340_SATA_CFG_POWERUP_RESET | \
+			SPEAR1340_SATA_CFG_RX_CLK_EN | \
+			SPEAR1340_SATA_CFG_TX_CLK_EN)
+
+#define SPEAR1340_PCIE_MIPHY_CFG		0x428
+	#define SPEAR1340_MIPHY_OSC_BYPASS_EXT		BIT(31)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV2		BIT(27)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV4		(2 << 27)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV8		(3 << 27)
+	#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)	(x << 0)
+	#define SPEAR1340_PCIE_MIPHY_CFG_MASK		0xF80000FF
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
+			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+			SPEAR1340_MIPHY_CLK_REF_DIV2 | \
+			SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+			(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
+			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
+
 enum phy_mode {
 	SATA,
 	PCIE,
@@ -50,6 +106,93 @@ struct miphy40lp_priv {
 	struct miphy40lp_plat_ops	*plat_ops;
 };
 
+static int miphy40lp_spear1340_sata_init(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, SPEAR1340_SATA_CFG_VAL);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK,
+			SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK);
+	/* Switch on sata power domain */
+	regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
+			SPEAR1340_PCM_CFG_SATA_POWER_EN,
+			SPEAR1340_PCM_CFG_SATA_POWER_EN);
+	msleep(20);
+	/* Disable PCIE SATA Controller reset */
+	regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
+			SPEAR1340_PERIP1_SW_RSATA, 0);
+	msleep(20);
+
+	return 0;
+}
+
+static int miphy40lp_spear1340_sata_exit(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, 0);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
+
+	/* Enable PCIE SATA Controller reset */
+	regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
+			SPEAR1340_PERIP1_SW_RSATA,
+			SPEAR1340_PERIP1_SW_RSATA);
+	msleep(20);
+	/* Switch off sata power domain */
+	regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
+			SPEAR1340_PCM_CFG_SATA_POWER_EN, 0);
+	msleep(20);
+
+	return 0;
+}
+
+static int miphy40lp_spear1340_init(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_init(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1340_exit(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_exit(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1340_suspend(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_exit(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1340_resume(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_init(priv);
+
+	return ret;
+}
+
+static struct miphy40lp_plat_ops spear1340_phy_ops = {
+	.plat_init = miphy40lp_spear1340_init,
+	.plat_exit = miphy40lp_spear1340_exit,
+	.plat_suspend = miphy40lp_spear1340_suspend,
+	.plat_resume = miphy40lp_spear1340_resume,
+};
+
 static int miphy40lp_init(struct phy *phy)
 {
 	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
@@ -100,6 +243,7 @@ static int miphy40lp_power_on(struct phy *phy)
 
 static const struct of_device_id miphy40lp_of_match[] = {
 	{ .compatible = "st,miphy40lp-phy", .data = NULL },
+	{ .compatible = "st,spear1340-miphy", .data = &spear1340_phy_ops },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, miphy40lp_of_match);
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH V5 6/8] phy: st-miphy-40lp: Add SPEAr1310 and SPEAr1340 PCIe phy support
From: Mohit Kumar @ 2014-02-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1391871170.git.pratyush.anand@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

SPEAr1310 and SPEAr1340 uses miphy40lp phy for PCIe. This driver adds
support for the same.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Tested-by: Mohit Kumar <mohit.kumar@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/phy/phy-miphy40lp.c | 165 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 165 insertions(+)

diff --git a/drivers/phy/phy-miphy40lp.c b/drivers/phy/phy-miphy40lp.c
index 0ee1972..fe8535a 100644
--- a/drivers/phy/phy-miphy40lp.c
+++ b/drivers/phy/phy-miphy40lp.c
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  *
  * 04/02/2014: Adding support of SATA mode for SPEAr1340.
+ * 04/02/2014: Adding support of PCIe mode for SPEAr1340 and SPEAr1310
  */
 
 #include <linux/bitops.h>
@@ -74,6 +75,80 @@
 	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
 			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
 			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
+/* SPEAr1310 Registers */
+#define SPEAR1310_PCIE_SATA_CFG			0x3A4
+	#define SPEAR1310_PCIE_SATA2_SEL_PCIE		(0 << 31)
+	#define SPEAR1310_PCIE_SATA1_SEL_PCIE		(0 << 30)
+	#define SPEAR1310_PCIE_SATA0_SEL_PCIE		(0 << 29)
+	#define SPEAR1310_PCIE_SATA2_SEL_SATA		BIT(31)
+	#define SPEAR1310_PCIE_SATA1_SEL_SATA		BIT(30)
+	#define SPEAR1310_PCIE_SATA0_SEL_SATA		BIT(29)
+	#define SPEAR1310_SATA2_CFG_TX_CLK_EN		BIT(27)
+	#define SPEAR1310_SATA2_CFG_RX_CLK_EN		BIT(26)
+	#define SPEAR1310_SATA2_CFG_POWERUP_RESET	BIT(25)
+	#define SPEAR1310_SATA2_CFG_PM_CLK_EN		BIT(24)
+	#define SPEAR1310_SATA1_CFG_TX_CLK_EN		BIT(23)
+	#define SPEAR1310_SATA1_CFG_RX_CLK_EN		BIT(22)
+	#define SPEAR1310_SATA1_CFG_POWERUP_RESET	BIT(21)
+	#define SPEAR1310_SATA1_CFG_PM_CLK_EN		BIT(20)
+	#define SPEAR1310_SATA0_CFG_TX_CLK_EN		BIT(19)
+	#define SPEAR1310_SATA0_CFG_RX_CLK_EN		BIT(18)
+	#define SPEAR1310_SATA0_CFG_POWERUP_RESET	BIT(17)
+	#define SPEAR1310_SATA0_CFG_PM_CLK_EN		BIT(16)
+	#define SPEAR1310_PCIE2_CFG_DEVICE_PRESENT	BIT(11)
+	#define SPEAR1310_PCIE2_CFG_POWERUP_RESET	BIT(10)
+	#define SPEAR1310_PCIE2_CFG_CORE_CLK_EN		BIT(9)
+	#define SPEAR1310_PCIE2_CFG_AUX_CLK_EN		BIT(8)
+	#define SPEAR1310_PCIE1_CFG_DEVICE_PRESENT	BIT(7)
+	#define SPEAR1310_PCIE1_CFG_POWERUP_RESET	BIT(6)
+	#define SPEAR1310_PCIE1_CFG_CORE_CLK_EN		BIT(5)
+	#define SPEAR1310_PCIE1_CFG_AUX_CLK_EN		BIT(4)
+	#define SPEAR1310_PCIE0_CFG_DEVICE_PRESENT	BIT(3)
+	#define SPEAR1310_PCIE0_CFG_POWERUP_RESET	BIT(2)
+	#define SPEAR1310_PCIE0_CFG_CORE_CLK_EN		BIT(1)
+	#define SPEAR1310_PCIE0_CFG_AUX_CLK_EN		BIT(0)
+
+	#define SPEAR1310_PCIE_CFG_MASK(x) ((0xF << (x * 4)) | BIT((x + 29)))
+	#define SPEAR1310_SATA_CFG_MASK(x) ((0xF << (x * 4 + 16)) | \
+			BIT((x + 29)))
+	#define SPEAR1310_PCIE_CFG_VAL(x) \
+			(SPEAR1310_PCIE_SATA##x##_SEL_PCIE | \
+			SPEAR1310_PCIE##x##_CFG_AUX_CLK_EN | \
+			SPEAR1310_PCIE##x##_CFG_CORE_CLK_EN | \
+			SPEAR1310_PCIE##x##_CFG_POWERUP_RESET | \
+			SPEAR1310_PCIE##x##_CFG_DEVICE_PRESENT)
+	#define SPEAR1310_SATA_CFG_VAL(x) \
+			(SPEAR1310_PCIE_SATA##x##_SEL_SATA | \
+			SPEAR1310_SATA##x##_CFG_PM_CLK_EN | \
+			SPEAR1310_SATA##x##_CFG_POWERUP_RESET | \
+			SPEAR1310_SATA##x##_CFG_RX_CLK_EN | \
+			SPEAR1310_SATA##x##_CFG_TX_CLK_EN)
+
+#define SPEAR1310_PCIE_MIPHY_CFG_1		0x3A8
+	#define SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT	BIT(31)
+	#define SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2	BIT(28)
+	#define SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(x)	(x << 16)
+	#define SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT	BIT(15)
+	#define SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2	BIT(12)
+	#define SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(x)	(x << 0)
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_MASK (0xFFFF)
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK (0xFFFF << 16)
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA \
+			(SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 | \
+			SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(60) | \
+			SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 | \
+			SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(60))
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+			(SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(120))
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE \
+			(SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(25) | \
+			SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(25))
+
+#define SPEAR1310_PCIE_MIPHY_CFG_2		0x3AC
 
 enum phy_mode {
 	SATA,
@@ -146,12 +221,35 @@ static int miphy40lp_spear1340_sata_exit(struct miphy40lp_priv *priv)
 	return 0;
 }
 
+static int miphy40lp_spear1340_pcie_init(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK,
+			SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, SPEAR1340_PCIE_CFG_VAL);
+
+	return 0;
+}
+
+static int miphy40lp_spear1340_pcie_exit(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, 0);
+
+	return 0;
+}
+
 static int miphy40lp_spear1340_init(struct miphy40lp_priv *priv)
 {
 	int ret = 0;
 
 	if (priv->mode == SATA)
 		ret = miphy40lp_spear1340_sata_init(priv);
+	else if (priv->mode == PCIE)
+		ret = miphy40lp_spear1340_pcie_init(priv);
 
 	return ret;
 }
@@ -162,6 +260,8 @@ static int miphy40lp_spear1340_exit(struct miphy40lp_priv *priv)
 
 	if (priv->mode == SATA)
 		ret = miphy40lp_spear1340_sata_exit(priv);
+	else if (priv->mode == PCIE)
+		ret = miphy40lp_spear1340_pcie_exit(priv);
 
 	return ret;
 }
@@ -193,6 +293,70 @@ static struct miphy40lp_plat_ops spear1340_phy_ops = {
 	.plat_resume = miphy40lp_spear1340_resume,
 };
 
+static int miphy40lp_spear1310_pcie_init(struct miphy40lp_priv *priv)
+{
+	u32 val;
+
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
+			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK,
+			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE);
+
+	switch (priv->id) {
+	case 0:
+		val = SPEAR1310_PCIE_CFG_VAL(0);
+		break;
+	case 1:
+		val = SPEAR1310_PCIE_CFG_VAL(1);
+		break;
+	case 2:
+		val = SPEAR1310_PCIE_CFG_VAL(2);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
+			SPEAR1310_PCIE_CFG_MASK(priv->id), val);
+
+	return 0;
+}
+
+static int miphy40lp_spear1310_pcie_exit(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
+			SPEAR1310_PCIE_CFG_MASK(priv->id), 0);
+
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
+			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK, 0);
+
+	return 0;
+}
+
+static int miphy40lp_spear1310_init(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == PCIE)
+		ret = miphy40lp_spear1310_pcie_init(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1310_exit(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == PCIE)
+		ret = miphy40lp_spear1310_pcie_exit(priv);
+
+	return ret;
+}
+
+static struct miphy40lp_plat_ops spear1310_phy_ops = {
+	.plat_init = miphy40lp_spear1310_init,
+	.plat_exit = miphy40lp_spear1310_exit,
+};
+
 static int miphy40lp_init(struct phy *phy)
 {
 	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
@@ -244,6 +408,7 @@ static int miphy40lp_power_on(struct phy *phy)
 static const struct of_device_id miphy40lp_of_match[] = {
 	{ .compatible = "st,miphy40lp-phy", .data = NULL },
 	{ .compatible = "st,spear1340-miphy", .data = &spear1340_phy_ops },
+	{ .compatible = "st,spear1310-miphy", .data = &spear1310_phy_ops },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, miphy40lp_of_match);
-- 
1.8.1.2

^ permalink raw reply related

* [Update][PATCH 2/2] clocksource: Make clocksource register functions void
From: Preeti Murthy @ 2014-02-10  8:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391997515-57736-1-git-send-email-wangyijing@huawei.com>

Hi Yijing,

For the powerpc part:
 Acked-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>

On Mon, Feb 10, 2014 at 7:28 AM, Yijing Wang <wangyijing@huawei.com> wrote:
> Currently, clocksource_register() and __clocksource_register_scale()
> functions always return 0, it's pointless, make functions void.
> And remove the dead code that check the clocksource_register_hz()
> return value.
>
> Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
> Acked-by: Tony Prisk <linux@prisktech.co.nz>
> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
> ---
>  arch/arm/mach-davinci/time.c                    |    5 ++---
>  arch/arm/mach-msm/timer.c                       |    4 +---
>  arch/arm/mach-omap2/timer.c                     |    8 +++-----
>  arch/avr32/kernel/time.c                        |    4 +---
>  arch/blackfin/kernel/time-ts.c                  |    6 ++----
>  arch/microblaze/kernel/timer.c                  |    3 +--
>  arch/mips/jz4740/time.c                         |    6 +-----
>  arch/mips/loongson/common/cs5536/cs5536_mfgpt.c |    3 ++-
>  arch/openrisc/kernel/time.c                     |    3 +--
>  arch/powerpc/kernel/time.c                      |    6 +-----
>  arch/um/kernel/time.c                           |    6 +-----
>  arch/x86/platform/uv/uv_time.c                  |   14 ++++++--------
>  drivers/clocksource/acpi_pm.c                   |    3 ++-
>  drivers/clocksource/cadence_ttc_timer.c         |    6 +-----
>  drivers/clocksource/exynos_mct.c                |    4 +---
>  drivers/clocksource/i8253.c                     |    3 ++-
>  drivers/clocksource/mmio.c                      |    3 ++-
>  drivers/clocksource/samsung_pwm_timer.c         |    5 +----
>  drivers/clocksource/scx200_hrt.c                |    3 ++-
>  drivers/clocksource/tcb_clksrc.c                |    8 +-------
>  drivers/clocksource/timer-marco.c               |    2 +-
>  drivers/clocksource/timer-prima2.c              |    2 +-
>  drivers/clocksource/vt8500_timer.c              |    4 +---
>  include/linux/clocksource.h                     |    8 ++++----
>  kernel/time/clocksource.c                       |    6 ++----
>  kernel/time/jiffies.c                           |    3 ++-
>  26 files changed, 45 insertions(+), 83 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
> index 24ad30f..92b772f 100644
> --- a/arch/arm/mach-davinci/time.c
> +++ b/arch/arm/mach-davinci/time.c
> @@ -387,9 +387,8 @@ void __init davinci_timer_init(void)
>
>         /* setup clocksource */
>         clocksource_davinci.name = id_to_name[clocksource_id];
> -       if (clocksource_register_hz(&clocksource_davinci,
> -                                   davinci_clock_tick_rate))
> -               printk(err, clocksource_davinci.name);
> +       clocksource_register_hz(&clocksource_davinci,
> +                                   davinci_clock_tick_rate);
>
>         sched_clock_register(davinci_read_sched_clock, 32,
>                           davinci_clock_tick_rate);
> diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
> index fd16449..ab485bc 100644
> --- a/arch/arm/mach-msm/timer.c
> +++ b/arch/arm/mach-msm/timer.c
> @@ -226,9 +226,7 @@ static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
>
>  err:
>         writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
> -       res = clocksource_register_hz(cs, dgt_hz);
> -       if (res)
> -               pr_err("clocksource_register failed\n");
> +       clocksource_register_hz(cs, dgt_hz);
>         sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
>  }
>
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 74044aa..032e1da 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -473,11 +473,9 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
>                                    OMAP_TIMER_NONPOSTED);
>         sched_clock_register(dmtimer_read_sched_clock, 32, clksrc.rate);
>
> -       if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
> -               pr_err("Could not register clocksource %s\n",
> -                       clocksource_gpt.name);
> -       else
> -               pr_info("OMAP clocksource: %s at %lu Hz\n",
> +       clocksource_register_hz(&clocksource_gpt, clksrc.rate);
> +
> +       pr_info("OMAP clocksource: %s at %lu Hz\n",
>                         clocksource_gpt.name, clksrc.rate);
>  }
>
> diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c
> index d0f771b..51b4a66 100644
> --- a/arch/avr32/kernel/time.c
> +++ b/arch/avr32/kernel/time.c
> @@ -134,9 +134,7 @@ void __init time_init(void)
>
>         /* figure rate for counter */
>         counter_hz = clk_get_rate(boot_cpu_data.clk);
> -       ret = clocksource_register_hz(&counter, counter_hz);
> -       if (ret)
> -               pr_debug("timer: could not register clocksource: %d\n", ret);
> +       clocksource_register_hz(&counter, counter_hz);
>
>         /* setup COMPARE clockevent */
>         comparator.mult = div_sc(counter_hz, NSEC_PER_SEC, comparator.shift);
> diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
> index cb0a484..df3bb08 100644
> --- a/arch/blackfin/kernel/time-ts.c
> +++ b/arch/blackfin/kernel/time-ts.c
> @@ -51,8 +51,7 @@ static inline unsigned long long bfin_cs_cycles_sched_clock(void)
>
>  static int __init bfin_cs_cycles_init(void)
>  {
> -       if (clocksource_register_hz(&bfin_cs_cycles, get_cclk()))
> -               panic("failed to register clocksource");
> +       clocksource_register_hz(&bfin_cs_cycles, get_cclk());
>
>         return 0;
>  }
> @@ -103,8 +102,7 @@ static int __init bfin_cs_gptimer0_init(void)
>  {
>         setup_gptimer0();
>
> -       if (clocksource_register_hz(&bfin_cs_gptimer0, get_sclk()))
> -               panic("failed to register clocksource");
> +       clocksource_register_hz(&bfin_cs_gptimer0, get_sclk());
>
>         return 0;
>  }
> diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
> index fb0c614..5b8ec44 100644
> --- a/arch/microblaze/kernel/timer.c
> +++ b/arch/microblaze/kernel/timer.c
> @@ -213,8 +213,7 @@ static struct clocksource clocksource_microblaze = {
>
>  static int __init xilinx_clocksource_init(void)
>  {
> -       if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq))
> -               panic("failed to register clocksource");
> +       clocksource_register_hz(&clocksource_microblaze, timer_clock_freq);
>
>         /* stop timer1 */
>         out_be32(timer_baseaddr + TCSR1,
> diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
> index 5e430ce..041cdff 100644
> --- a/arch/mips/jz4740/time.c
> +++ b/arch/mips/jz4740/time.c
> @@ -105,7 +105,6 @@ static struct irqaction timer_irqaction = {
>
>  void __init plat_time_init(void)
>  {
> -       int ret;
>         uint32_t clk_rate;
>         uint16_t ctrl;
>
> @@ -121,10 +120,7 @@ void __init plat_time_init(void)
>
>         clockevents_register_device(&jz4740_clockevent);
>
> -       ret = clocksource_register_hz(&jz4740_clocksource, clk_rate);
> -
> -       if (ret)
> -               printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
> +       clocksource_register_hz(&jz4740_clocksource, clk_rate);
>
>         setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
>
> diff --git a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
> index c639b9d..9fa6d99 100644
> --- a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
> +++ b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
> @@ -208,7 +208,8 @@ int __init init_mfgpt_clocksource(void)
>         if (num_possible_cpus() > 1)    /* MFGPT does not scale! */
>                 return 0;
>
> -       return clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE);
> +       clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE);
> +       return 0;
>  }
>
>  arch_initcall(init_mfgpt_clocksource);
> diff --git a/arch/openrisc/kernel/time.c b/arch/openrisc/kernel/time.c
> index 7c52e94..3f789aa 100644
> --- a/arch/openrisc/kernel/time.c
> +++ b/arch/openrisc/kernel/time.c
> @@ -156,8 +156,7 @@ static struct clocksource openrisc_timer = {
>
>  static int __init openrisc_timer_init(void)
>  {
> -       if (clocksource_register_hz(&openrisc_timer, cpuinfo.clock_frequency))
> -               panic("failed to register clocksource");
> +       clocksource_register_hz(&openrisc_timer, cpuinfo.clock_frequency);
>
>         /* Enable the incrementer: 'continuous' mode with interrupt disabled */
>         mtspr(SPR_TTMR, SPR_TTMR_CR);
> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
> index b3dab20..2e66b6f 100644
> --- a/arch/powerpc/kernel/time.c
> +++ b/arch/powerpc/kernel/time.c
> @@ -792,11 +792,7 @@ static void __init clocksource_init(void)
>         else
>                 clock = &clocksource_timebase;
>
> -       if (clocksource_register_hz(clock, tb_ticks_per_sec)) {
> -               printk(KERN_ERR "clocksource: %s is already registered\n",
> -                      clock->name);
> -               return;
> -       }
> +       clocksource_register_hz(clock, tb_ticks_per_sec);
>
>         printk(KERN_INFO "clocksource: %s mult[%x] shift[%d] registered\n",
>                clock->name, clock->mult, clock->shift);
> diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
> index 117568d..2034b58 100644
> --- a/arch/um/kernel/time.c
> +++ b/arch/um/kernel/time.c
> @@ -92,11 +92,7 @@ static void __init setup_itimer(void)
>                 clockevent_delta2ns(60 * HZ, &itimer_clockevent);
>         itimer_clockevent.min_delta_ns =
>                 clockevent_delta2ns(1, &itimer_clockevent);
> -       err = clocksource_register_hz(&itimer_clocksource, USEC_PER_SEC);
> -       if (err) {
> -               printk(KERN_ERR "clocksource_register_hz returned %d\n", err);
> -               return;
> -       }
> +       clocksource_register_hz(&itimer_clocksource, USEC_PER_SEC);
>         clockevents_register_device(&itimer_clockevent);
>  }
>
> diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c
> index 5c86786..b963774 100644
> --- a/arch/x86/platform/uv/uv_time.c
> +++ b/arch/x86/platform/uv/uv_time.c
> @@ -379,15 +379,13 @@ static __init int uv_rtc_setup_clock(void)
>         if (!is_uv_system())
>                 return -ENODEV;
>
> -       rc = clocksource_register_hz(&clocksource_uv, sn_rtc_cycles_per_second);
> -       if (rc)
> -               printk(KERN_INFO "UV RTC clocksource failed rc %d\n", rc);
> -       else
> -               printk(KERN_INFO "UV RTC clocksource registered freq %lu MHz\n",
> -                       sn_rtc_cycles_per_second/(unsigned long)1E6);
> +       clocksource_register_hz(&clocksource_uv, sn_rtc_cycles_per_second);
> +
> +       pr_info("UV RTC clocksource registered freq %lu MHz\n",
> +               sn_rtc_cycles_per_second/(unsigned long)1E6);
>
> -       if (rc || !uv_rtc_evt_enable || x86_platform_ipi_callback)
> -               return rc;
> +       if (!uv_rtc_evt_enable || x86_platform_ipi_callback)
> +               return 0;
>
>         /* Setup and register clockevents */
>         rc = uv_rtc_allocate_timers();
> diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
> index 6eab889..ab1dc63 100644
> --- a/drivers/clocksource/acpi_pm.c
> +++ b/drivers/clocksource/acpi_pm.c
> @@ -218,8 +218,9 @@ static int __init init_acpi_pm_clocksource(void)
>                 return -ENODEV;
>         }
>
> -       return clocksource_register_hz(&clocksource_acpi_pm,
> +       clocksource_register_hz(&clocksource_acpi_pm,
>                                                 PMTMR_TICKS_PER_SEC);
> +       return 0;
>  }
>
>  /* We use fs_initcall because we want the PCI fixups to have run
> diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c
> index 63f176d..b9b56ed 100644
> --- a/drivers/clocksource/cadence_ttc_timer.c
> +++ b/drivers/clocksource/cadence_ttc_timer.c
> @@ -301,11 +301,7 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base)
>         __raw_writel(CNT_CNTRL_RESET,
>                      ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
>
> -       err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE);
> -       if (WARN_ON(err)) {
> -               kfree(ttccs);
> -               return;
> -       }
> +       clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE);
>
>         ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET;
>         sched_clock_register(ttc_sched_clock_read, 16, ttccs->ttc.freq / PRESCALE);
> diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
> index 48f76bc..fcb9454 100644
> --- a/drivers/clocksource/exynos_mct.c
> +++ b/drivers/clocksource/exynos_mct.c
> @@ -197,9 +197,7 @@ struct clocksource mct_frc = {
>  static void __init exynos4_clocksource_init(void)
>  {
>         exynos4_mct_frc_start(0, 0);
> -
> -       if (clocksource_register_hz(&mct_frc, clk_rate))
> -               panic("%s: can't register clocksource\n", mct_frc.name);
> +       clocksource_register_hz(&mct_frc, clk_rate);
>  }
>
>  static void exynos4_mct_comp0_stop(void)
> diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c
> index 14ee3ef..9c45f0a 100644
> --- a/drivers/clocksource/i8253.c
> +++ b/drivers/clocksource/i8253.c
> @@ -95,7 +95,8 @@ static struct clocksource i8253_cs = {
>
>  int __init clocksource_i8253_init(void)
>  {
> -       return clocksource_register_hz(&i8253_cs, PIT_TICK_RATE);
> +       clocksource_register_hz(&i8253_cs, PIT_TICK_RATE);
> +       return 0;
>  }
>  #endif
>
> diff --git a/drivers/clocksource/mmio.c b/drivers/clocksource/mmio.c
> index c0e2512..6e0b530 100644
> --- a/drivers/clocksource/mmio.c
> +++ b/drivers/clocksource/mmio.c
> @@ -69,5 +69,6 @@ int __init clocksource_mmio_init(void __iomem *base, const char *name,
>         cs->clksrc.mask = CLOCKSOURCE_MASK(bits);
>         cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
>
> -       return clocksource_register_hz(&cs->clksrc, hz);
> +       clocksource_register_hz(&cs->clksrc, hz);
> +       return 0;
>  }
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 5645cfc..c59292f 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -340,7 +340,6 @@ static void __init samsung_clocksource_init(void)
>  {
>         unsigned long pclk;
>         unsigned long clock_rate;
> -       int ret;
>
>         pclk = clk_get_rate(pwm.timerclk);
>
> @@ -361,9 +360,7 @@ static void __init samsung_clocksource_init(void)
>                                                 pwm.variant.bits, clock_rate);
>
>         samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits);
> -       ret = clocksource_register_hz(&samsung_clocksource, clock_rate);
> -       if (ret)
> -               panic("samsung_clocksource_timer: can't register clocksource\n");
> +       clocksource_register_hz(&samsung_clocksource, clock_rate);
>  }
>
>  static void __init samsung_timer_resources(void)
> diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c
> index 64f9e82..57bdc04 100644
> --- a/drivers/clocksource/scx200_hrt.c
> +++ b/drivers/clocksource/scx200_hrt.c
> @@ -83,7 +83,8 @@ static int __init init_hrt_clocksource(void)
>
>         pr_info("enabling scx200 high-res timer (%s MHz +%d ppm)\n", mhz27 ? "27":"1", ppm);
>
> -       return clocksource_register_hz(&cs_hrt, freq);
> +       clocksource_register_hz(&cs_hrt, freq);
> +       return 0;
>  }
>
>  module_init(init_hrt_clocksource);
> diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
> index 00fdd11..805245d 100644
> --- a/drivers/clocksource/tcb_clksrc.c
> +++ b/drivers/clocksource/tcb_clksrc.c
> @@ -340,9 +340,7 @@ static int __init tcb_clksrc_init(void)
>         }
>
>         /* and away we go! */
> -       ret = clocksource_register_hz(&clksrc, divided_rate);
> -       if (ret)
> -               goto err_disable_t1;
> +       clocksource_register_hz(&clksrc, divided_rate);
>
>         /* channel 2:  periodic and oneshot timer support */
>         ret = setup_clkevents(tc, clk32k_divisor_idx);
> @@ -354,10 +352,6 @@ static int __init tcb_clksrc_init(void)
>  err_unregister_clksrc:
>         clocksource_unregister(&clksrc);
>
> -err_disable_t1:
> -       if (!tc->tcb_config || tc->tcb_config->counter_width != 32)
> -               clk_disable_unprepare(tc->clk[1]);
> -
>  err_disable_t0:
>         clk_disable_unprepare(t0_clk);
>
> diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c
> index 09a17d9..ae78ce0 100644
> --- a/drivers/clocksource/timer-marco.c
> +++ b/drivers/clocksource/timer-marco.c
> @@ -283,7 +283,7 @@ static void __init sirfsoc_marco_timer_init(void)
>         /* Clear all interrupts */
>         writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
>
> -       BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
> +       clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE);
>
>         sirfsoc_clockevent_init();
>  }
> diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c
> index 8a492d3..c9cc307 100644
> --- a/drivers/clocksource/timer-prima2.c
> +++ b/drivers/clocksource/timer-prima2.c
> @@ -204,7 +204,7 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np)
>         writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
>         writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
>
> -       BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
> +       clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE);
>
>         sched_clock_register(sirfsoc_read_sched_clock, 64, CLOCK_TICK_RATE);
>
> diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c
> index 1098ed3..13f5fa4 100644
> --- a/drivers/clocksource/vt8500_timer.c
> +++ b/drivers/clocksource/vt8500_timer.c
> @@ -150,9 +150,7 @@ static void __init vt8500_timer_init(struct device_node *np)
>         writel(0xf, regbase + TIMER_STATUS_VAL);
>         writel(~0, regbase + TIMER_MATCH_VAL);
>
> -       if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ))
> -               pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n",
> -                                       __func__, clocksource.name);
> +       clocksource_register_hz(&clocksource, VT8500_TIMER_HZ);
>
>         clockevent.cpumask = cpumask_of(0);
>
> diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
> index 67301a4..5a17c5e 100644
> --- a/include/linux/clocksource.h
> +++ b/include/linux/clocksource.h
> @@ -282,7 +282,7 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
>  }
>
>
> -extern int clocksource_register(struct clocksource*);
> +extern void clocksource_register(struct clocksource *);
>  extern int clocksource_unregister(struct clocksource*);
>  extern void clocksource_touch_watchdog(void);
>  extern struct clocksource* clocksource_get_next(void);
> @@ -301,17 +301,17 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
>   * Don't call __clocksource_register_scale directly, use
>   * clocksource_register_hz/khz
>   */
> -extern int
> +extern void
>  __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
>  extern void
>  __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
>
> -static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
> +static inline void clocksource_register_hz(struct clocksource *cs, u32 hz)
>  {
>         return __clocksource_register_scale(cs, 1, hz);
>  }
>
> -static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
> +static inline void clocksource_register_khz(struct clocksource *cs, u32 khz)
>  {
>         return __clocksource_register_scale(cs, 1000, khz);
>  }
> diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
> index 9951575..686ff72 100644
> --- a/kernel/time/clocksource.c
> +++ b/kernel/time/clocksource.c
> @@ -782,7 +782,7 @@ EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
>   * This *SHOULD NOT* be called directly! Please use the
>   * clocksource_register_hz() or clocksource_register_khz helper functions.
>   */
> -int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
> +void __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
>  {
>
>         /* Initialize mult/shift and max_idle_ns */
> @@ -794,7 +794,6 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
>         clocksource_enqueue_watchdog(cs);
>         clocksource_select();
>         mutex_unlock(&clocksource_mutex);
> -       return 0;
>  }
>  EXPORT_SYMBOL_GPL(__clocksource_register_scale);
>
> @@ -804,7 +803,7 @@ EXPORT_SYMBOL_GPL(__clocksource_register_scale);
>   * @cs:                clocksource to be registered
>   *
>   */
> -int clocksource_register(struct clocksource *cs)
> +void clocksource_register(struct clocksource *cs)
>  {
>         /* calculate max adjustment for given mult/shift */
>         cs->maxadj = clocksource_max_adjustment(cs);
> @@ -820,7 +819,6 @@ int clocksource_register(struct clocksource *cs)
>         clocksource_enqueue_watchdog(cs);
>         clocksource_select();
>         mutex_unlock(&clocksource_mutex);
> -       return 0;
>  }
>  EXPORT_SYMBOL(clocksource_register);
>
> diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
> index 7a925ba..ae4c534 100644
> --- a/kernel/time/jiffies.c
> +++ b/kernel/time/jiffies.c
> @@ -88,7 +88,8 @@ EXPORT_SYMBOL(jiffies);
>
>  static int __init init_jiffies_clocksource(void)
>  {
> -       return clocksource_register(&clocksource_jiffies);
> +       clocksource_register(&clocksource_jiffies);
> +       return 0;
>  }
>
>  core_initcall(init_jiffies_clocksource);
> --
> 1.7.1
>
>
> --
> 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

* [RFC PATCH] ARM: Add imprecise abort enable/disable macro
From: Ben Dooks @ 2014-02-10  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F892C8.80508@st.com>

On 10/02/14 08:50, Fabrice Gasnier wrote:
> On 02/07/2014 06:09 PM, Will Deacon wrote:
>> On Fri, Feb 07, 2014 at 04:19:15PM +0000, Fabrice GASNIER wrote:
>>> This patch adds imprecise abort enable/disable macros.
>>> It also enables imprecise aborts when starting kernel.
>>>
>>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>>> ---
>>>   arch/arm/include/asm/irqflags.h |   33
>>> +++++++++++++++++++++++++++++++++
>>>   arch/arm/kernel/smp.c           |    1 +
>>>   arch/arm/kernel/traps.c         |    4 ++++
>>>   3 files changed, 38 insertions(+)
>>>
>>> diff --git a/arch/arm/include/asm/irqflags.h
>>> b/arch/arm/include/asm/irqflags.h
>>> index 3b763d6..82e3834 100644
>>> --- a/arch/arm/include/asm/irqflags.h
>>> +++ b/arch/arm/include/asm/irqflags.h
>>> @@ -51,6 +51,9 @@ static inline void arch_local_irq_disable(void)
>>>   #define local_fiq_enable()  __asm__("cpsie f    @ __stf" : : :
>>> "memory", "cc")
>>>   #define local_fiq_disable() __asm__("cpsid f    @ __clf" : : :
>>> "memory", "cc")
>>> +
>>> +#define local_abt_enable()  __asm__("cpsie a    @ __sta" : : :
>>> "memory", "cc")
>>> +#define local_abt_disable() __asm__("cpsid a    @ __cla" : : :
>>> "memory", "cc")
>>>   #else
>>>   /*
>>> @@ -130,6 +133,36 @@ static inline void arch_local_irq_disable(void)
>>>       : "memory", "cc");                    \
>>>       })
>>> +/*
>>> + * Enable Aborts
>>> + */
>>> +#define local_abt_enable()                    \
>>> +    ({                            \
>>> +        unsigned long temp;                \
>>> +    __asm__ __volatile__(                    \
>>> +    "mrs    %0, cpsr        @ sta\n"        \
>>> +"    bic    %0, %0, %1\n"                    \
>>> +"    msr    cpsr_c, %0"                    \
>>> +    : "=r" (temp)                        \
>>> +    : "r" (PSR_A_BIT)                    \
>> Can you use "i" instead of a register for this constant?
> Hi,
>
> Sure, I will change it in a future patch.
>>
>>> +    : "memory", "cc");                    \
>> You don't need the "cc" clobber.
> That surprises me: I think "orr" and "bic" instruction might change N
> and Z bits, depending on the result.
> So shouldn't "cc" be placed here ?
> I also see that it is used in local_fiq_enable/disable macros just
> above, that are similar:

No, only if they have the S flag set on the instruction (ORRS,BICS)


-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply

* [PATCH v3 2/7] clk: samsung: add infrastructure to register cpu clocks
From: Lukasz Majewski @ 2014-02-10  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391788548-13056-3-git-send-email-thomas.ab@samsung.com>

Hi Thomas,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> The CPU clock provider supplies the clock to the CPU clock domain. The
> composition and organization of the CPU clock provider could vary
> among Exynos SoCs. A CPU clock provider can be composed of clock mux,
> dividers and gates. This patch defines a new clock type for CPU clock
> provider and adds infrastructure to register the CPU clock providers
> for Samsung platforms.
> 
> In addition to this, the arm cpu clock provider for Exynos4210 and
> compatible SoCs is instantiated using the new cpu clock type. The
> clock configuration data for this clock is obtained from device tree.

I'm a bit confused with the sentence:

> This implementation is reusable for Exynos4x12 and Exynos5250 SoCs as
> well.

It seems that the implementation for Exynos4210 is already reused in
this code for Exynos4412. 

Is the name convention of exynos4210_* after the first SoC supporting
such setup? If yes, I think that it could be explicitly written in the
commit message.

Additionally, the above commit message could also emphasis, that the
implementation for other Exynos4 SoCs (like Exynos4412) is already
in place.


> 
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
>  drivers/clk/samsung/Makefile  |    2 +-
>  drivers/clk/samsung/clk-cpu.c |  409
> +++++++++++++++++++++++++++++++++++++++++
> drivers/clk/samsung/clk.h     |    5 + 3 files changed, 415
> insertions(+), 1 deletion(-) create mode 100644
> drivers/clk/samsung/clk-cpu.c
> 
> diff --git a/drivers/clk/samsung/Makefile
> b/drivers/clk/samsung/Makefile index 8eb4799..e2b453f 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -2,7 +2,7 @@
>  # Samsung Clock specific Makefile
>  #
>  
> -obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-pll.o
> +obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-pll.o clk-cpu.o
>  obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
>  obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
>  obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
> diff --git a/drivers/clk/samsung/clk-cpu.c
> b/drivers/clk/samsung/clk-cpu.c new file mode 100644
> index 0000000..673f620
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-cpu.c
> @@ -0,0 +1,409 @@
> +/*
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or
> modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file contains the utility functions to register the cpu
> clocks
> + * for samsung platforms.
> +*/
> +
> +#include <linux/errno.h>
> +#include "clk.h"
> +
> +#define SRC_CPU			0x0
> +#define STAT_CPU		0x200
> +#define DIV_CPU0		0x300
> +#define DIV_CPU1		0x304
> +#define DIV_STAT_CPU0		0x400
> +#define DIV_STAT_CPU1		0x404
> +
> +#define MAX_DIV			8
> +
> +#define EXYNOS4210_ARM_DIV1(base) ((readl(base + DIV_CPU0) & 0xf) +
> 1) +#define EXYNOS4210_ARM_DIV2(base) (((readl(base + DIV_CPU0) >>
> 28) & 0xf) + 1) +
> +#define EXYNOS4210_DIV_CPU0(d5, d4, d3, d2, d1,
> d0)			\
> +		((d5 << 24) | (d4 << 20) | (d3 << 16) | (d2 << 12)
> |	\
> +		 (d1 << 8) | (d0 <<  4))
> +#define EXYNOS4210_DIV_CPU1(d2, d1,
> d0)					\
> +		((d2 << 8) | (d1 << 4) | (d0 << 0))
> +
> +#define EXYNOS4210_DIV1_HPM_MASK	((0x7 << 0) | (0x7 << 4))
> +#define EXYNOS4210_MUX_HPM_MASK		(1 << 20)
> +
> +/**
> + * struct exynos4210_armclk_data: config data to setup exynos4210
> cpu clocks.
> + * @prate:	frequency of the parent clock.
> + * @div0:	value to be programmed in the div_cpu0 register.
> + * @div1:	value to be programmed in the div_cpu1 register.
> + *
> + * This structure holds the divider configuration data for divider
> clocks
> + * belonging to the CMU_CPU clock domain. The parent frequency at
> which these
> + * divider values are vaild is specified in @prate.
> + */
> +struct exynos4210_armclk_data {
> +	unsigned long	prate;
> +	unsigned int	div0;
> +	unsigned int	div1;
> +};
> +
> +/**
> + * struct samsung_cpuclk: information about clock supplied to a CPU
> core.
> + * @hw:		handle between ccf and cpu clock.
> + * @alt_parent:	alternate parent clock to use when switching
> the speed
> + *		of the primary parent clock.
> + * @ctrl_base:	base address of the clock controller.
> + * @offset:	offset from the ctrl_base address where the cpu
> clock div/mux
> + *		registers can be accessed.
> + * @clk_nb:	clock notifier registered for changes in clock
> speed of the
> + *		primary parent clock.
> + * @data:	optional data which the acutal instantiation of
> this clock
> + *		can use.
> + */
> +struct samsung_cpuclk {
> +	struct clk_hw		hw;
> +	struct clk		*alt_parent;
> +	void __iomem		*ctrl_base;
> +	unsigned long		offset;
> +	struct notifier_block	clk_nb;
> +	void			*data;
> +};
> +
> +#define to_samsung_cpuclk_hw(hw) container_of(hw, struct
> samsung_cpuclk, hw) +#define to_samsung_cpuclk_nb(nb)
> container_of(nb, struct samsung_cpuclk, clk_nb) +
> +/**
> + * struct samsung_cpuclk_soc_data: soc specific data for cpu clocks.
> + * @parser:	pointer to a function that can parse SoC specific
> data.
> + * @ops:	clock operations to be used for this clock.
> + * @offset:	optional offset from base of clock controller
> register base, to
> + *		be used when accessing clock controller registers
> related to the
> + *		cpu clock.
> + * @clk_cb:	the clock notifier callback to be called for
> changes in the
> + *		clock rate of the primary parent clock.
> + *
> + * This structure provides SoC specific data for ARM clocks. Based on
> + * the compatible value of the clock controller node, the value of
> the
> + * fields in this structure can be populated.
> + */
> +struct samsung_cpuclk_soc_data {
> +	int (*parser)(struct device_node *, void **);
> +	const struct clk_ops *ops;
> +	unsigned int offset;
> +	int (*clk_cb)(struct notifier_block *nb, unsigned long evt,
> void *data); +};
> +
> +/* common round rate callback useable for all types of cpu clocks */
> +static long samsung_cpuclk_round_rate(struct clk_hw *hw,
> +			unsigned long drate, unsigned long *prate)
> +{
> +	struct clk *parent = __clk_get_parent(hw->clk);
> +	unsigned long max_prate = __clk_round_rate(parent, UINT_MAX);
> +	unsigned long t_prate, best_div = 1;
> +	unsigned long delta, min_delta = UINT_MAX;
> +
> +	do {
> +		t_prate = __clk_round_rate(parent, drate * best_div);
> +		delta = drate - (t_prate / best_div);
> +		if (delta < min_delta) {
> +			*prate = t_prate;
> +			min_delta = delta;
> +		}
> +		if (!delta)
> +			break;
> +		best_div++;
> +	} while ((drate * best_div) < max_prate && best_div <=
> MAX_DIV); +
> +	return t_prate / best_div;
> +}
> +
> +static unsigned long _calc_div(unsigned long prate, unsigned long
> drate) +{
> +	unsigned long div = prate / drate;
> +
> +	WARN_ON(div >= MAX_DIV);
> +	return (!(prate % drate)) ? div-- : div;
> +}
> +
> +/* helper function to register a cpu clock */
> +static int __init samsung_cpuclk_register(unsigned int lookup_id,
> +		const char *name, const char **parents,
> +		unsigned int num_parents, void __iomem *base,
> +		const struct samsung_cpuclk_soc_data *soc_data,
> +		struct device_node *np, const struct clk_ops *ops)
> +{
> +	struct samsung_cpuclk *cpuclk;
> +	struct clk_init_data init;
> +	struct clk *clk;
> +	int ret;
> +
> +	cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
> +	if (!cpuclk) {
> +		pr_err("%s: could not allocate memory for %s
> clock\n",
> +					__func__, name);
> +		return -ENOMEM;
> +	}
> +
> +	init.name = name;
> +	init.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT;
> +	init.parent_names = parents;
> +	init.num_parents = 1;
> +	init.ops = ops;
> +
> +	cpuclk->hw.init = &init;
> +	cpuclk->ctrl_base = base;
> +
> +	if (soc_data && soc_data->parser) {
> +		ret = soc_data->parser(np, &cpuclk->data);
> +		if (ret) {
> +			pr_err("%s: error %d in parsing %s clock
> data",
> +					__func__, ret, name);
> +			ret = -EINVAL;
> +			goto free_cpuclk;
> +		}
> +		cpuclk->offset = soc_data->offset;
> +		init.ops = soc_data->ops;
> +	}
> +
> +	if (soc_data && soc_data->clk_cb) {
> +		cpuclk->clk_nb.notifier_call = soc_data->clk_cb;
> +		if (clk_notifier_register(__clk_lookup(parents[0]),
> +				&cpuclk->clk_nb)) {
> +			pr_err("%s: failed to register clock
> notifier for %s\n",
> +					__func__, name);
> +			goto free_cpuclk_data;
> +		}
> +	}
> +
> +	if (num_parents == 2) {
> +		cpuclk->alt_parent = __clk_lookup(parents[1]);
> +		if (!cpuclk->alt_parent) {
> +			pr_err("%s: could not lookup alternate
> parent %s\n",
> +					__func__, parents[1]);
> +			ret = -EINVAL;
> +			goto free_cpuclk_data;
> +		}
> +	}
> +
> +	clk = clk_register(NULL, &cpuclk->hw);
> +	if (IS_ERR(clk)) {
> +		pr_err("%s: could not register cpuclk %s\n",
> __func__,	name);
> +		ret = PTR_ERR(clk);
> +		goto free_cpuclk_data;
> +	}
> +
> +	samsung_clk_add_lookup(clk, lookup_id);
> +	return 0;
> +
> +free_cpuclk_data:
> +	kfree(cpuclk->data);
> +free_cpuclk:
> +	kfree(cpuclk);
> +	return ret;
> +}
> +
> +static inline void _exynos4210_set_armclk_div(void __iomem *base,
> +			unsigned long div)
> +{
> +	writel((readl(base + DIV_CPU0) & ~0xf) | div, base +
> DIV_CPU0);
> +	while (readl(base + DIV_STAT_CPU0) != 0)
> +		;
> +}
> +
> +static unsigned long exynos4210_armclk_recalc_rate(struct clk_hw *hw,
> +				unsigned long parent_rate)
> +{
> +	struct samsung_cpuclk *armclk = to_samsung_cpuclk_hw(hw);
> +	void __iomem *base = armclk->ctrl_base + armclk->offset;
> +
> +	return parent_rate / EXYNOS4210_ARM_DIV1(base) /
> +				EXYNOS4210_ARM_DIV2(base);
> +}
> +
> +/*
> + * This clock notifier is called when the frequency of the parent
> clock
> + * of armclk is to be changed. This notifier handles the setting up
> all
> + * the divider clocks, remux to temporary parent and handling the
> safe
> + * frequency levels when using temporary parent.
> + */
> +static int exynos4210_armclk_notifier_cb(struct notifier_block *nb,
> +				unsigned long event, void *data)
> +{
> +	struct clk_notifier_data *ndata = data;
> +	struct samsung_cpuclk *armclk = to_samsung_cpuclk_nb(nb);
> +	struct exynos4210_armclk_data *armclk_data;
> +	unsigned long alt_prate, alt_div, div0, div1, mux_reg;
> +	void __iomem *base;
> +	bool need_safe_freq;
> +
> +	armclk_data = armclk->data;
> +	base = armclk->ctrl_base + armclk->offset;
> +	alt_prate = clk_get_rate(armclk->alt_parent);
> +
> +	if (event == POST_RATE_CHANGE)
> +		goto e4210_armclk_post_rate_change;
> +
> +	/* pre-rate change. find out the divider values to use for
> clock data */
> +	while (armclk_data->prate != ndata->new_rate) {
> +		if (armclk_data->prate == 0)
> +			return NOTIFY_BAD;
> +		armclk_data++;
> +	}
> +
> +	div0 = armclk_data->div0;
> +	div1 = armclk_data->div1;
> +	if (readl(base + SRC_CPU) & EXYNOS4210_MUX_HPM_MASK) {
> +		div1 = readl(base + DIV_CPU1) &
> EXYNOS4210_DIV1_HPM_MASK;
> +		div1 |= ((armclk_data->div1) &
> ~EXYNOS4210_DIV1_HPM_MASK);
> +	}
> +
> +	/*
> +	 * if the new and old parent clock speed is less than the
> clock speed
> +	 * of the alternate parent, then it should be ensured that
> at no point
> +	 * the armclk speed is more than the old_prate until the
> dividers are
> +	 * set.
> +	 */
> +	need_safe_freq = ndata->old_rate < alt_prate &&
> +				ndata->new_rate < alt_prate;
> +	if (need_safe_freq) {
> +		alt_div = _calc_div(alt_prate, ndata->old_rate);
> +		_exynos4210_set_armclk_div(base, alt_div);
> +		div0 |= alt_div;
> +	}
> +
> +	mux_reg = readl(base + SRC_CPU);
> +	writel(mux_reg | (1 << 16), base + SRC_CPU);
> +	while (((readl(base + STAT_CPU) >> 16) & 0x7) != 2)
> +		;
> +
> +	writel(div0, base + DIV_CPU0);
> +	while (readl(base + DIV_STAT_CPU0) != 0)
> +		;
> +	writel(div1, base + DIV_CPU1);
> +	while (readl(base + DIV_STAT_CPU1) != 0)
> +		;
> +	return NOTIFY_OK;
> +
> +e4210_armclk_post_rate_change:
> +	/* post-rate change event, re-mux back to primary parent */
> +	mux_reg = readl(base + SRC_CPU);
> +	writel(mux_reg & ~(1 << 16), base + SRC_CPU);
> +	while (((readl(base + STAT_CPU) >> 16) & 0x7) != 1)
> +			;
> +
> +	return NOTIFY_OK;
> +}
> +
> +static int exynos4210_armclk_set_rate(struct clk_hw *hw, unsigned
> long drate,
> +					unsigned long prate)
> +{
> +	struct samsung_cpuclk *armclk = to_samsung_cpuclk_hw(hw);
> +	void __iomem *base = armclk->ctrl_base + armclk->offset;
> +	unsigned long div;
> +
> +	div = drate < prate ? _calc_div(prate, drate) : 0;
> +	_exynos4210_set_armclk_div(base, div);
> +	return 0;
> +}
> +
> +static const struct clk_ops exynos4210_armclk_clk_ops = {
> +	.recalc_rate = exynos4210_armclk_recalc_rate,
> +	.round_rate = samsung_cpuclk_round_rate,
> +	.set_rate = exynos4210_armclk_set_rate,
> +};
> +
> +/*
> + * parse divider configuration data from dt for all the cpu clock
> domain
> + * clocks in exynos4210 and compatible SoC's.
> + */
> +static int __init exynos4210_armclk_parser(struct device_node *np,
> void **data) +{
> +	struct exynos4210_armclk_data *tdata;
> +	unsigned long cfg[10], row, col;
> +	const struct property *prop;
> +	const __be32 *val;
> +	u32 cells;
> +	int ret;
> +
> +	if (of_property_read_u32(np, "samsung,armclk-cells", &cells))
> +		return -EINVAL;
> +	prop = of_find_property(np, "samsung,armclk-divider-table",
> NULL);
> +	if (!prop)
> +		return -EINVAL;
> +	if (!prop->value)
> +		return -EINVAL;
> +	if ((prop->length / sizeof(u32)) % cells)
> +		return -EINVAL;
> +	row = ((prop->length / sizeof(u32)) / cells) + 1;
> +
> +	*data = kzalloc(sizeof(*tdata) * row, GFP_KERNEL);
> +	if (!*data)
> +		ret = -ENOMEM;
> +	tdata = *data;
> +
> +	val = prop->value;
> +	for (; row > 1; row--, tdata++) {
> +		for (col = 0; col < cells; col++)
> +			cfg[col] = be32_to_cpup(val++);
> +
> +		tdata->prate = cfg[0] * 1000;
> +		tdata->div0 = EXYNOS4210_DIV_CPU0(cfg[6], cfg[5],
> cfg[4],
> +						cfg[3], cfg[2],
> cfg[1]);
> +		tdata->div1 = cells == 10 ?
> +				EXYNOS4210_DIV_CPU1(cfg[9], cfg[8],
> cfg[7]) :
> +				EXYNOS4210_DIV_CPU1(0, cfg[8],
> cfg[7]);
> +	}
> +	tdata->prate = 0;
> +	return 0;
> +}
> +
> +static const struct samsung_cpuclk_soc_data
> exynos4210_cpuclk_soc_data = {
> +	.parser = exynos4210_armclk_parser,
> +	.ops = &exynos4210_armclk_clk_ops,
> +	.offset = 0x14200,
> +	.clk_cb = exynos4210_armclk_notifier_cb,
> +};
> +
> +static const struct samsung_cpuclk_soc_data
> exynos5250_cpuclk_soc_data = {
> +	.parser = exynos4210_armclk_parser,
> +	.ops = &exynos4210_armclk_clk_ops,
> +	.offset = 0x200,
> +	.clk_cb = exynos4210_armclk_notifier_cb,
> +};
> +
> +static const struct of_device_id samsung_clock_ids_armclk[] = {
> +	{ .compatible = "samsung,exynos4210-clock",
> +			.data = &exynos4210_cpuclk_soc_data, },
> +	{ .compatible = "samsung,exynos4412-clock",
> +			.data = &exynos4210_cpuclk_soc_data, },
> +	{ .compatible = "samsung,exynos5250-clock",
> +			.data = &exynos5250_cpuclk_soc_data, },
> +	{ },
> +};
> +
> +/**
> + * samsung_register_arm_clock: register arm clock with ccf.
> + * @lookup_id: armclk clock output id for the clock controller.
> + * @parent: name of the parent clock for armclk.
> + * @base: base address of the clock controller from which armclk is
> generated.
> + * @np: device tree node pointer of the clock controller (optional).
> + * @ops: clock ops for this clock (optional)
> + */
> +int __init samsung_register_arm_clock(unsigned int lookup_id,
> +		const char **parent_names, unsigned int num_parents,
> +		void __iomem *base, struct device_node *np, struct
> clk_ops *ops) +{
> +	const struct of_device_id *match;
> +	const struct samsung_cpuclk_soc_data *data = NULL;
> +
> +	if (np) {
> +		match = of_match_node(samsung_clock_ids_armclk, np);
> +		data = match ? match->data : NULL;
> +	}
> +
> +	return samsung_cpuclk_register(lookup_id, "armclk",
> parent_names,
> +			num_parents, base, data, np, ops);
> +}
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index 31b4174..5459856 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -340,4 +340,9 @@ extern void __init
> samsung_clk_register_pll(struct samsung_pll_clock *pll_list, 
>  extern unsigned long _get_rate(const char *clk_name);
>  
> +int __init samsung_register_arm_clock(unsigned int lookup_id,
> +		const char **parent_names, unsigned int num_parents,
> +		void __iomem *base, struct device_node *np,
> +		struct clk_ops *ops);
> +
>  #endif /* __SAMSUNG_CLK_H */

Rest of the code seems OK.

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH v2] ARM: at91: add Atmel's SAMA5D3 Xplained board
From: Nicolas Ferre @ 2014-02-10  9:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140207171948.GB9558@ns203013.ovh.net>

On 07/02/2014 18:19, Jean-Christophe PLAGNIOL-VILLARD :
> On 15:37 Fri 07 Feb     , Nicolas Ferre wrote:
>> On 07/02/2014 09:01, Jean-Christophe PLAGNIOL-VILLARD :
>>> On 09:35 Wed 05 Feb     , Nicolas Ferre wrote:
>>>> Add DT file for new SAMA5D3 Xpained board.
>>>> This board is based on Atmel's SAMA5D36 Cortex-A5 SoC.
>>>>
>>>> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
>>>> ---
>>>>  arch/arm/boot/dts/Makefile                  |   1 +
>>>>  arch/arm/boot/dts/at91-sama5d3_xplained.dts | 233 ++++++++++++++++++++++++++++
>>>>  2 files changed, 234 insertions(+)
>>>>  create mode 100644 arch/arm/boot/dts/at91-sama5d3_xplained.dts
>>>>
>>>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>>>> index b9d6a8b485e0..6d1e43d46187 100644
>>>> --- a/arch/arm/boot/dts/Makefile
>>>> +++ b/arch/arm/boot/dts/Makefile
>>>> @@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
>>>>  dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
>>>>  dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
>>>>  # sama5d3
>>>> +dtb-$(CONFIG_ARCH_AT91)	+= at91-sama5d3_xplained.dtb
>>>>  dtb-$(CONFIG_ARCH_AT91)	+= sama5d31ek.dtb
>>>>  dtb-$(CONFIG_ARCH_AT91)	+= sama5d33ek.dtb
>>>>  dtb-$(CONFIG_ARCH_AT91)	+= sama5d34ek.dtb
>>>> diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
>>>> new file mode 100644
>>>> index 000000000000..fb1349ca60a4
>>>> --- /dev/null
>>>> +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
>>>> @@ -0,0 +1,233 @@
>>>> +/*
>>>> + * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board
>>>> + *
>>>> + *  Copyright (C) 2014 Atmel,
>>>> + *		  2014 Nicolas Ferre <nicolas.ferre@atmel.com>
>>>> + *
>>>> + * Licensed under GPLv2 or later.
>>>> + */
>>>> +/dts-v1/;
>>>> +#include "sama5d36.dtsi"
>>>> +
>>>> +/ {
>>>> +	model = "SAMA5D3 Xplained";
>>>> +	compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5";
>>>> +
>>>> +	chosen {
>>>> +		bootargs = "console=ttyS0,115200";
>>> can you describe it via linux,stdout
>>
>> Well I would have liked, but the code in the serial driver is not there yet.
>> So, I keep it like this for the moment.
>>
>>>> +	};
>>>> +
>>>> +	memory {
>>>> +		reg = <0x20000000 0x10000000>;
>>>> +	};
>>>> +
>>>> +	ahb {
>>>> +		apb {
>>>> +			mmc0: mmc at f0000000 {
>>>> +				pinc?trl-names = "default";
>>> ?? this is SoC should never been seen here
> this need to move to dtsi not here

Yes. It is done already.

>>>> +				pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
>>>> +				status = "okay";
>>>> +				slot at 0 {
>>>> +					reg = <0>;
>>>> +					bus-width = <8>;
>>>> +					cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>;
>>>> +				};
>>>> +			};
>>>> +
>>>> +			spi0: spi at f0004000 {
>>>> +				cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
>>> if you use only one CS no need to specified all
>>>
>>> we need to add macro per SoC for the hw CS used as GPIO so it's more clear
>>
>> No, I do not think so.
> 
> yes as you dopy &pioD 13 0 everywhere instead of doing
> 
> #define SAMA5D3_SPI_CS0_GPIO	&pioD 13 GPIO_ACTIVE_LOW
> 
> and then
> 
> 			cs-gpios = <SAMA5D3_SPI_CS0_GPIO>;

I do not see any benefit in doing this.


> and drop the
> 			, <0>, <0>, <0>;

Already done.

> 
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			can0: can at f000c000 {
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			i2c0: i2c at f0014000 {
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			i2c1: i2c at f0018000 {
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			macb0: ethernet at f0028000 {
>>>> +				phy-mode = "rgmii";
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			usart0: serial at f001c000 {
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			usart1: serial at f0020000 {
>>>> +				pinctrl-names = "default";
>>> same as mmc
>>>> +				pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			uart0: serial at f0024000 {
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			mmc1: mmc at f8000000 {
>>>> +				pinctrl-names = "default";
>>> ditto
>>>> +				pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
>>>> +				status = "okay";
>>>> +				slot at 0 {
>>>> +					reg = <0>;
>>>> +					bus-width = <4>;
>>>> +					cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>;
>>>> +				};
>>>> +			};
>>>> +
>>>> +			spi1: spi at f8008000 {
>>>> +				cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>;
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			adc0: adc at f8018000 {
>>>> +				pinctrl-names = "default";
>>> ditto
>>>> +				pinctrl-0 = <
>>>> +					&pinctrl_adc0_adtrg
>>>> +					&pinctrl_adc0_ad0
>>>> +					&pinctrl_adc0_ad1
>>>> +					&pinctrl_adc0_ad2
>>>> +					&pinctrl_adc0_ad3
>>>> +					&pinctrl_adc0_ad4
>>>> +					&pinctrl_adc0_ad5
>>>> +					&pinctrl_adc0_ad6
>>>> +					&pinctrl_adc0_ad7
>>>> +					&pinctrl_adc0_ad8
>>>> +					&pinctrl_adc0_ad9
>>>> +					>;
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			i2c2: i2c at f801c000 {
>>>> +				dmas = <0>, <0>;	/* Do not use DMA for i2c2 */
>>> why?
>>
>> Because we use the channels for other peripherals
>>
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			macb1: ethernet at f802c000 {
>>>> +				phy-mode = "rmii";
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			dbgu: serial at ffffee00 {
>>>> +				status = "okay";
>>>> +			};
>>>> +
>>>> +			pinctrl at fffff200 {
>>>> +				board {
>>>> +					pinctrl_mmc0_cd: mmc0_cd {
>>>> +						atmel,pins =
>>>> +							<AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
>>>> +					};
>>>> +
>>>> +					pinctrl_mmc1_cd: mmc1_cd {
>>>> +						atmel,pins =
>>>> +							<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
>>>> +					};
>>>> +
>>>> +					pinctrl_usba_vbus: usba_vbus {
>>>> +						atmel,pins =
>>>> +							<AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;	/* PE9, conflicts with A9 */
>>> in this case we should have ifdef so we could choose what we want via make
>>> file
>>
>> No, we choose by modifying the DTS.
> exactly what I've said describe it via ifdef in the dts

Nothing else is connected to PE9, so I do not describe anything else in
the DTS. No need for ifdefs or anything else.

>>>> +					};
>>>> +				};
>>>> +			};
>>>> +
>>>> +			pmc: pmc at fffffc00 {
>>>> +				main: mainck {
>>>> +					clock-frequency = <12000000>;
>>>> +				};
>>>> +			};
>>>> +		};
>>>> +
>>>> +		nand0: nand at 60000000 {
>>>> +			nand-bus-width = <8>;
>>>> +			nand-ecc-mode = "hw";
>>>> +			atmel,has-pmecc;
>>>> +			atmel,pmecc-cap = <4>;
>>>> +			atmel,pmecc-sector-size = <512>;
>>>> +			nand-on-flash-bbt;
>>>> +			status = "okay";
>>>> +
>>>> +			at91bootstrap at 0 {
>>>> +				label = "at91bootstrap";
>>>> +				reg = <0x0 0x40000>;
>>>> +			};
>>>> +
>>>> +			bootloader at 40000 {
>>>> +				label = "bootloader";
>>>> +				reg = <0x40000 0x80000>;
>>>> +			};
>>>> +
>>>> +			bootloaderenv at c0000 {
>>>> +				label = "bootloader env";
>>>> +				reg = <0xc0000 0xc0000>;
>>>> +			};
>>>> +
>>>> +			dtb at 180000 {
>>>> +				label = "device tree";
>>>> +				reg = <0x180000 0x80000>;
>>>> +			};
>>>> +
>>>> +			kernel at 200000 {
>>>> +				label = "kernel";
>>>> +				reg = <0x200000 0x600000>;
>>>> +			};
>>>> +
>>>> +			rootfs at 800000 {
>>>> +				label = "rootfs";
>>>> +				reg = <0x800000 0x0f800000>;
>>>> +			};
>>> more I read this partition more it's seems wrong those days
>>>
>>> we really need to switch to UBI
>>
>> I am using UBI with this layout.
> 
> so put the kernel & dts on UBI to have wareleveling on it too
> 
> and then we do not need to knwown the kernel/rootfs/dtc partition size and
> position

I use this layout. Do not force me to use another one. I own this board,
do what you want on boards that you are responsible for and let me do
what I want on boards that I am responsible for.

If I want to switch to another layout, I will do at the proper date.


>>>> +		};
>>>> +
>>>> +		usb0: gadget at 00500000 {
>>>> +			atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>;	/* PE9, conflicts with A9 */
>>>> +			pinctrl-names = "default";
>>>> +			pinctrl-0 = <&pinctrl_usba_vbus>;
>>>> +			status = "okay";
>>>> +		};
>>>> +
>>>> +		usb1: ohci at 00600000 {
>>>> +			num-ports = <3>;
>>>> +			atmel,vbus-gpio = <0
>>>> +					   &pioE 3 GPIO_ACTIVE_LOW
>>>> +					   &pioE 4 GPIO_ACTIVE_LOW
>>>> +					  >;
>>>> +			status = "okay";
>>>> +		};
>>>> +
>>>> +		usb2: ehci at 00700000 {
>>>> +			status = "okay";
>>>> +		};
>>>> +	};
>>>> +
>>>> +	gpio_keys {
>>>> +		compatible = "gpio-keys";
>>>> +
>>>> +		bp3 {
>>>> +			label = "PB_USER";
>>>> +			gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
>>>> +			linux,code = <0x104>;
>>>> +			gpio-key,wakeup;
>>>> +		};
>>>> +	};
>>>> +
>>>> +	leds {
>>>> +		compatible = "gpio-leds";
>>>> +
>>>> +		d2 {
>>>> +			label = "d2";
>>>> +			gpios = <&pioE 23 GPIO_ACTIVE_LOW>;	/* PE23, conflicts with A23, CTS2 */
>>>> +			linux,default-trigger = "heartbeat";
>>>> +		};
>>>> +
>>>> +		d3 {
>>>> +			label = "d3";
>>>> +			gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
>>>> +		};
>>>> +	};
>>>> +};
>>>> -- 
>>>> 1.8.2.2
>>>>
>>>
>>
>>
>> -- 
>> Nicolas Ferre
> 


-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH 02/03] pinctrl: sh-pfc: r8a7790: Break out USB0 OVC/VBUS
From: Linus Walleij @ 2014-02-10  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1869968.h64ujKRKE7@avalon>

On Fri, Feb 7, 2014 at 1:36 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:

> I was thinking about letting Linus pick up the PFC patches again now that the
> flood is over. Of course, if it can help, I can still pick the patches up and
> submit pull requests to Linus.
>
> Linus, what's your opinion on this ? Would you rather pick the patches
> directly after I've acked them, or process pull requests ?

As long as it's reasonable traffic I'll take it. :-)

I'll queue this one then, I guess only patch 2/3?

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 02/03] pinctrl: sh-pfc: r8a7790: Break out USB0 OVC/VBUS
From: Linus Walleij @ 2014-02-10  9:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140129231019.22655.41456.sendpatchset@w520>

On Thu, Jan 30, 2014 at 12:10 AM, Magnus Damm <magnus.damm@gmail.com> wrote:

> From: Magnus Damm <damm@opensource.se>
>
> Create a new group for the USB0 OVC/VBUS pin by itself. This
> allows us to monitor PWEN as GPIO on the Lager board.
>
> Signed-off-by: Magnus Damm <damm@opensource.se>

Patch applied with Laurent's and Simon's ACKs.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v3 2/2] Binding: atmel-ssc: add option to choose clock
From: Nicolas Ferre @ 2014-02-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392012586-30790-3-git-send-email-voice.shen@atmel.com>

On 10/02/2014 07:09, Bo Shen :
> Add the option to choose clock on which pin input to SSC (as slave).
> Default is on TK pin to SSC, add "atmel,clk-from-rk-pin" option to
> specify the clock is on RK pin to SSC.
> 
> Signed-off-by: Bo Shen <voice.shen@atmel.com>

Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

> ---
> Changes in v3:
>   - None
> Series-changes: 2
>   - using "-" replace "_" in binding document
> 
>  Documentation/devicetree/bindings/misc/atmel-ssc.txt | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
> index a45ae08..5c1e14e 100644
> --- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt
> +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
> @@ -14,6 +14,14 @@ Required properties for devices compatible with "atmel,at91sam9g45-ssc":
>    See Documentation/devicetree/bindings/dma/atmel-dma.txt for details.
>  - dma-names: Must be "tx", "rx".
>  
> +Optional properties:
> +  - atmel,clk-from-rk-pin: bool property.
> +     - When SSC works in slave mode, according to the hardware design, the
> +       clock can get from TK pin, and also can get from RK pin. So, add
> +       this parameter to choose where the clock from.
> +     - By default the clock is from TK pin, if the clock from RK pin, this
> +       property is needed.
> +
>  Examples:
>  - PDC transfer:
>  ssc0: ssc at fffbc000 {
> 


-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH v3 1/2] ASoC: atmel_ssc_dai: make option to choose clock
From: Nicolas Ferre @ 2014-02-10  9:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392012586-30790-2-git-send-email-voice.shen@atmel.com>

On 10/02/2014 07:09, Bo Shen :
> When SSC works in slave mode, according to the hardware design, the
> clock can get from TK pin, also can get from RK pin. So, add one
> parameter to choose where the clock from.
> 
> Signed-off-by: Bo Shen <voice.shen@atmel.com>

Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

> ---
> Changes in v3:
>   - New, move clk-from-rk-pin property from card to ssc device
> 
>  drivers/misc/atmel-ssc.c        |  6 ++++++
>  include/linux/atmel-ssc.h       |  1 +
>  sound/soc/atmel/atmel_ssc_dai.c | 13 +++++++++----
>  3 files changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
> index 5be80840..22de137 100644
> --- a/drivers/misc/atmel-ssc.c
> +++ b/drivers/misc/atmel-ssc.c
> @@ -150,6 +150,12 @@ static int ssc_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat;
>  
> +	if (pdev->dev.of_node) {
> +		struct device_node *np = pdev->dev.of_node;
> +		ssc->clk_from_rk_pin =
> +			of_property_read_bool(np, "atmel,clk-from-rk-pin");
> +	}
> +
>  	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	ssc->regs = devm_ioremap_resource(&pdev->dev, regs);
>  	if (IS_ERR(ssc->regs))
> diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h
> index 66a0e53..571a12e 100644
> --- a/include/linux/atmel-ssc.h
> +++ b/include/linux/atmel-ssc.h
> @@ -18,6 +18,7 @@ struct ssc_device {
>  	struct clk		*clk;
>  	int			user;
>  	int			irq;
> +	bool			clk_from_rk_pin;
>  };
>  
>  struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
> diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
> index 8697ced..ca1d8a3 100644
> --- a/sound/soc/atmel/atmel_ssc_dai.c
> +++ b/sound/soc/atmel/atmel_ssc_dai.c
> @@ -341,6 +341,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
>  {
>  	int id = dai->id;
>  	struct atmel_ssc_info *ssc_p = &ssc_info[id];
> +	struct ssc_device *ssc = ssc_p->ssc;
>  	struct atmel_pcm_dma_params *dma_params;
>  	int dir, channels, bits;
>  	u32 tfmr, rfmr, tcmr, rcmr;
> @@ -466,7 +467,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
>  			| SSC_BF(RCMR_START, start_event)
>  			| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
>  			| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
> -			| SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
> +			| SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
> +					   SSC_CKS_PIN : SSC_CKS_CLOCK);
>  
>  		rfmr =	  SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
>  			| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
> @@ -481,7 +483,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
>  			| SSC_BF(TCMR_START, start_event)
>  			| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
>  			| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
> -			| SSC_BF(TCMR_CKS, SSC_CKS_PIN);
> +			| SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
> +					   SSC_CKS_CLOCK : SSC_CKS_PIN);
>  
>  		tfmr =	  SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
>  			| SSC_BF(TFMR_FSDEN, 0)
> @@ -550,7 +553,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
>  			| SSC_BF(RCMR_START, SSC_START_RISING_RF)
>  			| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
>  			| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
> -			| SSC_BF(RCMR_CKS, SSC_CKS_PIN);
> +			| SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
> +					   SSC_CKS_PIN : SSC_CKS_CLOCK);
>  
>  		rfmr =	  SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
>  			| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
> @@ -565,7 +569,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
>  			| SSC_BF(TCMR_START, SSC_START_RISING_RF)
>  			| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
>  			| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
> -			| SSC_BF(TCMR_CKS, SSC_CKS_PIN);
> +			| SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
> +					   SSC_CKS_CLOCK : SSC_CKS_PIN);
>  
>  		tfmr =	  SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
>  			| SSC_BF(TFMR_FSDEN, 0)
> 


-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH] pinctrl:at91:add drive strength configuration
From: Linus Walleij @ 2014-02-10  9:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390285991-1634-1-git-send-email-mark.roszko@gmail.com>

I agree with J-C that the patch shall be split in one for the DT changes and one
for the driver changes (that I will apply to the pinctrl tree).

On Tue, Jan 21, 2014 at 7:33 AM, Marek Roszko <mark.roszko@gmail.com> wrote:

> The SAMA5 and most SAM9xGs(baring a few exceptions like the SAM945G) have drive
> control registers that allow configuring the output current of the gpio pins between
> three predefined levels of low,medium and high drive.

Can we get to know a bit more about default/low/medium and high?

I.e. this:

> +#define DRIVE_STRENGTH_DEFAULT (0x0 << 5)
> +#define DRIVE_STRENGTH_LOW             (0x1 << 5)
> +#define DRIVE_STRENGTH_MED             (0x2 << 5)
> +#define DRIVE_STRENGTH_HI              (0x3 << 5)
(...)
> +static unsigned at91_mux_sam9x5_get_drivestrength(void __iomem *pio, unsigned pin)
> +{
> +       unsigned tmp = read_drive_strength(pio + at91sam9x5_get_drive_register(pin), pin);
> +
> +       /*
> +        * inverse the setting for dt defines
> +        * 0 = hi, 1 = med, 2 = low, 3 = rsvd

But in the defines ... 3-3=0 means "default" not
"reserved"?

> +        */
> +       tmp = DRIVE_STRENGTH_HI - tmp;
(...)
> +#define AT91_PINCTRL_DRIVE_STRENGTH_DEFAULT    (0x0 << 5)
> +#define AT91_PINCTRL_DRIVE_STRENGTH_LOW                (0x1 << 5)
> +#define AT91_PINCTRL_DRIVE_STRENGTH_MED                (0x2 << 5)
> +#define AT91_PINCTRL_DRIVE_STRENGTH_HI         (0x3 << 5)

So I guess "default" is some HW-defined driver strength decided when
synthesizing the block? (Document the answer in the bindings or
something.)

What I'm after is if this is drive strength in the sense of
"number of driver stages" i.e. a number of extra mA per
strength increase, usuall in 2mA or 4mA increases, so e.g.
LOW=2mA, mid=4mA, high=6mA or if it's actually a
slew rate thing designed for restricing the noise in silicon
and/or electronics by providing a less steep slope containing
less overtones. (This is usually done by another construction.)
Which one is it?

You also already have this:
#define AT91_PINCTRL_MULTI_DRIVE        (1 << 1)

How does these different things relate? Do you have to set
MULTI_DRIVE for the settings to work? Or is it leftover cruft?
Or what is it?

Also take this opportunity to update:
Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
To document all these funny defines and what they are used for.

The bindings changes should be part of the pinctrl driver patch.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 2/7] ARM: lpc32xx: don't select HAVE_PWM
From: Roland Stigge @ 2014-02-10  9:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <003b01cf25fc$bd4b51d0$37e1f570$%han@samsung.com>

On 10/02/14 02:09, Jingoo Han wrote:
> The HAVE_PWM symbol is only for legacy platforms that provide
> the PWM API without using the generic framework. The lpc32xx
> platforms use the generic PWM framework, after the commit "2132fa8
> pwm: add lpc32xx PWM support".
> 
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
>  arch/arm/Kconfig |    1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index e254198..897fa15 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -632,7 +632,6 @@ config ARCH_LPC32XX
>  	select CPU_ARM926T
>  	select GENERIC_CLOCKEVENTS
>  	select HAVE_IDE
> -	select HAVE_PWM
>  	select USB_ARCH_HAS_OHCI
>  	select USE_OF
>  	help
> 

Acked-by: Roland Stigge <stigge@antcom.de>

^ permalink raw reply

* [PATCH v3 06/15] at91: dt: at91sam9261ek: Adds DT entries for the 4 user buttons
From: Linus Walleij @ 2014-02-10  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F4B3E7.2080000@atmel.com>

On Fri, Feb 7, 2014 at 11:22 AM, Nicolas Ferre <nicolas.ferre@atmel.com> wrote:
> On 07/02/2014 10:30, Jean-Jacques Hiblot :
>> 2014-02-07 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>:
>>> On 16:57 Thu 23 Jan     , Jean-Jacques Hiblot wrote:
>>>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
>>>> ---
>>>>  arch/arm/boot/dts/at91sam9261ek.dts | 39 +++++++++++++++++++++++++++++++++++++
>>>>  1 file changed, 39 insertions(+)
>>>
>>> do only one patch for the 9261ek support no nned to clean
>>>>
>>>> diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
>>>> index 8909217..5555e9f5 100644
>>>> --- a/arch/arm/boot/dts/at91sam9261ek.dts
>>>> +++ b/arch/arm/boot/dts/at91sam9261ek.dts
>>>> @@ -83,6 +83,15 @@
>>>>                                               AT91_PIOA 23  AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
>>>>                                       };
>>>>                               };
>>>> +
>>>> +                             keys {
>>>> +                                     pinctrl_keys: keys-0 {
>>>> +                                             atmel,pins = <AT91_PIOA 27  AT91_PERIPH_GPIO AT91_PINCTRL_NONE
>>>> +                                             AT91_PIOA 26  AT91_PERIPH_GPIO AT91_PINCTRL_NONE
>>>> +                                             AT91_PIOA 25  AT91_PERIPH_GPIO AT91_PINCTRL_NONE
>>>> +                                             AT91_PIOA 24  AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
>>>> +                                     };
>>>> +                             };
>>>
>>> no need this you can drop it
>> ok. I thought that it would help the user to understand the GPIO usage.
>> I'll remove all pinmux for GPIO that don't require a special hardware
>> configuration
>
> Well, me also, I like to see what the board requires for functioning
> properly. It is convenient for:
> - understanding clearly what is used and what is not
> - doing a grep when searching where a particular GPIO is used
> - describing completely the hardware (which is the purpose of DT)
>
> So, I would like additional consideration by more AT91 users before
> following this rule... And maybe a note by Linus W.

So this is something like a grey area, it's not like there is a definitive
answer to it. It just reflects the fact that the pin control and GPIO
hardware is closely connected and we're cross-talking between
the subsystems to set up GPIOs when requested, i.e.
gpio_request_enable() is implemented.

If that function was *not* implemented, we'd have to do it like
this.

What happens in this case I guess, is that if &pinctrl_keys would
be tied to a default state, the GPIO pins would be muxed in
twice, which is not so horrible.

It becomes very interesting the day you want to add something
else than AT91_PINCTRL_NONE as the last flag, for example
pull-up or drive strength. Then you need both orthogonal interfaces
to be used, so then it's helpful to have this snippet there to fill
in the right biasing etc.

So I would say something lame like it depends on the suspected
use cases.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 00/17] i2c: deprecate class based instantiation for embedded I2C drivers
From: Wolfram Sang @ 2014-02-10 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

With I2C, class based instantiation means if a master driver has e.g.
I2C_CLASS_HWMON set, all slave drivers with this class will try to probe a
device using an array of possible addresses and some heuristics. That creates
traffic and needs time, even when nothing is connected. This mechanism is
needed when you do not have another method to describe the slaves. Embedded I2C
drivers do not need class based instantiation, since there is i2c_board_info or
devicetree description. Some drivers have the class flags set, though, and it
has spread further over the years. We can't remove the flags directly, because
there might be users out there relying on this feature. So, we add a
deprecation warning if a device is instantiated via class attributes. After
giving some time to switch over, we can then finally remove the class flags and
gain boot time.

Patch 1 adds some missing documentation. Patch 2 adds the deprecation feature.
Patches 3+4 are tested on hardware I need. Patches 5-17 are suggestions for
drivers I think could benefit from that. For those, acks are needed before I
will apply them to my tree. If you use a different driver which can also
benefit from this, just send a patch adding the new DEPRECATED flag.

The series can also be found here:

git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/deprecated_class

Thanks,

   Wolfram


Wolfram Sang (17):
  Documentation: i2c: describe devicetree method for instantiating
    devices
  i2c: add deprecation warning for class based instantiation
  i2c: i2c-omap: deprecate class based instantiation
  i2c: i2c-at91: deprecate class based instantiation
  i2c: i2c-bcm2835: deprecate class based instantiation
  i2c: i2c-bfin-twi: deprecate class based instantiation
  i2c: i2c-davinci: deprecate class based instantiation
  i2c: i2c-designware-platdrv: deprecate class based instantiation
  i2c: i2c-mv64xxx: deprecate class based instantiation
  i2c: i2c-nomadik: deprecate class based instantiation
  i2c: i2c-ocores: deprecate class based instantiation
  i2c: i2c-rcar: deprecate class based instantiation
  i2c: i2c-s3c2410: deprecate class based instantiation
  i2c: i2c-sirf: deprecate class based instantiation
  i2c: i2c-stu300: deprecate class based instantiation
  i2c: i2c-tegra: deprecate class based instantiation
  i2c: i2c-xiic: deprecate class based instantiation

 Documentation/i2c/instantiating-devices     | 34 +++++++++++++++++++++++++++--
 drivers/i2c/busses/i2c-at91.c               |  2 +-
 drivers/i2c/busses/i2c-bcm2835.c            |  2 +-
 drivers/i2c/busses/i2c-bfin-twi.c           |  2 +-
 drivers/i2c/busses/i2c-davinci.c            |  2 +-
 drivers/i2c/busses/i2c-designware-platdrv.c |  2 +-
 drivers/i2c/busses/i2c-mv64xxx.c            |  2 +-
 drivers/i2c/busses/i2c-nomadik.c            |  2 +-
 drivers/i2c/busses/i2c-ocores.c             |  2 +-
 drivers/i2c/busses/i2c-omap.c               |  2 +-
 drivers/i2c/busses/i2c-rcar.c               |  2 +-
 drivers/i2c/busses/i2c-s3c2410.c            |  2 +-
 drivers/i2c/busses/i2c-sirf.c               |  2 +-
 drivers/i2c/busses/i2c-stu300.c             |  2 +-
 drivers/i2c/busses/i2c-tegra.c              |  2 +-
 drivers/i2c/busses/i2c-xiic.c               |  2 +-
 drivers/i2c/i2c-core.c                      |  7 ++++++
 include/linux/i2c.h                         |  1 +
 18 files changed, 55 insertions(+), 17 deletions(-)

-- 
1.8.5.1

^ 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