Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH 1/2] drm: share drm_add_fake_info_node
From: Ben Widawsky @ 2014-01-15 20:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKMK7uE7CSh1gcs341ji6duRH_FgNDhoMfZNc=4hoYf-an1M=w@mail.gmail.com>

On Wed, Jan 15, 2014 at 09:45:28AM +0100, Daniel Vetter wrote:
> On Wed, Jan 15, 2014 at 9:39 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
> > On Wed, Jan 15, 2014 at 12:40 AM, Russell King - ARM Linux
> > <linux@arm.linux.org.uk> wrote:
> >> On Wed, Jan 15, 2014 at 12:25:10AM +0100, Daniel Vetter wrote:
> >>> On Tue, Jan 14, 2014 at 06:14:06AM -0800, Ben Widawsky wrote:
> >>> > Both i915 and Armada had the exact same implementation. For an upcoming
> >>> > patch, I'd like to call this function from two different source files in
> >>> > i915, and having it available externally helps there too.
> >>> >
> >>> > While moving, add 'debugfs_' to the name in order to match the other drm
> >>> > debugfs helper functions.
> >>> >
> >>> > Cc: linux-arm-kernel at lists.infradead.org
> >>> > Cc: intel-gfx at lists.freedesktop.org
> >>> > Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> >>>
> >>> drm_debugfs_create_files in drm_debugfs.c has the almost same code again.
> >>> Now the problem here is that the interface is a bit botched up, since all
> >>> the users in i915 and armada actaully faile to clean up teh debugfs dentry
> >>> if drm_add_fake_info_node.
> >>
> >> That's not correct - armada does clean up these, I think you need to
> >> take a closer look at the code.
> >>
> >> We do this by setting node->info_ent to the file operations structure,
> >> which is a unique key to the file being registered.
> >>
> >> Upon failure to create the fake node, we appropriately call
> >> drm_debugfs_remove_files() with the first argument being a pointer to
> >> the file operations.  This causes drm_debugfs_remove_files() to match
> >> the fake entry, call debugfs_remove() on the dentry, and remove the
> >> node from the list, and free the node structure we allocated.
> >>
> >> Upon driver teardown, we also call drm_debugfs_remove_files() but with
> >> each fops which should be registered, thus cleaning up each fake node
> >> which was created.
> >>
> >> So, Armada does clean up these entries properly.
> >
> > Indeed I've missed that and it's just i915 that botches this. I still
> > think the helper would be saner if it cleans up all its leftovers in
> > the failure case.
> 
> Ok, now I've actually page all the stuff back in - if
> drm_add_fake_info_node fails we don't set up a drm_info_node structure
> and link it anywhere. Which means drm_debugfs_remove_files won't ever
> find it and hence can't possibly call debugfs_remove. Which means the
> debugfs dentry is leaked. So I think the semantics of that new debugfs
> helper should get fixed to also allocate and clean up the debugfs
> node.
> 
> I agree that i915 is even worse since it doesn't bother to clean up
> any debugfs files at all in the failure case.
> -Daniel
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

Perhaps I don't understand what you want here. The only failure path in
the fake entry creation does already call debugfs_remove.

        if (node == NULL) {
                debugfs_remove(ent);
                return -ENOMEM;
        }

So long as the function succeeds, the node will be findable and removable.

-- 
Ben Widawsky, Intel Open Source Technology Center

^ permalink raw reply

* [PATCH 4/6] ARM: DTS: tegra: add the DFLL IP block to the T114 SoC file
From: Paul Walmsley @ 2014-01-15 20:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140115195025.GU20094@book.gsilab.sittig.org>

On 01/15/2014 11:50 AM, Gerhard Sittig wrote:
> On Mon, Jan 13, 2014 at 22:27 -0800, Paul Walmsley wrote:
>> On Thu, 19 Dec 2013, Stephen Warren wrote:
>>
>>> On 12/19/2013 05:49 AM, Paul Walmsley wrote:
>>>> Add basic DT bindings for the DFLL IP block for the NVIDIA Tegra114 SoC.
>>>> diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra114-dfll.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra114-dfll.txt
>>>> +- clocks : Must contain an array of two-cell arrays, one per clock.
>>>> +           DFLL source clocks.  At minimum this should include the
>>>> +           reference clock source and the IP block's main clock
>>>> +           source.  Also it should contain the DFLL's I2C controller
>>>> +           clock source.  The format is <&clock-provider-phandle
>>>> +           clock-id>.
>>> Entries in "clocks" aren't two cells, they're a phandle plus as many
>>> cells as the node referenced by the phandle specifies.
>> It's worth noting that the clock binding documentation itself refers
>> to pairs:
>>
>> ----
>>
>> clocks:		List of phandle and clock specifier pairs, one pair
>> 		for each clock input to the device.  Note: if the
>> 		clock provider specifies '0' for #clock-cells, then
>> 		only the phandle portion of the pair will appear.
>>
>> ----
>>
>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/clock/clock-bindings.txt#n50
>>
>> But given the ambiguity of that documentation, I basically agree, so
>> have changed it to:
> Please note that there neither is an ambiguity nor a conflict
> here, and that you actually acknowledge what Stephen said:

I do not agree that the Documentation is unambiguous.

It is not correct to refer to a "pair" without a second item as a "pair."

> This is exactly what Stephen said:  A "clocks" item does not need
> to have two cells.  The pair of phandle and clock specifier don't
> necessarily translate into two cells, instead the number of cells
> depends on the clock provider.

I do agree with this, and have updated the documentation accordingly.


- Paul

^ permalink raw reply

* [PATCH v9 2/4] Documentation: Add documentation for APM X-Gene SoC SATA host controller DTS binding
From: Arnd Bergmann @ 2014-01-15 20:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPw-ZT=wJVQ2Qw47Ehgu6rJZ4HkpADrGuhZr8Yjf4XA6z+-xbA@mail.gmail.com>

On Wednesday 15 January 2014 12:04:02 Loc Ho wrote:
> 
> >> +- clocks             : Reference to the clock entry.
> >> +- phys                       : PHY reference with parameter 0.
> >
> > The specific value of the phy-specifier shouldn't matter to this
> > binding. What should matter is what it logically corresponds to.
> 
> I not quite following this. Are you suggest that I drop the value 0.
> In the binding, one needs to specify the mode of operation - 0 is for
> SATA. Can you explain more?

The SATA device should not care what the argument for the PHY
device is. You could connect the same device to another PHY
that has a different set of arguments, which is the whole point
of abstracting it.

	Arnd

^ permalink raw reply

* [PATCH v7 3/4] PHY: add APM X-Gene SoC 15Gbps Multi-purpose PHY driver
From: Loc Ho @ 2014-01-15 20:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140115120946.GD25824@e106331-lin.cambridge.arm.com>

Hi,

> [...]
>
>> + * The APM X-Gene PHY consists of two PLL clock macro's (CMU) and lanes.
>> + * The first PLL clock macro is used for internal reference clock. The second
>> + * PLL clock macro is used to generate the clock for the PHY. This driver
>> + * configures the first PLL CMU, the second PLL CMU, and programs the PHY to
>> + * operate according to the mode of operation. The first PLL CMU is only
>> + * required if internal clock is enabled.
>> + *
>> + * Logical Layer Out Of HW module units:
>> + *
>> + * -----------------
>> + * | Internal      |    |------|
>> + * | Ref PLL CMU   |----|      |     -------------    ---------
>> + * ------------ ----    | MUX  |-----|PHY PLL CMU|----| Serdes|
>> + *                      |      |     |           |    ---------
>> + * External Clock ------|      |     -------------
>> + *                      |------|
>> + *
>> + * The Ref PLL CMU CSR (Configureation System Registers) is accessed
>> + * indirectly from the SDS offset at 0x2000. It is only required for
>> + * internal reference clock.
>> + * The PHY PLL CMU CSR is accessed indirectly from the SDS offset at 0x0000.
>> + * The Serdes CSR is accessed indirectly from the SDS offset at 0x0400.
>> + *
>> + * The Ref PLL CMU can be located within the same PHY IP or outside the PHY IP
>> + * due to shared Ref PLL CMU. For PHY with Ref PLL CMU shared with another IP,
>> + * it is located outside the PHY IP. This is the case for the PHY located
>> + * at 0x1f23a000 (SATA Port 4/5). For such PHY, another resource is required
>> + * to located the SDS/Ref PLL CMU module and its clock for that IP enabled.
>> + *
>> + * Currently, this driver only supports SATA mode with external clock.
>> + */
>
> Having looked at this and the binding, I'm confused as to why we need an
> additional reg entry when we're using the external clock.
>
> Surely the second resource (the external CMU base) is a property of the
> shared ref PLL clock, rather than the PHY itself. How do you handle two
> units trying to use the shared PLL?

You have an good point here. For the time being, let me rip out the
external CMU support as we don't support internal clock just yet. It
will be deal with later on.

>
> I think makes sense to model the ref PLL CMU as a separate clock, and
> use clock-names to differentiate between the two inputs to the mux:
>
> external: external_clock {
>         compatible = "fixed-clock";
>         clock-frequency = < ... >;
>         #clock-cells = <0>;
> };
>
> ref_pll: reference_clock {
>         compatible = "apm,xgene-ref-pll";
>         reg = < .... >;
>         #clock-cells = <0>;
> };
>
> phy {
>         compatible = "apm,xgene-phy";
>         reg = < ... >;
>         clocks = <&ref_pll>, <&external>;
>         clock-names = "ref-pll", "external";
>         ...
> };
>
>
> That also means the phy only needs a single compatible string -- you can
> figure out what to do by probing the set of clocks.
>
> Does that make sense? Is there something I'm missing?

Okay... As mentioned, let me rip the ref CMU out and address this at a
later time - going with your suggested approach in the future.

-Loc

^ permalink raw reply

* v3.12 regression from "ARM: kirkwood: convert to DT irqchip and clocksource" on non-DT kirkwood platforms
From: Ian Campbell @ 2014-01-15 20:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52D6E785.4000706@gmail.com>

On Wed, 2014-01-15 at 20:54 +0100, Sebastian Hesselbarth wrote:
> please try the following two patches on top of v3.13-rc8 and report
> back, if it solves the regression.

Yes, it works fine, thanks!

Tested-by: Ian Campbell <ijc@hellion.org.uk>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140115/3e39ef73/attachment.sig>

^ permalink raw reply

* [PATCH v7 0/2] ohci and ehci-platform clks, phy and dt support
From: Alan Stern @ 2014-01-15 20:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389813883-567-1-git-send-email-hdegoede@redhat.com>

On Wed, 15 Jan 2014, Hans de Goede wrote:

> Hi All,
> 
> This version of my ohci and ehci-platform clks, phy and dt support patch-set,
> really fixes the 2 small bugs Alan found.

All okay -- this time I can't find anything to complain about.  :-)

Alan Stern

^ permalink raw reply

* [PATCH v2 1/7] ARM: perf_event: Support percpu irqs for the CPU PMU
From: Stephen Boyd @ 2014-01-15 20:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389808535-23852-2-git-send-email-sboyd@codeaurora.org>

On 01/15, Stephen Boyd wrote:
> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
> index 789d846a9184..e76750980b38 100644
> --- a/arch/arm/kernel/perf_event.c
> +++ b/arch/arm/kernel/perf_event.c
> @@ -295,9 +297,15 @@ validate_group(struct perf_event *event)
>  
>  static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
>  {
> -	struct arm_pmu *armpmu = (struct arm_pmu *) dev;
> -	struct platform_device *plat_device = armpmu->plat_device;
> -	struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev);
> +	struct arm_pmu *armpmu;
> +	struct platform_device *plat_device;
> +	struct arm_pmu_platdata *plat;
> +
> +	if (irq_is_percpu(irq))
> +		dev = *(struct arm_pmu_cpu **)dev;

Oh. I just realized that struct arm_pmu_cpu doesn't even exist. This
still compiles though because we're dealing with a void pointer.

Perhaps its better to just do

	dev = *(void **)dev;

here. Can you fix that up when applying? Otherwise I'll do it on
the next send if there are more comments.

> +	armpmu = dev;
> +	plat_device = armpmu->plat_device;
> +	plat = dev_get_platdata(&plat_device->dev);
>  

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [PATCH v9 2/4] Documentation: Add documentation for APM X-Gene SoC SATA host controller DTS binding
From: Loc Ho @ 2014-01-15 21:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5905127.tqJ3nFt5cj@wuerfel>

Hi,

>>
>> >> +- clocks             : Reference to the clock entry.
>> >> +- phys                       : PHY reference with parameter 0.
>> >
>> > The specific value of the phy-specifier shouldn't matter to this
>> > binding. What should matter is what it logically corresponds to.
>>
>> I not quite following this. Are you suggest that I drop the value 0.
>> In the binding, one needs to specify the mode of operation - 0 is for
>> SATA. Can you explain more?
>
> The SATA device should not care what the argument for the PHY
> device is. You could connect the same device to another PHY
> that has a different set of arguments, which is the whole point
> of abstracting it.
>

I understand what you wrote here. We should not have an argument from
the host controller. Then my question is how should the PHY node
indicates that it needs to be configured itself as an SATA PHY?

-Loc

^ permalink raw reply

* [PATCH v9 2/4] Documentation: Add documentation for APM X-Gene SoC SATA host controller DTS binding
From: Arnd Bergmann @ 2014-01-15 21:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPw-ZTmVYfPLUVmtes3Gn8Z=+gyFtLoZxc-QUdHH7-ePjKAG9A@mail.gmail.com>

On Wednesday 15 January 2014 13:08:47 Loc Ho wrote:
> >> >> +- clocks             : Reference to the clock entry.
> >> >> +- phys                       : PHY reference with parameter 0.
> >> >
> >> > The specific value of the phy-specifier shouldn't matter to this
> >> > binding. What should matter is what it logically corresponds to.
> >>
> >> I not quite following this. Are you suggest that I drop the value 0.
> >> In the binding, one needs to specify the mode of operation - 0 is for
> >> SATA. Can you explain more?
> >
> > The SATA device should not care what the argument for the PHY
> > device is. You could connect the same device to another PHY
> > that has a different set of arguments, which is the whole point
> > of abstracting it.
> >
> 
> I understand what you wrote here. We should not have an argument from
> the host controller. Then my question is how should the PHY node
> indicates that it needs to be configured itself as an SATA PHY?

The "phys" property should specify whatever the configuration of
the phy device is supposed to be. It's just not the business of
the sata driver or the sata binding to know what that configuration
is.

	Arnd

^ permalink raw reply

* [PATCH v6 0/6] ARM: rockchip: add smp functionality
From: Heiko Stübner @ 2014-01-15 21:40 UTC (permalink / raw)
  To: linux-arm-kernel

This series enables the use of the additional cores on Rockchip
Cortex-A9 SoCs.

To achieve this, add the scu, the needed sram and power-management-unit.

Tested on both a BQ Curie2 (rk3066a / dual core) and
on a Radxa Rock (rk3188 / quad core).

changes since v5:
- Grant Likely liked it better to "specify reserved regions of the
  memory instead of the valid ranges", so go back to the mmio-sram-reserved
  property originally suggested by Rob Herring

changes since v4:
- rebase on top of the recent rk3188 board support
- implement suggestion from Matt Sealey in moving the sram-limit from
  marking reserved regions to marking available regions - hopefully
  I got the usage right 
- remove __CPUINIT as suggested by Fabio Estevam

changes since v3:
- address comments from Rob Herring:
  - split the gathering of the reserve-data into a separate loop
  - spelling and style fixes
- first patch only included for reference, already part of the
  char-misc git tree

changes since v2:
- rework the sram allocation following the suggestion from Philipp Zabel

changes since v1:
- add reserved block feature for mmio-sram, to not use two logical
  sram nodes
- the sram content is kept intact while the device is running, so
  copying the trampoline is only needed once


Heiko Stuebner (6):
  dt-bindings: sram: describe option to reserve parts of the memory
  misc: sram: implement mmio-sram-reserved option
  ARM: rockchip: add snoop-control-unit
  ARM: rockchip: add sram dt nodes and documentation
  ARM: rockchip: add power-management-unit
  ARM: rockchip: add smp bringup code

 .../devicetree/bindings/arm/rockchip/pmu.txt       |   16 ++
 .../devicetree/bindings/arm/rockchip/smp-sram.txt  |   23 +++
 Documentation/devicetree/bindings/misc/sram.txt    |    8 +
 arch/arm/boot/dts/rk3066a.dtsi                     |    6 +
 arch/arm/boot/dts/rk3188.dtsi                      |    6 +
 arch/arm/boot/dts/rk3xxx.dtsi                      |   10 +
 arch/arm/mach-rockchip/Kconfig                     |    1 +
 arch/arm/mach-rockchip/Makefile                    |    1 +
 arch/arm/mach-rockchip/core.h                      |   22 +++
 arch/arm/mach-rockchip/headsmp.S                   |   30 +++
 arch/arm/mach-rockchip/platsmp.c                   |  208 ++++++++++++++++++++
 arch/arm/mach-rockchip/rockchip.c                  |    2 +
 drivers/misc/sram.c                                |  118 ++++++++++-
 13 files changed, 443 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/pmu.txt
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt
 create mode 100644 arch/arm/mach-rockchip/core.h
 create mode 100644 arch/arm/mach-rockchip/headsmp.S
 create mode 100644 arch/arm/mach-rockchip/platsmp.c

-- 
1.7.10.4

^ permalink raw reply

* [PATCH v6 1/6] dt-bindings: sram: describe option to reserve parts of the memory
From: Heiko Stübner @ 2014-01-15 21:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <27256277.YJ687suYy5@phil>

Some SoCs need parts of their sram for special purposes. So while being part
of the peripheral, it should not be part of the genpool controlling the sram.

Therefore add an option mmio-sram-reserved to keep arbitrary portions of the
sram from general usage.

Suggested-by: Rob Herring <robherring2@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 Documentation/devicetree/bindings/misc/sram.txt |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt
index 4d0a00e..09ee7a3 100644
--- a/Documentation/devicetree/bindings/misc/sram.txt
+++ b/Documentation/devicetree/bindings/misc/sram.txt
@@ -8,9 +8,17 @@ Required properties:
 
 - reg : SRAM iomem address range
 
+Optional properties:
+
+- mmio-sram-reserved: ordered list of reserved chunks inside the sram that
+  should not be used by the operating system.
+  Format is <base size>, <base size>, ...; with base being relative to the
+  reg property base.
+
 Example:
 
 sram: sram at 5c000000 {
 	compatible = "mmio-sram";
 	reg = <0x5c000000 0x40000>; /* 256 KiB SRAM at address 0x5c000000 */
+	mmio-sram-reserved = <0x0 0x100>; /* reserve 0x5c000000-0x5c000100 */
 };
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 2/6] misc: sram: implement mmio-sram-reserved option
From: Heiko Stübner @ 2014-01-15 21:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <27256277.YJ687suYy5@phil>

This implements support for the mmio-sram-reserved option to keep the
genpool from using these areas.

Suggested-by: Rob Herring <robherring2@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 drivers/misc/sram.c |  118 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 110 insertions(+), 8 deletions(-)

diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index afe66571..7fb60f3 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -36,13 +36,23 @@ struct sram_dev {
 	struct clk *clk;
 };
 
+struct sram_reserve {
+	unsigned long start;
+	unsigned long size;
+};
+
 static int sram_probe(struct platform_device *pdev)
 {
 	void __iomem *virt_base;
 	struct sram_dev *sram;
 	struct resource *res;
-	unsigned long size;
-	int ret;
+	unsigned long size, cur_start, cur_size;
+	const __be32 *reserved_list = NULL;
+	int reserved_size = 0;
+	struct sram_reserve *rblocks;
+	unsigned int nblocks;
+	int ret = 0;
+	int i;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	virt_base = devm_ioremap_resource(&pdev->dev, res);
@@ -65,19 +75,111 @@ static int sram_probe(struct platform_device *pdev)
 	if (!sram->pool)
 		return -ENOMEM;
 
-	ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
-				res->start, size, -1);
-	if (ret < 0) {
-		if (sram->clk)
-			clk_disable_unprepare(sram->clk);
-		return ret;
+	if (pdev->dev.of_node) {
+		reserved_list = of_get_property(pdev->dev.of_node,
+						"mmio-sram-reserved",
+						&reserved_size);
+		if (reserved_list) {
+			reserved_size /= sizeof(*reserved_list);
+			if (!reserved_size || reserved_size % 2) {
+				dev_warn(&pdev->dev, "wrong number of arguments in mmio-sram-reserved\n");
+				reserved_list = NULL;
+				reserved_size = 0;
+			}
+		}
+	}
+
+	/*
+	 * We need an additional block to mark the end of the memory region
+	 * after the reserved blocks from the dt are processed.
+	 */
+	nblocks = reserved_size / 2 + 1;
+	rblocks = kmalloc((nblocks) * sizeof(*rblocks), GFP_KERNEL);
+	if (!rblocks) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	cur_start = 0;
+	for (i = 0; i < nblocks - 1; i++) {
+		rblocks[i].start = be32_to_cpu(*reserved_list++);
+		rblocks[i].size = be32_to_cpu(*reserved_list++);
+
+		if (rblocks[i].start < cur_start) {
+			dev_err(&pdev->dev,
+				"unsorted reserved list (0x%lx before current 0x%lx)\n",
+				rblocks[i].start, cur_start);
+			ret = -EINVAL;
+			goto err_chunks;
+		}
+
+		if (rblocks[i].start >= size) {
+			dev_err(&pdev->dev,
+				"reserved block at 0x%lx outside the sram size 0x%lx\n",
+				rblocks[i].start, size);
+			ret = -EINVAL;
+			goto err_chunks;
+		}
+
+		if (rblocks[i].start + rblocks[i].size > size) {
+			dev_warn(&pdev->dev,
+				 "reserved block at 0x%lx to large, trimming\n",
+				 rblocks[i].start);
+			rblocks[i].size = size - rblocks[i].start;
+		}
+
+		cur_start = rblocks[i].start + rblocks[i].size;
+
+		dev_dbg(&pdev->dev, "found reserved block 0x%lx-0x%lx\n",
+			rblocks[i].start,
+			rblocks[i].start + rblocks[i].size);
+	}
+
+	/* the last chunk marks the end of the region */
+	rblocks[nblocks - 1].start = size;
+	rblocks[nblocks - 1].size = 0;
+
+	cur_start = 0;
+	for (i = 0; i < nblocks; i++) {
+		/* current start is in a reserved block, so continue after it */
+		if (rblocks[i].start == cur_start) {
+			cur_start = rblocks[i].start + rblocks[i].size;
+			continue;
+		}
+
+		/*
+		 * allocate the space between the current starting
+		 * address and the following reserved block, or the
+		 * end of the region.
+		 */
+		cur_size = rblocks[i].start - cur_start;
+
+		dev_dbg(&pdev->dev, "adding chunk 0x%lx-0x%lx\n",
+			cur_start, cur_start + cur_size);
+		ret = gen_pool_add_virt(sram->pool,
+				(unsigned long)virt_base + cur_start,
+				res->start + cur_start, cur_size, -1);
+		if (ret < 0)
+			goto err_chunks;
+
+		/* next allocation after this reserved block */
+		cur_start = rblocks[i].start + rblocks[i].size;
 	}
 
+	kfree(rblocks);
+
 	platform_set_drvdata(pdev, sram);
 
 	dev_dbg(&pdev->dev, "SRAM pool: %ld KiB @ 0x%p\n", size / 1024, virt_base);
 
 	return 0;
+
+err_chunks:
+	kfree(rblocks);
+err_alloc:
+	if (sram->clk)
+		clk_disable_unprepare(sram->clk);
+	return ret;
 }
 
 static int sram_remove(struct platform_device *pdev)
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH] aarch64: always map VDSO at worst case alignment
From: Kyle McMartin @ 2014-01-15 21:41 UTC (permalink / raw)
  To: linux-arm-kernel

Currently on ARM64 with 4K pages set, GDB fails to load the VDSO with
the error "Failed to read a valid object file image from memory" as it
is applying the phdr alignment to the vma, and attempting to read below
where the VDSO is mapped. This is because our segment alignment is 64K
in the ELF headers, but the VDSO only has PAGE_SIZE alignment from
get_unmapped_area.

Work around this by calling vm_unmapped_area directly, and specifying
the worst case alignment (64K) directly.

With this patch applied, I no longer have issues loading the VDSO in
gdb (and no more error message every time I run a program inside it.)

Signed-off-by: Kyle McMartin <kyle@redhat.com>

--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -163,7 +163,18 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
 
 	down_write(&mm->mmap_sem);
-	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
+	{
+		/* the VDSO must be worst-case aligned to 64K */
+		struct vm_unmapped_area_info info =
+			{
+				.flags = 0,
+				.length = vdso_mapping_len,
+				.low_limit = mm->mmap_base,
+				.high_limit = TASK_SIZE,
+				.align_mask = (1 << 16) - 1,
+			};
+		vdso_base = vm_unmapped_area(&info);
+	}
 	if (IS_ERR_VALUE(vdso_base)) {
 		ret = vdso_base;
 		goto up_fail;

^ permalink raw reply

* [PATCH v6 3/6] ARM: rockchip: add snoop-control-unit
From: Heiko Stübner @ 2014-01-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <27256277.YJ687suYy5@phil>

This adds the device-node and config select to enable the
scu in all Rockchip Cortex-A9 SoCs.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 arch/arm/boot/dts/rk3xxx.dtsi  |    5 +++++
 arch/arm/mach-rockchip/Kconfig |    1 +
 2 files changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 0fcbcfd..0a3d5b1 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -26,6 +26,11 @@
 		compatible = "simple-bus";
 		ranges;
 
+		scu at 1013c000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0x1013c000 0x100>;
+		};
+
 		gic: interrupt-controller at 1013d000 {
 			compatible = "arm,cortex-a9-gic";
 			interrupt-controller;
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index cf073de..412cbcf 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -5,6 +5,7 @@ config ARCH_ROCKCHIP
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_GIC
 	select CACHE_L2X0
+	select HAVE_ARM_SCU
 	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
 	select COMMON_CLK
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 4/6] ARM: rockchip: add sram dt nodes and documentation
From: Heiko Stübner @ 2014-01-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <27256277.YJ687suYy5@phil>

Add dt-nodes for the sram on rk3066 and rk3188 including the reserved section
needed for smp bringup.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 .../devicetree/bindings/arm/rockchip/smp-sram.txt  |   23 ++++++++++++++++++++
 arch/arm/boot/dts/rk3066a.dtsi                     |    6 +++++
 arch/arm/boot/dts/rk3188.dtsi                      |    6 +++++
 3 files changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt

diff --git a/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt b/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt
new file mode 100644
index 0000000..80c878e
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt
@@ -0,0 +1,23 @@
+Rockchip SRAM for smp bringup:
+------------------------------
+
+Rockchip's smp-capable SoCs use the first part of the sram for the bringup
+of the cores. Once the core gets powered up it executes the code that is
+residing at the very beginning of the sram.
+
+Therefore a reserved section has to be added to the mmio-sram declaration.
+
+Required node properties:
+- compatible : should contain both "rockchip,rk3066-sram", "mmio-sram"
+  so that the smp code can select the correct sram node.
+
+The rest of the properties should follow the generic mmio-sram discription
+found in ../../misc/sram.txt
+
+Example:
+
+	sram: sram at 10080000 {
+		compatible = "rockchip,rk3066-sram", "mmio-sram";
+		reg = <0x10080000 0x10000>;
+		mmio-sram-reserved = <0x0 0x50>;
+	};
diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index be5d2b0..0dfb680 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -64,6 +64,12 @@
 			clock-names = "timer", "pclk";
 		};
 
+		sram: sram at 10080000 {
+			compatible = "rockchip,rk3066-sram", "mmio-sram";
+			reg = <0x10080000 0x10000>;
+			mmio-sram-reserved = <0x0 0x50>;
+		};
+
 		pinctrl at 20008000 {
 			compatible = "rockchip,rk3066a-pinctrl";
 			reg = <0x20008000 0x150>;
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 1a26b03..1fc7eda 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -60,6 +60,12 @@
 			interrupts = <GIC_PPI 13 0xf04>;
 		};
 
+		sram: sram at 10080000 {
+			compatible = "rockchip,rk3066-sram", "mmio-sram";
+			reg = <0x10080000 0x8000>;
+			mmio-sram-reserved = <0x0 0x50>;
+		};
+
 		pinctrl at 20008000 {
 			compatible = "rockchip,rk3188-pinctrl";
 			reg = <0x20008000 0xa0>,
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 5/6] ARM: rockchip: add power-management-unit
From: Heiko Stübner @ 2014-01-15 21:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <27256277.YJ687suYy5@phil>

The pmu is needed to bring up the cores during smp operations and later
also other system parts. Therefore add a node and documentation for it.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 Documentation/devicetree/bindings/arm/rockchip/pmu.txt |   16 ++++++++++++++++
 arch/arm/boot/dts/rk3xxx.dtsi                          |    5 +++++
 2 files changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/rockchip/pmu.txt

diff --git a/Documentation/devicetree/bindings/arm/rockchip/pmu.txt b/Documentation/devicetree/bindings/arm/rockchip/pmu.txt
new file mode 100644
index 0000000..3ee9b42
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/rockchip/pmu.txt
@@ -0,0 +1,16 @@
+Rockchip power-management-unit:
+-------------------------------
+
+The pmu is used to turn off and on different power domains of the SoCs
+This includes the power to the CPU cores.
+
+Required node properties:
+- compatible value : = "rockchip,rk3066-pmu";
+- reg : physical base address and the size of the registers window
+
+Example:
+
+	pmu at 20004000 {
+		compatible = "rockchip,rk3066-pmu";
+		reg = <0x20004000 0x100>;
+	};
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 0a3d5b1..26e5a96 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -31,6 +31,11 @@
 			reg = <0x1013c000 0x100>;
 		};
 
+		pmu at 20004000 {
+			compatible = "rockchip,rk3066-pmu";
+			reg = <0x20004000 0x100>;
+		};
+
 		gic: interrupt-controller at 1013d000 {
 			compatible = "arm,cortex-a9-gic";
 			interrupt-controller;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v6 6/6] ARM: rockchip: add smp bringup code
From: Heiko Stübner @ 2014-01-15 21:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <27256277.YJ687suYy5@phil>

This adds the necessary smp-operations and startup code to use
additional cores on Rockchip SoCs.

We currently hog the power management unit in the smp code, as it is
necessary to control the power to the cpu core and nothing else is
currently using it, so a generic implementation can be done later.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ulrich Prinz <ulrich.prinz@googlemail.com>
---
 arch/arm/mach-rockchip/Makefile   |    1 +
 arch/arm/mach-rockchip/core.h     |   22 ++++
 arch/arm/mach-rockchip/headsmp.S  |   30 ++++++
 arch/arm/mach-rockchip/platsmp.c  |  208 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-rockchip/rockchip.c |    2 +
 5 files changed, 263 insertions(+)
 create mode 100644 arch/arm/mach-rockchip/core.h
 create mode 100644 arch/arm/mach-rockchip/headsmp.S
 create mode 100644 arch/arm/mach-rockchip/platsmp.c

diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 1547d4f..4377a14 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-rockchip/core.h b/arch/arm/mach-rockchip/core.h
new file mode 100644
index 0000000..e2e7c9d
--- /dev/null
+++ b/arch/arm/mach-rockchip/core.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+extern char rockchip_secondary_trampoline;
+extern char rockchip_secondary_trampoline_end;
+
+extern unsigned long rockchip_boot_fn;
+extern void rockchip_secondary_startup(void);
+
+extern struct smp_operations rockchip_smp_ops;
diff --git a/arch/arm/mach-rockchip/headsmp.S b/arch/arm/mach-rockchip/headsmp.S
new file mode 100644
index 0000000..73206e3
--- /dev/null
+++ b/arch/arm/mach-rockchip/headsmp.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ENTRY(rockchip_secondary_startup)
+	bl	v7_invalidate_l1
+	b	secondary_startup
+ENDPROC(rockchip_secondary_startup)
+
+ENTRY(rockchip_secondary_trampoline)
+	ldr	pc, 1f
+ENDPROC(rockchip_secondary_trampoline)
+	.globl	rockchip_boot_fn
+rockchip_boot_fn:
+1:	.space	4
+
+ENTRY(rockchip_secondary_trampoline_end)
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
new file mode 100644
index 0000000..3459b17
--- /dev/null
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+#include <asm/mach/map.h>
+
+#include "core.h"
+
+static void __iomem *scu_base_addr;
+static void __iomem *sram_base_addr;
+static int ncores;
+
+#define PMU_PWRDN_CON		0x08
+#define PMU_PWRDN_ST		0x0c
+
+#define PMU_PWRDN_SCU		4
+
+static void __iomem *pmu_base_addr;
+
+static inline bool pmu_power_domain_is_on(int pd)
+{
+	return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd));
+}
+
+static void pmu_set_power_domain(int pd, bool on)
+{
+	u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON);
+	if (on)
+		val &= ~BIT(pd);
+	else
+		val |=  BIT(pd);
+	writel(val, pmu_base_addr + PMU_PWRDN_CON);
+
+	while (pmu_power_domain_is_on(pd) != on) { }
+}
+
+/*
+ * Handling of CPU cores
+ */
+
+static int __cpuinit rockchip_boot_secondary(unsigned int cpu,
+					     struct task_struct *idle)
+{
+	if (!sram_base_addr || !pmu_base_addr) {
+		pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
+		return -ENXIO;
+	}
+
+	if (cpu >= ncores) {
+		pr_err("%s: cpu %d outside maximum number of cpus %d\n",
+							__func__, cpu, ncores);
+		return -ENXIO;
+	}
+
+	/* start the core */
+	pmu_set_power_domain(0 + cpu, true);
+
+	return 0;
+}
+
+/**
+ * rockchip_smp_prepare_sram - populate necessary sram block
+ * Starting cores execute the code residing at the start of the on-chip sram
+ * after power-on. Therefore make sure, this sram region is reserved and
+ * big enough. After this check, copy the trampoline code that directs the
+ * core to the real startup code in ram into the sram-region.
+ * @node: mmio-sram device node
+ */
+static int __init rockchip_smp_prepare_sram(struct device_node *node)
+{
+	unsigned int trampoline_sz = &rockchip_secondary_trampoline_end -
+					    &rockchip_secondary_trampoline;
+	const __be32 *reserved_list = NULL;
+	int reserved_size;
+	int rstart = -1;
+	unsigned int rsize;
+	unsigned int i;
+
+	reserved_list = of_get_property(node, "mmio-sram-reserved",
+					&reserved_size);
+	if (!reserved_list) {
+		pr_err("%s: wrong number of arguments in mmio-sram-reserved\n",
+		       __func__);
+		return -ENOENT;
+	}
+
+	reserved_size /= sizeof(*reserved_list);
+	if (!reserved_size || reserved_size % 2) {
+		pr_err("%s: wrong number of arguments in mmio-sram-reserved\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < reserved_size; i += 2) {
+		/* get the next reserved block */
+		rstart = be32_to_cpu(*reserved_list++);
+		rsize = be32_to_cpu(*reserved_list++);
+
+		if (!rstart)
+			break;
+	}
+
+	if (rstart) {
+		pr_err("%s: start of sram is not reserved from mmio-sram\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	if (rsize < trampoline_sz) {
+		pr_err("%s: reserved block with size 0x%x is to small for trampoline size 0x%x\n",
+		       __func__, rsize, trampoline_sz);
+		return -EINVAL;
+	}
+
+	sram_base_addr = of_iomap(node, 0);
+
+	/* set the boot function for the sram code */
+	rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup);
+
+	/* copy the trampoline to sram, that runs during startup of the core */
+	memcpy(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz);
+	flush_cache_all();
+	outer_clean_range(0, trampoline_sz);
+
+	dsb_sev();
+
+	return 0;
+}
+
+static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
+{
+	struct device_node *node;
+	unsigned int i;
+
+	node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+	if (!node) {
+		pr_err("%s: missing scu\n", __func__);
+		return;
+	}
+
+	scu_base_addr = of_iomap(node, 0);
+	if (!scu_base_addr) {
+		pr_err("%s: could not map scu registers\n", __func__);
+		return;
+	}
+
+	node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-sram");
+	if (!node) {
+		pr_err("%s: could not find sram dt node\n", __func__);
+		return;
+	}
+
+	if (rockchip_smp_prepare_sram(node))
+		return;
+
+	node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu");
+	if (!node) {
+		pr_err("%s: could not find sram dt node\n", __func__);
+		return;
+	}
+
+	pmu_base_addr = of_iomap(node, 0);
+	if (!pmu_base_addr) {
+		pr_err("%s: could not map pmu registers\n", __func__);
+		return;
+	}
+
+	/* enable the SCU power domain */
+	pmu_set_power_domain(PMU_PWRDN_SCU, true);
+
+	/*
+	 * While the number of cpus is gathered from dt, also get the number
+	 * of cores from the scu to verify this value when booting the cores.
+	 */
+	ncores = scu_get_core_count(scu_base_addr);
+
+	scu_enable(scu_base_addr);
+
+	/* Make sure that all cores except the first are really off */
+	for (i = 1; i < ncores; i++)
+		pmu_set_power_domain(0 + i, false);
+}
+
+struct smp_operations rockchip_smp_ops __initdata = {
+	.smp_prepare_cpus	= rockchip_smp_prepare_cpus,
+	.smp_boot_secondary	= rockchip_boot_secondary,
+};
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index 82c0b07..d211d6f 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -22,6 +22,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/cache-l2x0.h>
+#include "core.h"
 
 static void __init rockchip_dt_init(void)
 {
@@ -38,6 +39,7 @@ static const char * const rockchip_board_dt_compat[] = {
 };
 
 DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
+	.smp		= smp_ops(rockchip_smp_ops),
 	.init_machine	= rockchip_dt_init,
 	.dt_compat	= rockchip_board_dt_compat,
 MACHINE_END
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 3.8 136/166] clk: clk-divider: fix divisor > 255 bug
From: Kamal Mostafa @ 2014-01-15 21:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389822780-4729-1-git-send-email-kamal@canonical.com>

3.8.13.16 -stable review patch.  If anyone has any objections, please let me know.

------------------

From: James Hogan <james.hogan@imgtec.com>

commit 778037e1ccb75609846deca9e419449c1dc137fa upstream.

Commit 6d9252bd9a4bb (clk: Add support for power of two type dividers)
merged in v3.6 added the _get_val function to convert a divisor value to
a register field value depending on the flags. However it used the type
u8 for the div field, causing divisors larger than 255 to be masked
and the resultant clock rate to be too high.

E.g. in my case an 11bit divider was supposed to divide 24.576 MHz down
to 32.768KHz. The divisor was correctly calculated as 750 (0x2ee). This
was masked to 238 (0xee) resulting in a frequency of 103.26KHz.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 drivers/clk/clk-divider.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index a9204c6..f253ce1 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -87,7 +87,7 @@ static unsigned int _get_table_val(const struct clk_div_table *table,
 	return 0;
 }
 
-static unsigned int _get_val(struct clk_divider *divider, u8 div)
+static unsigned int _get_val(struct clk_divider *divider, unsigned int div)
 {
 	if (divider->flags & CLK_DIVIDER_ONE_BASED)
 		return div;
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH v9 2/4] Documentation: Add documentation for APM X-Gene SoC SATA host controller DTS binding
From: Loc Ho @ 2014-01-15 22:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4632602.a1zUZOeMuh@wuerfel>

Hi,

>> >> >> +- clocks             : Reference to the clock entry.
>> >> >> +- phys                       : PHY reference with parameter 0.
>> >> >
>> >> > The specific value of the phy-specifier shouldn't matter to this
>> >> > binding. What should matter is what it logically corresponds to.
>> >>
>> >> I not quite following this. Are you suggest that I drop the value 0.
>> >> In the binding, one needs to specify the mode of operation - 0 is for
>> >> SATA. Can you explain more?
>> >
>> > The SATA device should not care what the argument for the PHY
>> > device is. You could connect the same device to another PHY
>> > that has a different set of arguments, which is the whole point
>> > of abstracting it.
>> >
>>
>> I understand what you wrote here. We should not have an argument from
>> the host controller. Then my question is how should the PHY node
>> indicates that it needs to be configured itself as an SATA PHY?
>
> The "phys" property should specify whatever the configuration of
> the phy device is supposed to be. It's just not the business of
> the sata driver or the sata binding to know what that configuration
> is.
>

Here is what I have and I am trying to piece this together:

phy1 {
   #phy-cells = <0>;  /* No parameter as suggest by Mark */
};

sata1 {
    :::
    phys = <&phy1>;
};

What I don't get is how does one specify the mode
(SATA/USB/SGMII/etc)? As another parameter in the phy1 node?

-Loc

^ permalink raw reply

* [PATCH v5 net-next 2/4] sh_eth: Add support for r7s72100
From: Sergei Shtylyov @ 2014-01-15 22:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389766341-14001-3-git-send-email-horms+renesas@verge.net.au>

Hello.

On 01/15/2014 09:12 AM, Simon Horman wrote:

> This is a fast ethernet controller.

    I have to say it's not exact enough patch description: R7S72100 is not 
Ethernet controller itself, it's a SoC containing the Ethernet controller.

> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

> ---
> v5
> * As suggested by Sergei Shtylyov
>    - Do not use sh_eth_chip_reset_r8a7740 as it accesses non-existent
>      RMII registers. Instead use sh_eth_chip_reset.
>    - Do not use sh_eth_set_rate_gether as it accesses non-existent registers.
>    - Do not use reserved LCHNG bit of ECSR
>    - Do not use reserved LCHNGIP bit of ECSIPR
>    - Document that R8A779x also needs a 16 bit shift of the RFS bits
>    - Do not document that the R7S72100 has GECMR, it does not

   The above change list was moved from v2 section and doesn't match the real 
changes done in v5. ;-)

> v4
> * As requested by David Miller
>    - Use a boolean for the return value of sh_eth_is_rz_fast_ether()
>    - Correct coding style in sh_eth_get_stats()

> v3
> * No change

> v2
> * As suggested by Magnus Damm and Sergei Shtylyov
>    - r7s72100 ethernet is not gigabit so do not refer to it as such

> * As suggested by Magnus Damm
>    - As RZ specific register layout rather than using the gigabit layout
>      which includes registers that do not exist on this chip.
> ---
>   drivers/net/ethernet/renesas/sh_eth.c | 126 ++++++++++++++++++++++++++++++++--
>   drivers/net/ethernet/renesas/sh_eth.h |   3 +-
>   2 files changed, 121 insertions(+), 8 deletions(-)

> diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
> index 4f5cfad..a7a0555 100644
> --- a/drivers/net/ethernet/renesas/sh_eth.c
> +++ b/drivers/net/ethernet/renesas/sh_eth.c
> @@ -190,6 +190,64 @@ static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
>   	[TRIMD]		= 0x027c,
>   };
>
> +static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = {

    Shouldn't this map precede R-Car one since this SoC is newer the same way 
you've reordered *enum* values, etc.? Sorry for not noticing in the previous 
review...

[...]
> +	[ARSTR]		= 0x0000,
> +	[TSU_CTRST]	= 0x0004,
> +	[TSU_VTAG0]	= 0x0058,
> +	[TSU_ADSBSY]	= 0x0060,
> +	[TSU_TEN]	= 0x0064,
> +	[TXNLCR0]	= 0x0080,
> +	[TXALCR0]	= 0x0084,
> +	[RXNLCR0]	= 0x0088,
> +	[RXALCR0]	= 0x008C,

    Well, the above counter register subgroup stands out from the TSU_* 
registers in the Gigabit mapping, not sure if we should follow that. These 
registers are not currently used anyway...

> +	[TSU_ADRH0]	= 0x0100,
> +	[TSU_ADRL0]	= 0x0104,
> +	[TSU_ADRH31]	= 0x01f8,
> +	[TSU_ADRL31]	= 0x01fc,
> +};
> +
>   static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
>   	[ECMR]		= 0x0100,
>   	[RFLR]		= 0x0108,
> @@ -318,6 +376,14 @@ static bool sh_eth_is_gether(struct sh_eth_private *mdp)
>   		return false;
>   }
>
> +static bool sh_eth_is_rz_fast_ether(struct sh_eth_private *mdp)
> +{
> +	if (mdp->reg_offset == sh_eth_offset_fast_rz)
> +		return true;
> +	else
> +		return false;

    Perhaps you should compress the above functions to one-liners as Joe has 
suggested. Or I/you could do it in a separate patch...

> +}
> +
>   static void sh_eth_select_mii(struct net_device *ndev)
>   {
>   	u32 value = 0x0;
[...]
> @@ -1309,9 +1409,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
>
>   		/* In case of almost all GETHER/ETHERs, the Receive Frame State
>   		 * (RFS) bits in the Receive Descriptor 0 are from bit 9 to
> -		 * bit 0. However, in case of the R8A7740's GETHER, the RFS
> -		 * bits are from bit 25 to bit 16. So, the driver needs right
> -		 * shifting by 16.
> +		 * bit 0. However, in case of the R8A7740, R8A779x and

    Small nit: comma needed before "and" as far as I know English grammar.

> +		 * R7S72100 the RFS bits are from bit 25 to bit 16. So, the
> +		 * driver needs right shifting by 16.
>   		 */
>   		if (mdp->cd->shift_rd0)
>   			desc_status >>= 16;

    Other than that, this looks fine now, you can add my:

Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

WBR, Sergei

^ permalink raw reply

* [PATCH v4 net-next 2/4] sh_eth: Add support for r7s72100
From: Sergei Shtylyov @ 2014-01-15 22:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140109050351.GE2132@verge.net.au>

Hello.

On 01/09/2014 08:03 AM, Simon Horman wrote:

>>> This is a fast ethernet controller.

>>> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

>> [...]

>>> diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
>>> index 4b38533..cc6d4af 100644
>>> --- a/drivers/net/ethernet/renesas/sh_eth.c
>>> +++ b/drivers/net/ethernet/renesas/sh_eth.c
>>> @@ -190,6 +190,59 @@ static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
[...]
>>> @@ -701,6 +762,35 @@ static struct sh_eth_cpu_data r8a7740_data = {
>>>   	.shift_rd0	= 1,
>>>   };
>>>
>>> +/* R7S72100 */
>>> +static struct sh_eth_cpu_data r7s72100_data = {
>>> +	.chip_reset	= sh_eth_chip_reset,
>>> +	.set_duplex	= sh_eth_set_duplex,
>>> +
>>> +	.register_type	= SH_ETH_REG_FAST_RZ,
>>> +
>>> +	.ecsr_value	= ECSR_ICD,
>>> +	.ecsipr_value	= ECSIPR_ICDIP,
>>> +	.eesipr_value	= 0xff7f009f,
>>> +
>>> +	.tx_check	= EESR_TC1 | EESR_FTC,
>>> +	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
>>> +			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
>>> +			  EESR_TDE | EESR_ECI,
>>> +	.fdr_value	= 0x0000070f,
>>> +	.rmcr_value	= RMCR_RNC,
>>> +
>>> +	.apr		= 1,
>>> +	.mpr		= 1,
>>> +	.tpauser	= 1,
>>> +	.hw_swap	= 1,
>>> +	.rpadir		= 1,
>>> +	.rpadir_value   = 2 << 16,
>>> +	.no_trimd	= 1,
>>> +	.tsu		= 1,
>>> +	.shift_rd0	= 1,

>>     Perhaps this field should be renamed to something talking about
>> check summing support (since bits 0..15 of RD0 contain a frame check
>> sum for those SoCs). Or maybe it should be just merged with the
>> 'hw_crc' field...

> I have no feelings about that one way or another.

    Do you happen to have R8A7740 manual by chance? If so, does it talk about 
RX check summing support and using RD0 for that?

> But it seems to be orthogonal to this patch.

    Of course, was a note to self. :-)

[...]
>>> @@ -880,6 +970,8 @@ static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
>>>   {
>>>   	if (sh_eth_is_gether(mdp))
>>>   		return EDTRR_TRNS_GETHER;
>>> +	else if (sh_eth_is_rz_fast_ether(mdp))
>>> +		return EDTRR_TRNS_RZ_ETHER;

>>     I'd just merge this with the GEther case.

> Sure, but in that case should we change the name.
> As both you and Magnus pointed out to me, the rz is not gigabit.

    See below.

>>>   	else
>>>   		return EDTRR_TRNS_ETHER;
>>>   }
>> [...]
>>> @@ -1062,7 +1155,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
>>>   		if (i == 0) {
>>>   			/* Tx descriptor address set */
>>>   			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
>>> -			if (sh_eth_is_gether(mdp))
>>> +			if (sh_eth_is_gether(mdp) ||
>>> +			    sh_eth_is_rz_fast_ether(mdp))
>>>   				sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);

>>     Hmm, TDFAR exists also on SH4 Ethers...

> Lets fix that separately.

    Of course, was just another not to self.

[...]
>>> diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
>>> index 0fe35b7..0bcde90 100644
>>> --- a/drivers/net/ethernet/renesas/sh_eth.h
>>> +++ b/drivers/net/ethernet/renesas/sh_eth.h
[...]
>>> @@ -191,6 +192,7 @@ enum DMAC_M_BIT {
>>>   /* EDTRR */
>>>   enum DMAC_T_BIT {
>>>   	EDTRR_TRNS_GETHER = 0x03,
>>> +	EDTRR_TRNS_RZ_ETHER = 0x03,

>>     I doubt we need a special case here. You didn't introduce one for
>> the software reset bits.

> True, but RZ is not Gigabit. So I think we either need two names
> or to choose a more generic name.

    Well, R7S72100 manual calls these bits just TR[1:0]. Don't know what SoCs 
having Gigabit call it in the manuals...

>>>   	EDTRR_TRNS_ETHER = 0x01,

    R-Car manuals seem to call the bit TRNS (as well as the prehistoric SH 
manuals probably). Perhaps we could use that difference, TRNS vs TR, don't know...

>>>   };

WBR, Sergei

^ permalink raw reply

* [PATCH] ARM: sunxi: Add driver for sunxi usb phy
From: Maxime Ripard @ 2014-01-15 22:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389740305-6993-1-git-send-email-hdegoede@redhat.com>

Hi Hans,

Please keep me in CC for all the Allwinner-related patches.

On Tue, Jan 14, 2014 at 11:58:25PM +0100, Hans de Goede wrote:
> The Allwinner A1x / A2x SoCs have 2 or 3 usb phys which are all accessed
> through a single set of registers. Besides this there are also some other
> phy related bits which need poking, which are per phy, but shared between the
> ohci and ehci controllers, so these are also controlled from this new phy
> driver.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../devicetree/bindings/phy/sun4i-usb-phy.txt      |  26 ++
>  drivers/phy/Kconfig                                |  11 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-sun4i-usb.c                        | 318 +++++++++++++++++++++
>  4 files changed, 356 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
>  create mode 100644 drivers/phy/phy-sun4i-usb.c
> 
> diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
> new file mode 100644
> index 0000000..6c54b3b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
> @@ -0,0 +1,26 @@
> +Allwinner sun4i USB PHY
> +-----------------------
> +
> +Required properties:
> +- compatible : should be one of "allwinner,sun4i-a10-usb-phy",

It is sun4i-usb-phy.

> +  "allwinner,sun5i-a13-usb-phy" or "allwinner,sun7i-a20-usb-phy"
> +- reg : 2 or 3 register offset + length pairs, 1 phy base reg pair +
> +  1 pair for the pmu-irq register of each hcd

In which order they should be set? Maybe you should use reg-names here
to clarify things. From that documentation, I have no idea how I
should put the values if I just want the common stuff and the (for
example) usb1 configuration.

> +- #phy-cells : from the generic phy bindings, must be 1
> +
> +Optional properties:
> +- clocks : phandle + clock specifier for the phy clock
> +- clock-names : "usb_phy"
> +- resets : a list of phandle + reset specifier pairs
> +- reset-names : "usb0_reset", "usb1_reset", and / or "usb2_reset"
> +
> +Example:
> +	usbphy: phy at 0x01c13400 {
> +		#phy-cells = <1>;
> +		compatible = "allwinner,sun4i-a10-usb-phy";
> +		reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>;

If you prefer not to use reg-names after all, please put a comment
stating what each pair correspond to.

> +		clocks = <&usb_clk 8>;
> +		clock-names = "usb_phy";
> +		resets = <&usb_clk 1>, <&usb_clk 2>;
> +		reset-names = "usb1_reset", "usb2_reset";
> +	};
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 330ef2d..dcce4cf 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -51,4 +51,15 @@ config PHY_EXYNOS_DP_VIDEO
>  	help
>  	  Support for Display Port PHY found on Samsung EXYNOS SoCs.
>  
> +config PHY_SUN4I_USB
> +	tristate "Allwinner sunxi SoC USB PHY driver"
> +	depends on ARCH_SUNXI
> +	select GENERIC_PHY
> +	help
> +	  Enable this to support the transceiver that is part of Allwinner
> +	  sunxi SoCs.
> +
> +	  This driver controls the entire USB PHY block, both the USB OTG
> +	  parts, as well as the 2 regular USB 2 host PHYs.
> +
>  endmenu
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index d0caae9..e9e82f0 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -7,3 +7,4 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)	+= phy-exynos-dp-video.o
>  obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
>  obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
>  obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
> +obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> new file mode 100644
> index 0000000..a15ecc1
> --- /dev/null
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -0,0 +1,318 @@
> +/*
> + * Allwinner sun4i USB phy driver
> + *
> + * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com>
> + *
> + * Based on code from
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + *
> + * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
> + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +
> +#define REG_ISCR			0x00
> +#define REG_PHYCTL			0x04
> +#define REG_PHYBIST			0x08
> +#define REG_PHYTUNE			0x0c
> +
> +#define SUNXI_AHB_ICHR8_EN		BIT(10)
> +#define SUNXI_AHB_INCR4_BURST_EN	BIT(9)
> +#define SUNXI_AHB_INCRX_ALIGN_EN	BIT(8)
> +#define SUNXI_ULPI_BYPASS_EN		BIT(0)
> +
> +#define MAX_PHYS			3
> +
> +struct sun4i_usb_phy_data {
> +	struct clk *clk;
> +	void __iomem *base;
> +	struct mutex mutex;
> +	int num_phys;
> +	u32 disc_thresh;
> +	struct sun4i_usb_phy {
> +		struct phy *phy;
> +		void __iomem *pmu_irq;
> +		struct regulator *vbus;
> +		struct reset_control *reset;
> +		int index;
> +	} phys[MAX_PHYS];
> +};
> +
> +#define to_sun4i_usb_phy_data(phy) \
> +	container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
> +
> +static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
> +				int len)
> +{
> +	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
> +	u32 temp, usbc_bit = BIT(phy->index * 2);
> +	int i;
> +
> +	mutex_lock(&phy_data->mutex);
> +
> +	for (i = 0; i < len; i++) {
> +		temp = readl(phy_data->base + REG_PHYCTL);
> +
> +		/* clear the address portion */
> +		temp &= ~(0xff << 8);
> +
> +		/* set the address */
> +		temp |= ((addr + i) << 8);
> +		writel(temp, phy_data->base + REG_PHYCTL);
> +
> +		/* set the data bit and clear usbc bit*/
> +		temp = readb(phy_data->base + REG_PHYCTL);
> +		if (data & 0x1)
> +			temp |= BIT(7);
> +		else
> +			temp &= ~BIT(7);
> +		temp &= ~usbc_bit;
> +		writeb(temp, phy_data->base + REG_PHYCTL);
> +
> +		/* pulse usbc_bit */
> +		temp = readb(phy_data->base + REG_PHYCTL);
> +		temp |= usbc_bit;
> +		writeb(temp, phy_data->base + REG_PHYCTL);
> +
> +		temp = readb(phy_data->base + REG_PHYCTL);
> +		temp &= ~usbc_bit;
> +		writeb(temp, phy_data->base + REG_PHYCTL);
> +
> +		data >>= 1;
> +	}
> +	mutex_unlock(&phy_data->mutex);
> +}
> +
> +static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
> +{
> +	u32 bits, reg_value;
> +
> +	if (!phy->pmu_irq)
> +		return;
> +
> +	bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN |
> +		SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;
> +
> +	reg_value = readl(phy->pmu_irq);
> +
> +	if (enable)
> +		reg_value |= bits;
> +	else
> +		reg_value &= ~bits;
> +
> +	writel(reg_value, phy->pmu_irq);
> +}
> +
> +static int sun4i_usb_phy_init(struct phy *_phy)
> +{
> +	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> +	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> +	int ret;
> +
> +	ret = clk_prepare_enable(data->clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = reset_control_deassert(phy->reset);
> +	if (ret) {
> +		clk_disable_unprepare(data->clk);
> +		return ret;
> +	}
> +
> +	/* Adjust PHY's magnitude and rate */
> +	sun4i_usb_phy_write(phy, 0x20, 0x14, 5);
> +
> +	/* Disconnect threshold adjustment */
> +	sun4i_usb_phy_write(phy, 0x2a, data->disc_thresh, 2);
> +
> +	sun4i_usb_phy_passby(phy, 1);
> +
> +	return 0;
> +}
> +
> +static int sun4i_usb_phy_exit(struct phy *_phy)
> +{
> +	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> +	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> +
> +	sun4i_usb_phy_passby(phy, 0);
> +	reset_control_assert(phy->reset);
> +	clk_disable_unprepare(data->clk);
> +
> +	return 0;
> +}
> +
> +static int sun4i_usb_phy_power_on(struct phy *_phy)
> +{
> +	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> +	int ret;
> +
> +	if (phy->vbus) {
> +		ret = regulator_enable(phy->vbus);
> +		if (ret)
> +			return ret;
> +
> +	}
> +
> +	return 0;
> +}
> +
> +static int sun4i_usb_phy_power_off(struct phy *_phy)
> +{
> +	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> +
> +	if (phy->vbus)
> +		regulator_disable(phy->vbus);
> +
> +	return 0;
> +}
> +
> +static struct phy_ops sun4i_usb_phy_ops = {
> +	.init		= sun4i_usb_phy_init,
> +	.exit		= sun4i_usb_phy_exit,
> +	.power_on	= sun4i_usb_phy_power_on,
> +	.power_off	= sun4i_usb_phy_power_off,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static struct phy *sun4i_usb_phy_xlate(struct device *dev,
> +					struct of_phandle_args *args)
> +{
> +	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
> +
> +	if (WARN_ON(args->args[0] == 0 || args->args[0] >= data->num_phys))
> +		return ERR_PTR(-ENODEV);
> +
> +	return data->phys[args->args[0]].phy;
> +}
> +
> +static int sun4i_usb_phy_probe(struct platform_device *pdev)
> +{
> +	struct sun4i_usb_phy_data *data;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	void __iomem *pmu_irq = NULL;
> +	struct phy_provider *phy_provider;
> +	struct reset_control *reset;
> +	struct regulator *vbus;
> +	struct phy *phy;
> +	char name[16];
> +	int i;
> +
> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	mutex_init(&data->mutex);
> +	if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) {
> +		data->num_phys = 3;
> +		data->disc_thresh = 3;
> +	} else if (of_device_is_compatible(np,
> +					"allwinner,sun5i-a13-usb-phy")) {
> +		data->num_phys = 2;
> +		data->disc_thresh = 2;
> +	} else { /* allwinner,sun7i-a20-usb-phy */
> +		data->num_phys = 3;
> +		data->disc_thresh = 2;
> +	}

Maybe we can use of_match_data() here instead of having an ever-growing
list of if-else statements?

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140115/5feda29e/attachment-0001.sig>

^ permalink raw reply

* [PATCH] ARM: shmobile: Break out R-Car SYSC PM code
From: Magnus Damm @ 2014-01-15 23:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140115083027.GC16455@verge.net.au>

Hi Simon and Morimoto-san,

On Wed, Jan 15, 2014 at 5:30 PM, Simon Horman <horms@verge.net.au> wrote:
> On Wed, Jan 15, 2014 at 04:43:08PM +0900, Magnus Damm wrote:
>> From: Magnus Damm <damm@opensource.se>
>>
>> Break out the R-Car SYSC power management code from
>> the r8a7779 SoC code. With this new shared R-Car SYSC
>> code base it is possible to hook in Generation 2 SoCs
>> as well.
>
> Is this also useful for the r8a7778 (the other Gen 1 SoC in mainline) ?

I don't know actually. =) What does Morimoto-san say about this?

Cheers,

/ magnus

^ permalink raw reply

* [PATCH v6 0/3] AArch64: KGDB support
From: Andrew Pinski @ 2014-01-15 23:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140106181201.GE1096@mudshark.cambridge.arm.com>

On Mon, Jan 6, 2014 at 10:12 AM, Will Deacon <will.deacon@arm.com> wrote:
> Hi Vijay,
>
> On Thu, Dec 19, 2013 at 11:50:48AM +0000, vijay.kilari at gmail.com wrote:
>> From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
>>
>> Based on the step-handler and break-handler hooks patch from
>> Sandeepa, KGDB debugging support is added for EL1
>> debug in AArch64 mode. Any updates that come for Patch 1 from
>> Sandeepa will be rebased in next version
>>
>> With second patch,register layout is updated to be inline with GDB tool.
>> Basic GDB connection, break point set/clear and info commands
>> are supported except step/next debugging
>>
>> With third patch, step/next debugging support is added, where in
>> pc is updated to point to the instruction to be stepped and
>> stopped.
>>
>> With fourth patch, the compile time breakpoint instruction
>> reordering is fixed by making kgbd_breakpoint() as noinline
>>
>> Tested with ARM64 simulator
>>
>> v6:
>>  - Change pstate register to 8 bytes to make endian nuetral.
>>    Use GDB below GDB patch to display pstate in Big endian mode.
>>    https://sourceware.org/ml/gdb-patches/2013-12/msg00720.html
>>    Thanks to Andrew.
>
> Thanks for getting this new version out. Just a few things before it can be
> applied:
>
>   1. Can you please use "arm64:" instead of "AArch64:" in the patch
>      subjects?
>
>   2. Can you get an ack from somebody like Jason on the final patch please?
>
>   3. Can you rebase onto the for-next/core branch at the arm64 repo:
>
>        git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
>
>      you'll get a trivial conflict against arch/arm64/kernel/Makefile.
>
>   4. Can you make sure that the gdb patch you linked to actually gets
>      merged? There is still some discussion by the looks of it.


I merged it last week:
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=a4d9ba85ec5597a6a556afe26b712e878374b9dd
.

Thanks,
Andrew Pinski

>
> Cheers,
>
> Will

^ permalink raw reply

* [UPDATED PATCHv4 6/7] hwspinlock/omap: enable module before reading SYSSTATUS register
From: Suman Anna @ 2014-01-15 23:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389658764-39199-7-git-send-email-s-anna@ti.com>

The number of hwspinlocks are determined based on the value read
from the IP block's SYSSTATUS register. However, the module may
not be enabled and clocked, and the read may result in a bus error.

This particular issue is seen rather easily on AM33XX, since the
module wakeup is software controlled, and it is disabled out of
reset. Make sure the module is enabled and clocked before reading
the SYSSTATUS register.

Signed-off-by: Suman Anna <s-anna@ti.com>
---
 drivers/hwspinlock/omap_hwspinlock.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 9f56fb2..7764291 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -101,10 +101,29 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
 	if (!io_base)
 		return -ENOMEM;
 
+	/*
+	 * make sure the module is enabled and clocked before reading
+	 * the module SYSSTATUS register
+	 */
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&pdev->dev);
+		goto iounmap_base;
+	}
+
 	/* Determine number of locks */
 	i = readl(io_base + SYSSTATUS_OFFSET);
 	i >>= SPINLOCK_NUMLOCKS_BIT_OFFSET;
 
+	/*
+	 * runtime PM will make sure the clock of this module is
+	 * enabled again iff at least one lock is requested
+	 */
+	ret = pm_runtime_put_sync(&pdev->dev);
+	if (ret < 0)
+		goto iounmap_base;
+
 	/* one of the four lsb's must be set, and nothing else */
 	if (hweight_long(i & 0xf) != 1 || i > 8) {
 		ret = -EINVAL;
@@ -124,12 +143,6 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
 	for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
 		hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
-	/*
-	 * runtime PM will make sure the clock of this module is
-	 * enabled iff at least one lock is requested
-	 */
-	pm_runtime_enable(&pdev->dev);
-
 	ret = hwspin_lock_register(bank, &pdev->dev, &omap_hwspinlock_ops,
 						base_id, num_locks);
 	if (ret)
@@ -138,9 +151,9 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
 	return 0;
 
 reg_fail:
-	pm_runtime_disable(&pdev->dev);
 	kfree(bank);
 iounmap_base:
+	pm_runtime_disable(&pdev->dev);
 	iounmap(io_base);
 	return ret;
 }
-- 
1.8.4.3

^ permalink raw reply related


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