Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] USB: Update EHCI-platform driver to devicetree.
From: Tony Prisk @ 2012-10-20  3:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350703053-4661-1-git-send-email-linux@prisktech.co.nz>

This patch adds devicetree support to the EHCI-platform driver,
and removes the now unneeded ehci-vt8500.c

Existing platform properties are maintained, with the exception
the power_(on/off) and suspend function pointers.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
 drivers/usb/host/ehci-hcd.c      |    5 --
 drivers/usb/host/ehci-platform.c |   46 ++++++++++
 drivers/usb/host/ehci-vt8500.c   |  171 --------------------------------------
 3 files changed, 46 insertions(+), 176 deletions(-)
 delete mode 100644 drivers/usb/host/ehci-vt8500.c

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6bf6c42..42c8e84 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1274,11 +1274,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		cns3xxx_ehci_driver
 #endif
 
-#ifdef CONFIG_ARCH_VT8500
-#include "ehci-vt8500.c"
-#define	PLATFORM_DRIVER		vt8500_ehci_driver
-#endif
-
 #ifdef CONFIG_PLAT_SPEAR
 #include "ehci-spear.c"
 #define PLATFORM_DRIVER		spear_ehci_hcd_driver
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 764e010..7f962dc 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -19,6 +19,7 @@
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/usb/ehci_pdriver.h>
 
 static int ehci_platform_reset(struct usb_hcd *hcd)
@@ -78,14 +79,48 @@ static const struct hc_driver ehci_platform_hc_driver = {
 	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
+static u64 ehci_dma_mask = DMA_BIT_MASK(32);
+
 static int __devinit ehci_platform_probe(struct platform_device *dev)
 {
 	struct usb_hcd *hcd;
 	struct resource *res_mem;
 	struct usb_ehci_pdata *pdata = dev->dev.platform_data;
+	struct device_node *np = dev->dev.of_node;
 	int irq;
 	int err = -ENOMEM;
 
+	/* Are we being initialized from a DT-probed device? */
+	if (np) {
+		/*
+		 * No platform data is being passed, so initalize pdata.
+		 * Limitation: we can't support power_on, power_off or
+		 * power_suspend function pointers from DT.
+		 * TODO: The missing functions could be replaced with
+		 * power sequence handlers.
+		 */
+		pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
+		dev->dev.platform_data = pdata;
+
+		/* Read the optional properties from DT node */
+		of_property_read_u32(np, "caps-offset", &pdata->caps_offset);
+		if (of_property_read_bool(np, "has-tt"))
+			pdata->has_tt = 1;
+		if (of_property_read_bool(np, "has-synopsys-hc-bug"))
+			pdata->has_synopsys_hc_bug = 1;
+		if (of_property_read_bool(np, "big-endian-desc"))
+			pdata->big_endian_desc = 1;
+		if (of_property_read_bool(np, "big-endian-mmio"))
+			pdata->big_endian_mmio = 1;
+
+		/* Right now device-tree probed devices don't get dma_mask set.
+		 * Since shared usb code relies on it, set it here for now.
+		 * Once we have dma capability bindings this can go away.
+		 */
+		if (!dev->dev.dma_mask)
+			dev->dev.dma_mask = &ehci_dma_mask;
+	}
+
 	if (!pdata) {
 		WARN_ON(1);
 		return -ENODEV;
@@ -215,6 +250,16 @@ static const struct platform_device_id ehci_platform_table[] = {
 	{ "ehci-platform", 0 },
 	{ }
 };
+
+#ifdef CONFIG_OF
+static const struct of_device_id ehci_platform_ids[] = {
+	{ .compatible = "ehci-platform", },
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, ehci_platform_ids);
+#endif
+
 MODULE_DEVICE_TABLE(platform, ehci_platform_table);
 
 static const struct dev_pm_ops ehci_platform_pm_ops = {
@@ -231,5 +276,6 @@ static struct platform_driver ehci_platform_driver = {
 		.owner	= THIS_MODULE,
 		.name	= "ehci-platform",
 		.pm	= &ehci_platform_pm_ops,
+		.of_match_table = of_match_ptr(ehci_platform_ids),
 	}
 };
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
deleted file mode 100644
index d3c9a3e..0000000
--- a/drivers/usb/host/ehci-vt8500.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * drivers/usb/host/ehci-vt8500.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * Based on ehci-au1xxx.c
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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/of.h>
-#include <linux/platform_device.h>
-
-static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
-	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-	int rc = 0;
-
-	if (!udev->parent) /* udev is root hub itself, impossible */
-		rc = -1;
-	/* we only support lpm device connected to root hub yet */
-	if (ehci->has_lpm && !udev->parent->parent) {
-		rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
-		if (!rc)
-			rc = ehci_lpm_check(ehci, udev->portnum);
-	}
-	return rc;
-}
-
-static const struct hc_driver vt8500_ehci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "VT8500 EHCI",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq			= ehci_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset			= ehci_setup,
-	.start			= ehci_run,
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number	= ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	/*
-	 * call back when device connected and addressed
-	 */
-	.update_device =	ehci_update_device,
-
-	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
-};
-
-static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32);
-
-static int vt8500_ehci_drv_probe(struct platform_device *pdev)
-{
-	struct usb_hcd *hcd;
-	struct ehci_hcd *ehci;
-	struct resource *res;
-	int ret;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	/*
-	 * Right now device-tree probed devices don't get dma_mask set.
-	 * Since shared usb code relies on it, set it here for now.
-	 * Once we have dma capability bindings this can go away.
-	 */
-	if (!pdev->dev.dma_mask)
-		pdev->dev.dma_mask = &vt8500_ehci_dma_mask;
-
-	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
-		pr_debug("resource[1] is not IORESOURCE_IRQ");
-		return -ENOMEM;
-	}
-	hcd = usb_create_hcd(&vt8500_ehci_hc_driver, &pdev->dev, "VT8500");
-	if (!hcd)
-		return -ENOMEM;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hcd->rsrc_start = res->start;
-	hcd->rsrc_len = resource_size(res);
-
-	hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
-	if (!hcd->regs) {
-		pr_debug("ioremap failed");
-		ret = -ENOMEM;
-		goto err1;
-	}
-
-	ehci = hcd_to_ehci(hcd);
-	ehci->caps = hcd->regs;
-
-	ret = usb_add_hcd(hcd, pdev->resource[1].start,
-			  IRQF_SHARED);
-	if (ret == 0) {
-		platform_set_drvdata(pdev, hcd);
-		return ret;
-	}
-
-err1:
-	usb_put_hcd(hcd);
-	return ret;
-}
-
-static int vt8500_ehci_drv_remove(struct platform_device *pdev)
-{
-	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
-	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
-static const struct of_device_id vt8500_ehci_ids[] = {
-	{ .compatible = "via,vt8500-ehci", },
-	{ .compatible = "wm,prizm-ehci", },
-	{}
-};
-
-static struct platform_driver vt8500_ehci_driver = {
-	.probe		= vt8500_ehci_drv_probe,
-	.remove		= vt8500_ehci_drv_remove,
-	.shutdown	= usb_hcd_platform_shutdown,
-	.driver = {
-		.name	= "vt8500-ehci",
-		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(vt8500_ehci_ids),
-	}
-};
-
-MODULE_ALIAS("platform:vt8500-ehci");
-MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
-- 
1.7.9.5

^ permalink raw reply related

* [RFC PATCH 0/2] Update ehci-platform driver to support devicetree
From: Tony Prisk @ 2012-10-20  3:17 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset updates the ehci-platform.c driver to allow device tree probing.
I have dropped support for the three function pointers (power_on, power_off
and power_suspend). If someone has knowledge of the power sequence functions
that are being implemented, these functions could be replaced (Sorry, I don't
know anything about implementing it).

port_power_(on_off) properties are not supported in DT as Alan Stern indicated
they are going to be removed.

I have included a binding document, but must admit most of the descriptions
for the properties are guessed. Quite likely some of these descriptions are
incorrect and/or need to be clarified.

Tony Prisk (2):
  USB: Update EHCI-platform driver to devicetree.
  USB: doc: Binding document for ehci-platform driver

 .../devicetree/bindings/usb/ehci-platform.txt      |   22 +++
 drivers/usb/host/ehci-hcd.c                        |    5 -
 drivers/usb/host/ehci-platform.c                   |   46 ++++++
 drivers/usb/host/ehci-vt8500.c                     |  171 --------------------
 4 files changed, 68 insertions(+), 176 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/ehci-platform.txt
 delete mode 100644 drivers/usb/host/ehci-vt8500.c

-- 
1.7.9.5

^ permalink raw reply

* [PATCH 2/2] ARM: bcm2835: Fix typo in the error message
From: Domenico Andreoli @ 2012-10-20  1:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121020013526.829093485@gmail.com>

An embedded and charset-unspecified text was scrubbed...
Name: arm-bcm2835-fix-typo-in-error-message.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121020/ae0a800e/attachment.ksh>

^ permalink raw reply

* [PATCH 1/2] ARM: bcm2835: Add missing static modifiers
From: Domenico Andreoli @ 2012-10-20  1:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121020013526.829093485@gmail.com>

An embedded and charset-unspecified text was scrubbed...
Name: arm-bcm2835-add-missing-statics.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121020/7f43dd41/attachment.ksh>

^ permalink raw reply

* [PATCH 0/2] ARM: bcm2835: Fixes
From: Domenico Andreoli @ 2012-10-20  1:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stephen,

  here are few things I found reviewing my clone of your code.

cheers,
Domenico

^ permalink raw reply

* [GIT PULL] ARM: soc fixes for -rc2
From: Olof Johansson @ 2012-10-20  0:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

The following changes since commit ddffeb8c4d0331609ef2581d84de4d763607bd37:

  Linux 3.7-rc1 (2012-10-14 14:41:04 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/fixes-for-linus

for you to fetch changes up to 70f3900ee5c78d498dbbf880ec409f4b8f4da21e:

  Merge tag 'kirkwood_fixes_for_v3.7' of git://git.infradead.org/users/jcooper/linux into fixes (2012-10-19 16:17:51 -0700)

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

ARM: soc: Fixes for 3.7-rc2

A set of fixes and some minor cleanups for -rc2:

- A series from Arnd that fixes warnings in drivers and other code
  included by ARM defconfigs. Most have been acked by corresponding
  maintainers (and seem quite hard to argue not picking up anyway in the
  few exception cases).
- A few misc patches from the list for integrator/vt8500/i.MX
- A batch of fixes to OMAP platforms, fixing:
  - boot problems on beaglebone,
  - regression fixes for local timers
  - clockdomain locking fixes
  - a few boot/sparse warnings
- For Tegra:
  - Clock rate calculation overflow fix
  - Revert a change that removed timer clocks and a fix for symbol name clashes
- For Renesas:
  - IO accessor / annotation cleanups to remove warnings
- For Kirkwood/Dove/mvebu:
  - Fixes for device trees for Dove (some minor cleanups, some fixes)
  - Fixes for the mvebu gpio driver
  - Fix build problem for Feroceon due to missing ifdefs
  - Fix lsxl DTS files

----------------------------------------------------------------
Arnd Bergmann (7):
      SCSI: ARM: ncr5380/oak uses no interrupts
      SCSI: ARM: make fas216_dumpinfo function conditional
      mm/slob: use min_t() to compare ARCH_SLAB_MINALIGN
      USB: EHCI: mark ehci_orion_conf_mbus_windows __devinit
      pcmcia: sharpsl: don't discard sharpsl_pcmcia_ops
      spi/s3c64xx: use correct dma_transfer_direction type
      ARM: s3c: mark s3c2440_clk_add as __init_refok

Axel Lin (1):
      gpio: mvebu: Add missing breaks in mvebu_gpio_irq_set_type

Benoit Cousson (1):
      ARM: OMAP2+: clock data: Add dev-id for the omap-gpmc dummy fck

Jason Gunthorpe (1):
      ARM: Kirkwood: fix disabling CACHE_FEROCEON_L2

Jon Hunter (1):
      ARM: OMAP2+: Allow kernel to boot even if GPMC fails to reserve memory

Kuninori Morimoto (2):
      ARM: shmobile: armadillo800eva: __io abuse cleanup
      ARM: shmobile: r8a7779: use __iomem pointers for MMIO

Linus Walleij (1):
      ARM: dts: compile Integrator device trees

Mark Zhang (1):
      ARM: tegra30: clk: Fix output_rate overflow

Michael Walle (2):
      ARM: kirkwood: fix LEDs names for lsxl boards
      ARM: kirkwood: fix buttons on lsxl boards

Olof Johansson (7):
      Merge branch 'fixes' of git://git.kernel.org/.../horms/renesas into fixes
      Merge tag 'tegra-for-3.7-fixes-for-rc2' of git://git.kernel.org/.../swarren/linux-tegra into fixes
      Merge tag 'omap-for-v3.7-rc1/fixes-take5-signed' of git://git.kernel.org/.../tmlind/linux-omap into fixes
      Merge tag 'mvebu_dove_late_fixes_for_v3.7' of git://git.infradead.org/users/jcooper/linux into fixes
      Merge tag 'mvebu_gpio_fixes_for_v3.7' of git://git.infradead.org/users/jcooper/linux into fixes
      Merge branch 'testing/driver-warnings' of git://git.kernel.org/.../arm/arm-soc into fixes
      Merge tag 'kirkwood_fixes_for_v3.7' of git://git.infradead.org/users/jcooper/linux into fixes

Paul Walmsley (1):
      ARM: OMAP: resolve sparse warning concerning debug_card_init()

Sebastian Hesselbarth (6):
      ARM: dove: Add pcie clock support
      ARM: dove: Fix tauros2 device tree init
      ARM: dove: Fix clock names of sata and gbe
      ARM: dove: Restructure SoC device tree descriptor
      ARM: dove: Remove watchdog from DT
      ARM: dove: Add crypto engine to DT

Sebastien Guiriec (1):
      ARM: OMAP4: devices: fixup OMAP4 DMIC platform device error message

Shawn Guo (1):
      ARM: dts: imx6q-arm2: move NANDF_CS pins out of 'hog'

Sivaram Nair (2):
      ARM: tegra: rename tegra system timer
      ARM: tegra: add tegra_timer clock

Tero Kristo (1):
      ARM: OMAP: clockdomain: Fix locking on _clkdm_clk_hwmod_enable / disable

Tony Lindgren (1):
      ARM: OMAP4: Fix twd_local_timer_register regression

Tony Prisk (1):
      dtb: fix interrupt assignment for ehci/uhci on wm8505

 arch/arm/boot/dts/Makefile                     |  2 ++
 arch/arm/boot/dts/dove.dtsi                    | 49 +++++++++++++++++---------
 arch/arm/boot/dts/imx6q-arm2.dts               | 10 +++++-
 arch/arm/boot/dts/kirkwood-lsxl.dtsi           | 18 +++++-----
 arch/arm/boot/dts/wm8505.dtsi                  |  4 +--
 arch/arm/mach-dove/common.c                    |  8 ++---
 arch/arm/mach-dove/pcie.c                      |  5 +++
 arch/arm/mach-kirkwood/board-dt.c              |  2 --
 arch/arm/mach-kirkwood/common.c                |  4 +--
 arch/arm/mach-omap2/clock44xx_data.c           |  2 +-
 arch/arm/mach-omap2/clockdomain.c              | 15 +++++---
 arch/arm/mach-omap2/devices.c                  |  2 +-
 arch/arm/mach-omap2/gpmc.c                     | 24 ++++++++++---
 arch/arm/mach-omap2/timer.c                    |  2 +-
 arch/arm/mach-s3c24xx/clock-s3c2440.c          |  2 +-
 arch/arm/mach-shmobile/board-armadillo800eva.c |  2 +-
 arch/arm/mach-shmobile/clock-r8a7779.c         | 22 ++++++------
 arch/arm/mach-tegra/board-dt-tegra20.c         |  2 +-
 arch/arm/mach-tegra/board-dt-tegra30.c         |  2 +-
 arch/arm/mach-tegra/board.h                    |  2 +-
 arch/arm/mach-tegra/tegra20_clocks_data.c      |  1 +
 arch/arm/mach-tegra/tegra30_clocks.c           |  2 +-
 arch/arm/mach-tegra/tegra30_clocks_data.c      |  1 +
 arch/arm/mach-tegra/timer.c                    |  2 +-
 arch/arm/plat-omap/debug-devices.c             |  1 +
 drivers/gpio/gpio-mvebu.c                      |  3 ++
 drivers/pcmcia/pxa2xx_sharpsl.c                |  2 +-
 drivers/scsi/arm/fas216.c                      |  2 +-
 drivers/scsi/arm/oak.c                         |  1 +
 drivers/spi/spi-s3c64xx.c                      |  6 ++--
 drivers/usb/host/ehci-orion.c                  |  2 +-
 mm/slob.c                                      |  6 ++--
 32 files changed, 133 insertions(+), 75 deletions(-)

^ permalink raw reply

* [RFC] ARM: sched_clock: update epoch_cyc on resume
From: Kevin Hilman @ 2012-10-19 23:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGsJ_4z_tF3LKy-vygr=kwah7q7U03Y2K2XKAkZTB1QC2pSYmw@mail.gmail.com>

Barry Song <21cnbao@gmail.com> writes:

> 2012/7/18 Colin Cross <ccross@android.com>:
>> Many clocks that are used to provide sched_clock will reset during
>> suspend.  If read_sched_clock returns 0 after suspend, sched_clock will
>> appear to jump forward.  This patch resets cd.epoch_cyc to the current
>> value of read_sched_clock during resume, which causes sched_clock() just
>> after suspend to return the same value as sched_clock() just before
>> suspend.
>>
>> In addition, during the window where epoch_ns has been updated before
>> suspend, but epoch_cyc has not been updated after suspend, it is unknown
>> whether the clock has reset or not, and sched_clock() could return a
>> bogus value.  Add a suspended flag, and return the pre-suspend epoch_ns
>> value during this period.
>
> Acked-by: Barry Song <21cnbao@gmail.com>
>
> this patch should also fix the issue that:
> 1. launch some rt threads, rt threads sleep before suspend
> 2. repeat to suspend/resume
> 3. after resuming, waking up rt threads
>
> repeat 1-3 again and again, sometimes all rt threads will hang after
> resuming due to wrong sched_clock will make sched_rt think rt_time is
> much more than rt_runtime (default 950ms in 1s). then rt threads will
> lost cpu timeslot to run since the 95% threshold is there.

Re-visiting this in light of a related problem.

I've run into a similar issue where IRQ threads are prevented from
running during resume becase the RT throttling kicks because RT
runtime is accumulated during suspend.  Using the 'needs_suspend'
version fixes this problem too.

However, because of the RT throttling issue, it seems like *all*
platforms should be using the 'needs_suspend' version always.  But, as
already pointed out, that makes the timed printk output during
suspend/resume rather unhelpful.

Having to choose between useful printk times during suspend/resume and
functioning IRQ threads during suspend/resume isn't a choice I want to
make.   I'd rather have both.  Any ideas?

Kevin

^ permalink raw reply

* RT throttling and suspend/resume (was Re: [PATCH] i2c: omap: revert "i2c: omap: switch to threaded IRQ support")
From: Kevin Hilman @ 2012-10-19 23:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350655227.2768.11.camel@twins>

Peter Zijlstra <peterz@infradead.org> writes:

> On Thu, 2012-10-18 at 08:51 +0300, Felipe Balbi wrote:
>> > So the primary question remains: is RT runtime supposed to include the
>> > time spent suspended?  I suspect not. 
>> 
>> you might be right there, though we need Thomas or Peter to answer :-s 
>
> re, sorry both tglx and I have been traveling, he still is, I'm trying
> to play catch-up :-)
>
> Anyway, yeah I'm somewhat surprised the clock is 'running' when the
> machine isn't. From what I could gather, this is !x86 hardware, right?
>
> x86 explicitly makes sure our clocks are 'stopped' during suspend, see
> commit cd7240c0b900eb6d690ccee088a6c9b46dae815a.
>
> Can you do something similar for ARM?

So I did the same thing for my ARM SoC, and it definitley stops the RT
throttling.  

However, it has the undesriable (IMO) side effect of making timed printk
output rather unhelpful for debugging suspend/resume since printk time
stays constant throughout suspend/resume no matter how long you
sleep. :(

So does that mean we have to choose between useful printk times during
suspend/resume or functioning IRQ threads during suspend/resume ?

Kevin

^ permalink raw reply

* RT throttling and suspend/resume (was Re: [PATCH] i2c: omap: revert "i2c: omap: switch to threaded IRQ support")
From: Kevin Hilman @ 2012-10-19 23:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350655227.2768.11.camel@twins>

Peter Zijlstra <peterz@infradead.org> writes:

> On Thu, 2012-10-18 at 08:51 +0300, Felipe Balbi wrote:
>> > So the primary question remains: is RT runtime supposed to include the
>> > time spent suspended?  I suspect not. 
>> 
>> you might be right there, though we need Thomas or Peter to answer :-s 
>
> re, sorry both tglx and I have been traveling, he still is, I'm trying
> to play catch-up :-)

No worries, thanks for the help.

> Anyway, yeah I'm somewhat surprised the clock is 'running' when the
> machine isn't. From what I could gather, this is !x86 hardware, right?
>
> x86 explicitly makes sure our clocks are 'stopped' during suspend, see
> commit cd7240c0b900eb6d690ccee088a6c9b46dae815a.
>
> Can you do something similar for ARM? A quick look at
> arch/arm/kernel/sched_clock.c shows there's already suspend/resume
> hooks, do they do the wrong thing?

No, they do the right thing, but only if they're asked by the
SoC-specific code that registers a sched_clock.  Changing the SoC
specific code to use the 'needs_suspend' API gets things working
perfectly.

Thanks,

Kevin

^ permalink raw reply

* [PATCH V3 5/5] ARM: tegra: move debug-macro.S to include/debug
From: Stephen Warren @ 2012-10-19 22:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350686507-3022-1-git-send-email-swarren@wwwdotorg.org>

From: Stephen Warren <swarren@nvidia.com>

Move Tegra's debug-macro.S over to the common debug macro directory.

Move Tegra's debug UART selection menu into ARM's Kconfig.debug, so that
all related options are selected in the same place.

Tegra's uncompress.h is left in mach-tegra/include/mach; it will be
removed whenever Tegra is converted to multi-platform.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: No change; just rebased on updated earlier patches.
v2: Remove redundant default selection in Kconfig.debug, fix indentation
    there.
---
 arch/arm/Kconfig.debug                             |   38 ++++++++++++++++++++
 .../mach/debug-macro.S => include/debug/tegra.S}   |    2 -
 arch/arm/mach-tegra/Kconfig                        |   29 ---------------
 3 files changed, 38 insertions(+), 31 deletions(-)
 rename arch/arm/{mach-tegra/include/mach/debug-macro.S => include/debug/tegra.S} (99%)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index b0f3857..96b9425 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -345,6 +345,13 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on SOCFPGA based platforms.
 
+	config DEBUG_TEGRA_UART
+		depends on ARCH_TEGRA
+		bool "Use Tegra UART for low-level debug"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on Tegra based platforms.
+
 	config DEBUG_VEXPRESS_UART0_DETECT
 		bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
 		depends on ARCH_VEXPRESS && CPU_CP15_MMU
@@ -409,6 +416,36 @@ choice
 
 endchoice
 
+choice
+	prompt "Low-level debug console UART"
+	depends on DEBUG_LL && DEBUG_TEGRA_UART
+
+	config TEGRA_DEBUG_UART_AUTO_ODMDATA
+	bool "Via ODMDATA"
+	help
+	  Automatically determines which UART to use for low-level debug based
+	  on the ODMDATA value. This value is part of the BCT, and is written
+	  to the boot memory device using nvflash, or other flashing tool.
+	  When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
+	  0/1/2/3/4 are UART A/B/C/D/E.
+
+	config TEGRA_DEBUG_UARTA
+		bool "UART A"
+
+	config TEGRA_DEBUG_UARTB
+		bool "UART B"
+
+	config TEGRA_DEBUG_UARTC
+		bool "UART C"
+
+	config TEGRA_DEBUG_UARTD
+		bool "UART D"
+
+	config TEGRA_DEBUG_UARTE
+		bool "UART E"
+
+endchoice
+
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/icedcc.S" if DEBUG_ICEDCC
@@ -418,6 +455,7 @@ config DEBUG_LL_INCLUDE
 	default "debug/socfpga.S" if DEBUG_SOCFPGA_UART
 	default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \
 		DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1
+	default "debug/tegra.S" if DEBUG_TEGRA_UART
 	default "mach/debug-macro.S"
 
 config EARLY_PRINTK
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/include/debug/tegra.S
similarity index 99%
rename from arch/arm/mach-tegra/include/mach/debug-macro.S
rename to arch/arm/include/debug/tegra.S
index f67fd6d..883d7c2 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/tegra.S
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-tegra/include/mach/debug-macro.S
- *
  * Copyright (C) 2010,2011 Google, Inc.
  * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
  *
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 97fcd16..e426d1b 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -57,35 +57,6 @@ config TEGRA_AHB
 	  which controls AHB bus master arbitration and some
 	  perfomance parameters(priority, prefech size).
 
-choice
-        prompt "Low-level debug console UART"
-
-config TEGRA_DEBUG_UART_AUTO_ODMDATA
-	bool "Via ODMDATA"
-	help
-	  Automatically determines which UART to use for low-level debug based
-	  on the ODMDATA value. This value is part of the BCT, and is written
-	  to the boot memory device using nvflash, or other flashing tool.
-	  When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
-	  0/1/2/3/4 are UART A/B/C/D/E.
-
-config TEGRA_DEBUG_UARTA
-        bool "UART-A"
-
-config TEGRA_DEBUG_UARTB
-        bool "UART-B"
-
-config TEGRA_DEBUG_UARTC
-        bool "UART-C"
-
-config TEGRA_DEBUG_UARTD
-        bool "UART-D"
-
-config TEGRA_DEBUG_UARTE
-        bool "UART-E"
-
-endchoice
-
 config TEGRA_EMC_SCALING_ENABLE
 	bool "Enable scaling the memory frequency"
 
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH V3 4/5] ARM: tegra: don't include iomap.h from debug-macro.S
From: Stephen Warren @ 2012-10-19 22:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350686507-3022-1-git-send-email-swarren@wwwdotorg.org>

From: Stephen Warren <swarren@nvidia.com>

In order to move Tegra's debug-macro.S to a common location for single
zImage, it must not rely on any machine-specific header files such as
<mach/iomap.h>. Duplicate the few physical address definitions that
debug-macro.S relies upon directly into the file.

To avoid tegra_io_desc[] requiring shared knowledge of the UART
mapping's virtual address, use a virtual address outside the ranges
in tegra_io_desc[]. Call debug_ll_io_init() to propagate the mapping
beyond the early pages tables.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: New patch.
---
 arch/arm/mach-tegra/include/mach/debug-macro.S |   24 +++++++++++++++++++-----
 arch/arm/mach-tegra/io.c                       |    1 +
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index d4c23d6..f67fd6d 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -26,10 +26,18 @@
 
 #include <linux/serial_reg.h>
 
-#include "../../iomap.h"
-
 #define UART_SHIFT 2
 
+/* Physical addresses */
+#define TEGRA_CLK_RESET_BASE		0x60006000
+#define TEGRA_APB_MISC_BASE		0x70000000
+#define TEGRA_UARTA_BASE		0x70006000
+#define TEGRA_UARTB_BASE		0x70006040
+#define TEGRA_UARTC_BASE		0x70006200
+#define TEGRA_UARTD_BASE		0x70006300
+#define TEGRA_UARTE_BASE		0x70006400
+#define TEGRA_PMC_BASE			0x7000e400
+
 #define TEGRA_CLK_RST_DEVICES_L		(TEGRA_CLK_RESET_BASE + 0x04)
 #define TEGRA_CLK_RST_DEVICES_H		(TEGRA_CLK_RESET_BASE + 0x08)
 #define TEGRA_CLK_RST_DEVICES_U		(TEGRA_CLK_RESET_BASE + 0x0c)
@@ -39,6 +47,12 @@
 #define TEGRA_PMC_SCRATCH20		(TEGRA_PMC_BASE + 0xa0)
 #define TEGRA_APB_MISC_GP_HIDREV	(TEGRA_APB_MISC_BASE + 0x804)
 
+/*
+ * Must be 1MB-aligned since a 1MB mapping is used early on.
+ * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[].
+ */
+#define UART_VIRTUAL_BASE		0xfe100000
+
 #define checkuart(rp, rv, lhu, bit, uart) \
 		/* Load address of CLK_RST register */ \
 		movw	rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \
@@ -139,10 +153,10 @@
 91:		str	\rp, [\tmp, #4]		@ Store in tegra_uart_phys
 		cmp	\rp, #0			@ Valid UART address?
 		bne	92f			@ Yes, go process it
-		str	\rp, [\tmp, #8]		@ Store 0 in tegra_uart_phys
+		str	\rp, [\tmp, #8]		@ Store 0 in tegra_uart_virt
 		b	100f			@ Done
-92:		sub	\rv, \rp, #IO_APB_PHYS	@ Calculate virt address
-		add	\rv, \rv, #IO_APB_VIRT
+92:		and	\rv, \rp, #0xffffff	@ offset within 1MB section
+		add	\rv, \rv, #UART_VIRTUAL_BASE
 		str	\rv, [\tmp, #8]		@ Store in tegra_uart_virt
 		movw	\rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff
 		movt	\rv, #TEGRA_APB_MISC_GP_HIDREV >> 16
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
index 7d09f30..bb9c9c2 100644
--- a/arch/arm/mach-tegra/io.c
+++ b/arch/arm/mach-tegra/io.c
@@ -59,5 +59,6 @@ static struct map_desc tegra_io_desc[] __initdata = {
 
 void __init tegra_map_common_io(void)
 {
+	debug_ll_io_init();
 	iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
 }
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH V3 3/5] ARM: tegra: decouple uncompress.h and debug-macro.S
From: Stephen Warren @ 2012-10-19 22:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350686507-3022-1-git-send-email-swarren@wwwdotorg.org>

From: Stephen Warren <swarren@nvidia.com>

Prior to this change, Tegra's debug-macro.S relied on uncompress.h having
determined which UART to use, and whether it was safe to use the UART
(i.e. is it not in reset, and is clocked). This determination was
communicated from uncompress.h to debug-macro.S using a few bytes of
Tegra's IRAM (an on-SoC RAM). This had the disadvantage that uncompress.h
was a required part of the kernel boot process; booting a non-compressed
kernel would not allow earlyprintk to operate.

This change duplicates the UART selection and validation logic into
debug-macro.S so that the reliance on uncompress.h is removed.

This also helps out with single-zImage work, since there is currently no
support for using any uncompress.h with single-zImage.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: No change.
---
 arch/arm/mach-tegra/common.c                   |    4 +-
 arch/arm/mach-tegra/include/mach/debug-macro.S |  151 ++++++++++++++++++++---
 arch/arm/mach-tegra/include/mach/uncompress.h  |   13 --
 arch/arm/mach-tegra/irammap.h                  |    9 --
 4 files changed, 134 insertions(+), 43 deletions(-)

diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index b493d64..a57dd7a 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -44,13 +44,15 @@
  * kernel is loaded. The data is declared here rather than debug-macro.S so
  * that multiple inclusions of debug-macro.S point at the same data.
  */
-u32 tegra_uart_config[3] = {
+u32 tegra_uart_config[4] = {
 	/* Debug UART initialization required */
 	1,
 	/* Debug UART physical address */
 	0,
 	/* Debug UART virtual address */
 	0,
+	/* Scratch space for debug macro */
+	0,
 };
 
 #ifdef CONFIG_OF
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index 44ca7b1..d4c23d6 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -27,7 +27,42 @@
 #include <linux/serial_reg.h>
 
 #include "../../iomap.h"
-#include "../../irammap.h"
+
+#define UART_SHIFT 2
+
+#define TEGRA_CLK_RST_DEVICES_L		(TEGRA_CLK_RESET_BASE + 0x04)
+#define TEGRA_CLK_RST_DEVICES_H		(TEGRA_CLK_RESET_BASE + 0x08)
+#define TEGRA_CLK_RST_DEVICES_U		(TEGRA_CLK_RESET_BASE + 0x0c)
+#define TEGRA_CLK_OUT_ENB_L		(TEGRA_CLK_RESET_BASE + 0x10)
+#define TEGRA_CLK_OUT_ENB_H		(TEGRA_CLK_RESET_BASE + 0x14)
+#define TEGRA_CLK_OUT_ENB_U		(TEGRA_CLK_RESET_BASE + 0x18)
+#define TEGRA_PMC_SCRATCH20		(TEGRA_PMC_BASE + 0xa0)
+#define TEGRA_APB_MISC_GP_HIDREV	(TEGRA_APB_MISC_BASE + 0x804)
+
+#define checkuart(rp, rv, lhu, bit, uart) \
+		/* Load address of CLK_RST register */ \
+		movw	rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \
+		movt	rp, #TEGRA_CLK_RST_DEVICES_##lhu >> 16 ; \
+		/* Load value from CLK_RST register */ \
+		ldr	rp, [rp, #0] ; \
+		/* Test UART's reset bit */ \
+		tst	rp, #(1 << bit) ; \
+		/* If set, can't use UART; jump to save no UART */ \
+		bne	90f ; \
+		/* Load address of CLK_OUT_ENB register */ \
+		movw	rp, #TEGRA_CLK_OUT_ENB_##lhu & 0xffff ; \
+		movt	rp, #TEGRA_CLK_OUT_ENB_##lhu >> 16 ; \
+		/* Load value from CLK_OUT_ENB register */ \
+		ldr	rp, [rp, #0] ; \
+		/* Test UART's clock enable bit */ \
+		tst	rp, #(1 << bit) ; \
+		/* If clear, can't use UART; jump to save no UART */ \
+		beq	90f ; \
+		/* Passed all tests, load address of UART registers */ \
+		movw	rp, #TEGRA_UART##uart##_BASE & 0xffff ; \
+		movt	rp, #TEGRA_UART##uart##_BASE >> 16 ; \
+		/* Jump to save UART address */ \
+		b 91f
 
 		.macro  addruart, rp, rv, tmp
 		adr	\rp, 99f		@ actual addr of 99f
@@ -36,22 +71,101 @@
 		ldr	\rp, [\rp, #4]		@ linked tegra_uart_config
 		sub	\tmp, \rp, \rv		@ actual tegra_uart_config
 		ldr	\rp, [\tmp]		@ Load tegra_uart_config
-		cmp	\rp, #1			@ needs intitialization?
+		cmp	\rp, #1			@ needs initialization?
 		bne	100f			@ no; go load the addresses
 		mov	\rv, #0			@ yes; record init is done
 		str	\rv, [\tmp]
-		mov	\rp, #TEGRA_IRAM_BASE	@ See if cookie is in IRAM
-		ldr	\rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET]
-		movw	\rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff
-		movt	\rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16
-		cmp	\rv, \rp		@ Cookie present?
-		bne	100f			@ No, use default UART
-		mov	\rp, #TEGRA_IRAM_BASE	@ Load UART address from IRAM
-		ldr	\rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4]
-		str	\rv, [\tmp, #4]		@ Store in tegra_uart_phys
-		sub	\rv, \rv, #IO_APB_PHYS	@ Calculate virt address
+
+#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
+		/* Check ODMDATA */
+10:		movw	\rp, #TEGRA_PMC_SCRATCH20 & 0xffff
+		movt	\rp, #TEGRA_PMC_SCRATCH20 >> 16
+		ldr	\rp, [\rp, #0]		@ Load PMC_SCRATCH20
+		ubfx	\rv, \rp, #18, #2	@ 19:18 are console type
+		cmp	\rv, #2			@ 2 and 3 mean DCC, UART
+		beq	11f			@ some boards swap the meaning
+		cmp	\rv, #3			@ so accept either
+		bne	90f
+11:		ubfx	\rv, \rp, #15, #3	@ 17:15 are UART ID
+		cmp	\rv, #0			@ UART 0?
+		beq	20f
+		cmp	\rv, #1			@ UART 1?
+		beq	21f
+		cmp	\rv, #2			@ UART 2?
+		beq	22f
+		cmp	\rv, #3			@ UART 3?
+		beq	23f
+		cmp	\rv, #4			@ UART 4?
+		beq	24f
+		b	90f			@ invalid
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTA) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART A validity */
+20:		checkuart(\rp, \rv, L, 6, A)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTB) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART B validity */
+21:		checkuart(\rp, \rv, L, 7, B)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTC) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART C validity */
+22:		checkuart(\rp, \rv, H, 23, C)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTD) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART D validity */
+23:		checkuart(\rp, \rv, U, 1, D)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTE) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART E validity */
+24:
+		checkuart(\rp, \rv, U, 2, E)
+#endif
+
+		/* No valid UART found */
+90:		mov	\rp, #0
+		/* fall through */
+
+		/* Record whichever UART we chose */
+91:		str	\rp, [\tmp, #4]		@ Store in tegra_uart_phys
+		cmp	\rp, #0			@ Valid UART address?
+		bne	92f			@ Yes, go process it
+		str	\rp, [\tmp, #8]		@ Store 0 in tegra_uart_phys
+		b	100f			@ Done
+92:		sub	\rv, \rp, #IO_APB_PHYS	@ Calculate virt address
 		add	\rv, \rv, #IO_APB_VIRT
 		str	\rv, [\tmp, #8]		@ Store in tegra_uart_virt
+		movw	\rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff
+		movt	\rv, #TEGRA_APB_MISC_GP_HIDREV >> 16
+		ldr	\rv, [\rv, #0]		@ Load HIDREV
+		ubfx	\rv, \rv, #8, #8	@ 15:8 are SoC version
+		cmp	\rv, #0x20		@ Tegra20?
+		moveq	\rv, #0x75		@ Tegra20 divisor
+		movne	\rv, #0xdd		@ Tegra30 divisor
+		str	\rv, [\tmp, #12]	@ Save divisor to scratch
+		/* uart[UART_LCR] = UART_LCR_WLEN8 | UART_LCR_DLAB; */
+		mov	\rv, #UART_LCR_WLEN8 | UART_LCR_DLAB
+		str	\rv, [\rp, #UART_LCR << UART_SHIFT]
+		/* uart[UART_DLL] = div & 0xff; */
+		ldr	\rv, [\tmp, #12]
+		and	\rv, \rv, #0xff
+		str	\rv, [\rp, #UART_DLL << UART_SHIFT]
+		/* uart[UART_DLM] = div >> 8; */
+		ldr	\rv, [\tmp, #12]
+		lsr	\rv, \rv, #8
+		str	\rv, [\rp, #UART_DLM << UART_SHIFT]
+		/* uart[UART_LCR] = UART_LCR_WLEN8; */
+		mov	\rv, #UART_LCR_WLEN8
+		str	\rv, [\rp, #UART_LCR << UART_SHIFT]
 		b	100f
 
 		.align
@@ -59,27 +173,24 @@
 		.word	tegra_uart_config
 		.ltorg
 
+		/* Load previously selected UART address */
 100:		ldr	\rp, [\tmp, #4]		@ Load tegra_uart_phys
 		ldr	\rv, [\tmp, #8]		@ Load tegra_uart_virt
 		.endm
 
-#define UART_SHIFT 2
-
 /*
  * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
- * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case.
- * We use the fact that all 5 valid UART addresses all have something in the
- * 2nd-to-lowest byte.
+ * check to make sure that the UART address is actually valid.
  */
 
 		.macro	senduart, rd, rx
-		tst	\rx, #0x0000ff00
+		cmp	\rx, #0
 		strneb	\rd, [\rx, #UART_TX << UART_SHIFT]
 1001:
 		.endm
 
 		.macro	busyuart, rd, rx
-		tst	\rx, #0x0000ff00
+		cmp	\rx, #0
 		beq	1002f
 1001:		ldrb	\rd, [\rx, #UART_LSR << UART_SHIFT]
 		and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
@@ -90,7 +201,7 @@
 
 		.macro	waituart, rd, rx
 #ifdef FLOW_CONTROL
-		tst	\rx, #0x0000ff00
+		cmp	\rx, #0
 		beq	1002f
 1001:		ldrb	\rd, [\rx, #UART_MSR << UART_SHIFT]
 		tst	\rd, #UART_MSR_CTS
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 4150c71..485003f 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -29,7 +29,6 @@
 #include <linux/serial_reg.h>
 
 #include "../../iomap.h"
-#include "../../irammap.h"
 
 #define BIT(x) (1 << (x))
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -52,17 +51,6 @@ static inline void flush(void)
 {
 }
 
-static inline void save_uart_address(void)
-{
-	u32 *buf = (u32 *)(TEGRA_IRAM_BASE + TEGRA_IRAM_DEBUG_UART_OFFSET);
-
-	if (uart) {
-		buf[0] = TEGRA_IRAM_DEBUG_UART_COOKIE;
-		buf[1] = (u32)uart;
-	} else
-		buf[0] = 0;
-}
-
 static const struct {
 	u32 base;
 	u32 reset_reg;
@@ -169,7 +157,6 @@ static inline void arch_decomp_setup(void)
 	else
 		uart = (volatile u8 *)uarts[uart_id].base;
 
-	save_uart_address();
 	if (uart == NULL)
 		return;
 
diff --git a/arch/arm/mach-tegra/irammap.h b/arch/arm/mach-tegra/irammap.h
index 0cbe632..501952a 100644
--- a/arch/arm/mach-tegra/irammap.h
+++ b/arch/arm/mach-tegra/irammap.h
@@ -23,13 +23,4 @@
 #define TEGRA_IRAM_RESET_HANDLER_OFFSET	0
 #define TEGRA_IRAM_RESET_HANDLER_SIZE	SZ_1K
 
-/*
- * These locations are written to by uncompress.h, and read by debug-macro.S.
- * The first word holds the cookie value if the data is valid. The second
- * word holds the UART physical address.
- */
-#define TEGRA_IRAM_DEBUG_UART_OFFSET	SZ_1K
-#define TEGRA_IRAM_DEBUG_UART_SIZE	8
-#define TEGRA_IRAM_DEBUG_UART_COOKIE	0x55415254
-
 #endif
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH V3 2/5] ARM: tegra: simplify DEBUG_LL UART selection options
From: Stephen Warren @ 2012-10-19 22:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350686507-3022-1-git-send-email-swarren@wwwdotorg.org>

From: Stephen Warren <swarren@nvidia.com>

Delete CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH; it's not useful any more:
* No upstream bootloader currently or will ever support this option.
* CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA is a much more direct alternative.

Merge the fixed and automatic UART selection menus into a single choice
for simplicity; now you either pick AUTO_ODMDATA or a single fixed UART,
rather than potentially having an AUTO option override whatever fixed
option was chosen.

Remove TEGRA_DEBUG_UART_NONE; if you don't want a Tegra DEBUG_LL UART,
simply don't turn on DEBUG_LL. NONE used to be the default option, so
pick AUTO_ODMDATA as the new default.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: No change.
v2: Remove redundant default selection in mach-tegra/Kconfig
---
 arch/arm/mach-tegra/Kconfig                   |   40 ++++---------------
 arch/arm/mach-tegra/common.c                  |    5 +-
 arch/arm/mach-tegra/include/mach/uncompress.h |   52 ++-----------------------
 arch/arm/mach-tegra/iomap.h                   |   14 -------
 4 files changed, 15 insertions(+), 96 deletions(-)

diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 9ff6f6e..97fcd16 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -58,11 +58,16 @@ config TEGRA_AHB
 	  perfomance parameters(priority, prefech size).
 
 choice
-        prompt "Default low-level debug console UART"
-        default TEGRA_DEBUG_UART_NONE
+        prompt "Low-level debug console UART"
 
-config TEGRA_DEBUG_UART_NONE
-        bool "None"
+config TEGRA_DEBUG_UART_AUTO_ODMDATA
+	bool "Via ODMDATA"
+	help
+	  Automatically determines which UART to use for low-level debug based
+	  on the ODMDATA value. This value is part of the BCT, and is written
+	  to the boot memory device using nvflash, or other flashing tool.
+	  When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
+	  0/1/2/3/4 are UART A/B/C/D/E.
 
 config TEGRA_DEBUG_UARTA
         bool "UART-A"
@@ -81,33 +86,6 @@ config TEGRA_DEBUG_UARTE
 
 endchoice
 
-choice
-	prompt "Automatic low-level debug console UART"
-	default TEGRA_DEBUG_UART_AUTO_NONE
-
-config TEGRA_DEBUG_UART_AUTO_NONE
-	bool "None"
-
-config TEGRA_DEBUG_UART_AUTO_ODMDATA
-	bool "Via ODMDATA"
-	help
-	  Automatically determines which UART to use for low-level debug based
-	  on the ODMDATA value. This value is part of the BCT, and is written
-	  to the boot memory device using nvflash, or other flashing tool.
-	  When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
-	  0/1/2/3/4 are UART A/B/C/D/E.
-
-config TEGRA_DEBUG_UART_AUTO_SCRATCH
-	bool "Via UART scratch register"
-	help
-	  Automatically determines which UART to use for low-level debug based
-	  on the UART scratch register value. Some bootloaders put ASCII 'D'
-	  in this register when they initialize their own console UART output.
-	  Using this option allows the kernel to automatically pick the same
-	  UART.
-
-endchoice
-
 config TEGRA_EMC_SCALING_ENABLE
 	bool "Enable scaling the memory frequency"
 
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index f688daa..b493d64 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -44,14 +44,13 @@
  * kernel is loaded. The data is declared here rather than debug-macro.S so
  * that multiple inclusions of debug-macro.S point at the same data.
  */
-#define TEGRA_DEBUG_UART_OFFSET (TEGRA_DEBUG_UART_BASE & 0xFFFF)
 u32 tegra_uart_config[3] = {
 	/* Debug UART initialization required */
 	1,
 	/* Debug UART physical address */
-	(u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET),
+	0,
 	/* Debug UART virtual address */
-	(u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET),
+	0,
 };
 
 #ifdef CONFIG_OF
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 2772575..4150c71 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -139,51 +139,19 @@ int auto_odmdata(void)
 }
 #endif
 
-#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH
-int auto_scratch(void)
-{
-	int i;
-
-	/*
-	 * Look for the first UART that:
-	 * a) Is not in reset.
-	 * b) Is clocked.
-	 * c) Has a 'D' in the scratchpad register.
-	 *
-	 * Note that on Tegra30, the first two conditions are required, since
-	 * if not true, accesses to the UART scratch register will hang.
-	 * Tegra20 doesn't have this issue.
-	 *
-	 * The intent is that the bootloader will tell the kernel which UART
-	 * to use by setting up those conditions. If nothing found, we'll fall
-	 * back to what's specified in TEGRA_DEBUG_UART_BASE.
-	 */
-	for (i = 0; i < ARRAY_SIZE(uarts); i++) {
-		if (!uart_clocked(i))
-			continue;
-
-		uart = (volatile u8 *)uarts[i].base;
-		if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
-			continue;
-
-		return i;
-	}
-
-	return -1;
-}
-#endif
-
 /*
  * Setup before decompression.  This is where we do UART selection for
  * earlyprintk and init the uart_base register.
  */
 static inline void arch_decomp_setup(void)
 {
-	int uart_id, auto_uart_id;
+	int uart_id;
 	volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
 	u32 chip, div;
 
-#if defined(CONFIG_TEGRA_DEBUG_UARTA)
+#if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+	uart_id = auto_odmdata();
+#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
 	uart_id = 0;
 #elif defined(CONFIG_TEGRA_DEBUG_UARTB)
 	uart_id = 1;
@@ -193,19 +161,7 @@ static inline void arch_decomp_setup(void)
 	uart_id = 3;
 #elif defined(CONFIG_TEGRA_DEBUG_UARTE)
 	uart_id = 4;
-#else
-	uart_id = -1;
-#endif
-
-#if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
-	auto_uart_id = auto_odmdata();
-#elif defined(CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH)
-	auto_uart_id = auto_scratch();
-#else
-	auto_uart_id = -1;
 #endif
-	if (auto_uart_id != -1)
-		uart_id = auto_uart_id;
 
 	if (uart_id < 0 || uart_id >= ARRAY_SIZE(uarts) ||
 	    !uart_clocked(uart_id))
diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h
index 5315103..db8be51 100644
--- a/arch/arm/mach-tegra/iomap.h
+++ b/arch/arm/mach-tegra/iomap.h
@@ -261,20 +261,6 @@
 #define TEGRA_SDMMC4_BASE		0xC8000600
 #define TEGRA_SDMMC4_SIZE		SZ_512
 
-#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
-# define TEGRA_DEBUG_UART_BASE 0
-#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTA_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTB_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTC_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTD_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTE_BASE
-#endif
-
 /* On TEGRA, many peripherals are very closely packed in
  * two 256MB io windows (that actually only use about 64KB
  * at the start of each).
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH V3 1/5] ARM: implement debug_ll_io_init()
From: Stephen Warren @ 2012-10-19 22:41 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <robherring2@gmail.com>

When using DEBUG_LL, the UART's (or other HW's) registers are mapped
into early page tables based on the results of assembly macro addruart.
Later, when the page tables are replaced, the same virtual address must
remain valid. Historically, this has been ensured by using defines from
<mach/iomap.h> in both the implementation of addruart, and the machine's
.map_io() function. However, with the move to single zImage, we wish to
remove <mach/iomap.h>. To enable this, the macro addruart may be used
when constructing the late page tables too; addruart is exposed as a
C function debug_ll_addr(), and used to set up the required mapping in
debug_ll_io_init(), which may called on an opt-in basis from a machine's
.map_io() function.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
[swarren: Mask map.virtual with PAGE_MASK. Checked for NULL results from
 debug_ll_addr (e.g. when selected UART isn't valid). Fixed compile when
 either !CONFIG_DEBUG_LL or CONFIG_DEBUG_SEMIHOSTING.]
Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
I assume this first patch should actually go into some arm-soc branch so
that if others want to take advantage of it this kernel cycle, they can.

v3: New patch.
---
 arch/arm/include/asm/mach/map.h |    7 +++++++
 arch/arm/kernel/debug.S         |   13 +++++++++++++
 arch/arm/mm/mmu.c               |   16 ++++++++++++++++
 3 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index 195ac2f..2fe141f 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -40,6 +40,13 @@ extern void iotable_init(struct map_desc *, int);
 extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
 				  void *caller);
 
+#ifdef CONFIG_DEBUG_LL
+extern void debug_ll_addr(unsigned long *paddr, unsigned long *vaddr);
+extern void debug_ll_io_init(void);
+#else
+static inline void debug_ll_io_init(void) {}
+#endif
+
 struct mem_type;
 extern const struct mem_type *get_mem_type(unsigned int type);
 /*
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index 66f711b..7525ce4 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -100,6 +100,13 @@ ENTRY(printch)
 		b	1b
 ENDPROC(printch)
 
+ENTRY(debug_ll_addr)
+		addruart r2, r3, ip
+		str	r2, [r0]
+		str	r3, [r1]
+		mov	pc, lr
+ENDPROC(debug_ll_addr)
+
 #else
 
 ENTRY(printascii)
@@ -119,4 +126,10 @@ ENTRY(printch)
 		mov	pc, lr
 ENDPROC(printch)
 
+ENTRY(debug_ll_addr)
+		mov	r2, #0
+		mov	r3, #0
+		mov	pc, lr
+ENDPROC(debug_ll_addr)
+
 #endif
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 941dfb9..39719bb 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -876,6 +876,22 @@ static void __init pci_reserve_io(void)
 #define pci_reserve_io() do { } while (0)
 #endif
 
+#ifdef CONFIG_DEBUG_LL
+void __init debug_ll_io_init(void)
+{
+	struct map_desc map;
+
+	debug_ll_addr(&map.pfn, &map.virtual);
+	if (!map.pfn || !map.virtual)
+		return;
+	map.pfn = __phys_to_pfn(map.pfn);
+	map.virtual &= PAGE_MASK;
+	map.length = PAGE_SIZE;
+	map.type = MT_DEVICE;
+	create_mapping(&map);
+}
+#endif
+
 static void * __initdata vmalloc_min =
 	(void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
 
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 10/10] document: devicetree: bind pinconf in pinctrl single
From: Tony Lindgren @ 2012-10-19 22:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350551224-12857-10-git-send-email-haojian.zhuang@gmail.com>

* Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:09]:
> Add comments with pinconf & gpio range in the document of
> pinctrl-single.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  .../devicetree/bindings/pinctrl/pinctrl-single.txt |   43 ++++++++++++++++++++
>  1 files changed, 43 insertions(+), 0 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
> index 5187f0d..b0e5059 100644
> --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
> @@ -15,6 +15,49 @@ Optional properties:
>    available and same for all registers; if not specified, disabling of
>    pin functions is ignored
>  
> +- pinctrl-single,gpio-mask : mask of enabling gpio function register
> +
> +- pinctrl-single,gpio-ranges : gpio range list
> +
> +- pinctrl-single,gpio : array with gpio range start, size & register
> +  offset
> +
> +- pinctrl-single,gpio-enable : value of enabling gpio function
> +
> +- pinctrl-single,gpio-disable : value of disabling gpio function
> +
> +- pinctrl-single,power-source-mask : mask of setting power source in
> +  the pinmux register
> +
> +- pinctrl-single,power-source-shift : shift of power source field in
> +  the pinmux register

Maybe use "value of", "mask for", "shift for" here?
Can somebody native english speaker maybe comment on that?

Regards,

Tony

^ permalink raw reply

* [PATCH 1/3] ARM: dts: Update board files for pwm support
From: Tony Prisk @ 2012-10-19 22:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350643135-13197-1-git-send-email-linux@prisktech.co.nz>

On Fri, 2012-10-19 at 23:38 +1300, Tony Prisk wrote:
> This patch adds pwm support to arch-vt8500 board files, and adds
> the use-case of pwm-backlight.
> 
> Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
> ---
>  arch/arm/boot/dts/vt8500-bv07.dts |    8 ++++++++
>  arch/arm/boot/dts/vt8500.dtsi     |   29 +++++++++++++++++++++++++++++
>  arch/arm/boot/dts/wm8505-ref.dts  |    8 ++++++++
>  arch/arm/boot/dts/wm8505.dtsi     |   29 +++++++++++++++++++++++++++++
>  arch/arm/boot/dts/wm8650-mid.dts  |    8 ++++++++
>  arch/arm/boot/dts/wm8650.dtsi     |   17 +++++++++++++----
>  6 files changed, 95 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/vt8500-bv07.dts b/arch/arm/boot/dts/vt8500-bv07.dts
> index 567cf4e..3cba367 100644
> --- a/arch/arm/boot/dts/vt8500-bv07.dts
> +++ b/arch/arm/boot/dts/vt8500-bv07.dts
> @@ -33,4 +33,12 @@
>  			};
>  		};
>  	};
> +
> +	backlight {
> +		compatible = "pwm-backlight";
> +		pwms = <&pwm 0 50000>;
> +
> +		brightness-levels = <0 4 8 16 32 64 128 255>;
> +		default-brightness-level = <5>;
> +	};
>  };
> diff --git a/arch/arm/boot/dts/vt8500.dtsi b/arch/arm/boot/dts/vt8500.dtsi
> index d8645e9..e196b2e 100644
> --- a/arch/arm/boot/dts/vt8500.dtsi
> +++ b/arch/arm/boot/dts/vt8500.dtsi
> @@ -40,14 +40,43 @@
>  				#address-cells = <1>;
>  				#size-cells = <0>;
>  
> +				ref25: ref25M {
> +					#clock-cells = <0>;
> +					compatible = "fixed-clock";
> +					clock-frequency = <25000000>;
> +				};
> +
>  				ref24: ref24M {
>  					#clock-cells = <0>;
>  					compatible = "fixed-clock";
>  					clock-frequency = <24000000>;
>  				};
> +
> +				pllb: pllb {
> +					#clock-cells = <0>;
> +					compatible = "via,vt8500-pll-clock";
> +					clocks = <&ref25>;
> +					reg = <0x204>;
> +				};
> +
> +				clkpwm: pwm {
> +					#clock-cells = <0>;
> +					compatible = "via,vt8500-device-clock";
> +					clocks = <&pllb>;
> +					divisor-reg = <0x348>;
> +					enable-reg = <0x250>;
> +					enable-bit = <14>;
> +				};
>  			};
>  		};
>  
> +		pwm: pwm at d8220000 {
> +			#pwm-cells = <2>;
> +			compatible = "via,vt8500-pwm";
> +			reg = <0xd8220000 0x100>;
> +			clocks = <&clkpwm>;
> +		};
> +
>  		timer at d8130100 {
>  			compatible = "via,vt8500-timer";
>  			reg = <0xd8130100 0x28>;
> diff --git a/arch/arm/boot/dts/wm8505-ref.dts b/arch/arm/boot/dts/wm8505-ref.dts
> index fd4e248..f51c0ed 100644
> --- a/arch/arm/boot/dts/wm8505-ref.dts
> +++ b/arch/arm/boot/dts/wm8505-ref.dts
> @@ -33,4 +33,12 @@
>  			};
>  		};
>  	};
> +
> +	backlight {
> +		compatible = "pwm-backlight";
> +		pwms = <&pwm 0 50000>;
> +
> +		brightness-levels = <0 4 8 16 32 64 128 255>;
> +		default-brightness-level = <5>;
> +	};
>  };
> diff --git a/arch/arm/boot/dts/wm8505.dtsi b/arch/arm/boot/dts/wm8505.dtsi
> index b459691..83c8ec5 100644
> --- a/arch/arm/boot/dts/wm8505.dtsi
> +++ b/arch/arm/boot/dts/wm8505.dtsi
> @@ -54,14 +54,43 @@
>  				#address-cells = <1>;
>  				#size-cells = <0>;
>  
> +				ref25: ref25M {
> +					#clock-cells = <0>;
> +					compatible = "fixed-clock";
> +					clock-frequency = <25000000>;
> +				};
> +
>  				ref24: ref24M {
>  					#clock-cells = <0>;
>  					compatible = "fixed-clock";
>  					clock-frequency = <24000000>;
>  				};
> +
> +				pllb: pllb {
> +					#clock-cells = <0>;
> +					compatible = "via,vt8500-pll-clock";
> +					clocks = <&ref25>;
> +					reg = <0x204>;
> +				};
> +
> +				clkpwm: pwm {
> +					#clock-cells = <0>;
> +					compatible = "via,vt8500-device-clock";
> +					clocks = <&pllb>;
> +					divisor-reg = <0x348>;
> +					enable-reg = <0x250>;
> +					enable-bit = <10>;
> +				};
>  			};
>  		};
>  
> +		pwm: pwm at d8220000 {
> +			#pwm-cells = <2>;
> +			compatible = "via,vt8500-pwm";
> +			reg = <0xd8220000 0x100>;
> +			clocks = <&clkpwm>;
> +		};
> +
>  		timer at d8130100 {
>  			compatible = "via,vt8500-timer";
>  			reg = <0xd8130100 0x28>;
> diff --git a/arch/arm/boot/dts/wm8650-mid.dts b/arch/arm/boot/dts/wm8650-mid.dts
> index cefd938..7a05dd5 100644
> --- a/arch/arm/boot/dts/wm8650-mid.dts
> +++ b/arch/arm/boot/dts/wm8650-mid.dts
> @@ -33,4 +33,12 @@
>  			};
>  		};
>  	};
> +
> +	backlight {
> +		compatible = "pwm-backlight";
> +		pwms = <&pwm 0 50000>;
> +
> +		brightness-levels = <0 4 8 16 32 64 128 255>;
> +		default-brightness-level = <5>;
> +	};
>  };
> diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi
> index 83b9467..a25d240 100644
> --- a/arch/arm/boot/dts/wm8650.dtsi
> +++ b/arch/arm/boot/dts/wm8650.dtsi
> @@ -75,14 +75,16 @@
>  					reg = <0x204>;
>  				};
>  
> -				arm: arm {
> +				clkpwm: pwm {
>  					#clock-cells = <0>;
>  					compatible = "via,vt8500-device-clock";
> -					clocks = <&plla>;
> -					divisor-reg = <0x300>;
> +					clocks = <&pllb>;
> +					divisor-reg = <0x348>;
> +					enable-reg = <0x250>;
> +					enable-bit = <10>;
>  				};
>  
> -				sdhc: sdhc {
> +				clksdhc: sdhc {
>  					#clock-cells = <0>;
>  					compatible = "via,vt8500-device-clock";
>  					clocks = <&pllb>;
> @@ -94,6 +96,13 @@
>  			};
>  		};
>  
> +		pwm: pwm at d8220000 {
> +			#pwm-cells = <2>;
> +			compatible = "via,vt8500-pwm";
> +			reg = <0xd8220000 0x100>;
> +			clocks = <&clkpwm>;
> +		};
> +
>  		timer at d8130100 {
>  			compatible = "via,vt8500-timer";
>  			reg = <0xd8130100 0x28>;

Please don't pull Patch 1/3 to any trees. I will include in a
pull-request for arm-soc with other dts updates later on.

Patch 2/3 + 3/3 can be taken now or Ack'd and I'll do a pull-request
later.

Regards
Tony P

^ permalink raw reply

* [PATCH 06/10] pinctrl: single: support gpio request and free
From: Tony Lindgren @ 2012-10-19 22:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350551224-12857-6-git-send-email-haojian.zhuang@gmail.com>

Hi,

Few minor comments below.

* Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
> Marvell's PXA/MMP silicon also match the behavior of pinctrl-single.
> Each pin binds to one register. A lot of pins could be configured
> as gpio.
> 
> Now add three properties in below.
> pinctrl-single,gpio-mask: mask of enable/disable value of gpio
> pinctrl-single,gpio-ranges: gpio range array
> pinctrl-single,gpio: <gpio base, npins in range, pin base>
> pinctrl-single,gpio-enable: <gpio enable register offset, enable
> value>
> pinctrl-single,gpio-disable: <gpio disable register offset, disable
> value>

Looks like this needs to be rebased also against v3.7-rc1 to apply
cleanly. Maybe also undo the wrapping in the description above while
at it?
 
> --- a/drivers/pinctrl/pinctrl-single.c
> +++ b/drivers/pinctrl/pinctrl-single.c
> @@ -75,6 +76,26 @@ struct pcs_function {
>  };
>  
>  /**
> + * struct pcs_gpio_range - pinctrl gpio range
> + * @range:	subrange of the GPIO number space
> + * @reg_en:	register of enabling gpio function
> + * @reg_dis:	register of disabling gpio function
> + * @val_en:	enable value on gpio function
> + * @val_dis:	disable value on gpio function
> + * @need_en:	need to handle enable value on gpio function
> + * @need_dis:	need to handle disable value on gpio function
> + */
> +struct pcs_gpio_range {
> +	struct pinctrl_gpio_range range;
> +	u32 reg_en;
> +	u32 reg_dis;

These should be void __iomem *reg_en and reg_dis to avoid casts?

You now introduce few "warning: cast removes address space of
expression" warnings when checking with sparse..

> @@ -387,9 +414,48 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
>  }
>  
>  static int pcs_request_gpio(struct pinctrl_dev *pctldev,
> -			struct pinctrl_gpio_range *range, unsigned offset)
> +			    struct pinctrl_gpio_range *range, unsigned offset)
>  {
> -	return -ENOTSUPP;
> +	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
> +	struct pcs_gpio_range *gpio = NULL;
> +	int end;
> +	unsigned data;

Should you return -ENOTSUPP if not configured for GPIO here?

> +	gpio = container_of(range, struct pcs_gpio_range, range);
> +	if (!gpio->need_en)
> +		return 0;
> +	end = range->pin_base + range->npins - 1;
> +	if (offset < range->pin_base || offset > end) {
> +		dev_err(pctldev->dev, "offset %d isn't in the range of "
> +			"%d to %d\n", offset, range->pin_base, end);
> +		return -EINVAL;
> +	}
> +	data = pcs_readl((void __iomem *)gpio->reg_en) & ~pcs->gmask;
> +	data |= gpio->val_en;
> +	pcs_writel(data, (void __iomem *)gpio->reg_en);

These casts should not be needed then.

> +	return 0;
> +}
> +
> +static void pcs_disable_gpio(struct pinctrl_dev *pctldev,
> +			     struct pinctrl_gpio_range *range, unsigned offset)
> +{
> +	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
> +	struct pcs_gpio_range *gpio = NULL;
> +	int end;
> +	unsigned data;
> +
> +	gpio = container_of(range, struct pcs_gpio_range, range);
> +	if (!gpio->need_dis)
> +		return;
> +	end = range->pin_base + range->npins - 1;
> +	if (offset < range->pin_base || offset > end) {
> +		dev_err(pctldev->dev, "offset %d isn't in the range of "
> +			"%d to %d\n", offset, range->pin_base, end);
> +		return;
> +	}
> +	data = pcs_readl((void __iomem *)gpio->reg_dis) & ~pcs->gmask;
> +	data |= gpio->val_dis;
> +	pcs_writel(data, (void __iomem *)gpio->reg_dis);

And these casts.

> +static int __devinit pcs_add_gpio_range(struct device_node *node,
> +					struct pcs_device *pcs)
> +{
> +	struct pcs_gpio_range *gpio;
> +	struct device_node *np;
> +	const __be32 *list;
> +	const char list_name[] = "pinctrl-single,gpio-ranges";
> +	const char name[] = "pinctrl-single";
> +	u32 gpiores[PCS_MAX_GPIO_VALUES];
> +	int ret, size, i, mux_bytes = 0;
> +
> +	ret = of_property_read_u32(node, "pinctrl-single,gpio-mask",
> +				&pcs->gmask);
> +	if (ret < 0)
> +		return 0;
> +	list = of_get_property(node, list_name, &size);
> +	if (!list)
> +		return -ENOENT;
> +	size = size / sizeof(*list);
> +	for (i = 0; i < size; i++) {
> +		np = of_parse_phandle(node, list_name, i);
> +		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
> +		ret = of_property_read_u32_array(np, "pinctrl-single,gpio",
> +						 gpiores, PCS_MAX_GPIO_VALUES);
> +		if (ret < 0)
> +			return -ENOENT;
> +		gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL);
> +		if (!gpio) {
> +			dev_err(pcs->dev, "failed to allocate pcs gpio\n");
> +			return -ENOMEM;
> +		}
> +		gpio->range.id = i;
> +		gpio->range.base = gpiores[0];
> +		gpio->range.npins = gpiores[1];
> +		gpio->range.name = kmemdup(name, sizeof(name), GFP_KERNEL);
> +		mux_bytes = pcs->width / BITS_PER_BYTE;
> +		gpio->range.pin_base = gpiores[2] / mux_bytes;
> +		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
> +		ret = of_property_read_u32_array(np,
> +				"pinctrl-single,gpio-enable", gpiores, 2);
> +		if (!ret) {
> +			gpio->reg_en = (u32)pcs->base + gpiores[0];
> +			gpio->val_en = gpiores[1];
> +			gpio->need_en = 1;
> +		}
> +		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
> +		ret = of_property_read_u32_array(np,
> +				"pinctrl-single,gpio-disable", gpiores, 2);
> +		if (!ret) {
> +			gpio->reg_dis = (u32)pcs->base + gpiores[0];
> +			gpio->val_dis = gpiores[1];
> +			gpio->need_dis = 1;
> +		}

I think it's the u32 casts here that introduce the sparse warnings.

Other than that looks OK to me.

Regards,

Tony

^ permalink raw reply

* [PATCH v2] ARM: OMAP2: UART: fix console UART mismatched runtime PM status
From: Kevin Hilman @ 2012-10-19 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kevin Hilman <khilman@ti.com>

The runtime PM framework assumes that the hardware state of devices
when initialized is disabled.  For all omap_devices, we idle/disable
device by default.  However, the console uart uses a "no idle" option
during omap_device init in order to allow earlyprintk usage to work
seamlessly during boot.

Because the hardware is left partially enabled after init (whatever
the bootloader settings were), the omap_device should later be fully
initialized (including mux) and the runtime PM framework should be
told that the device is active, and not disabled so that the hardware
state is in sync with runtime PM state.

To fix, after the device has been created/registered, call
omap_device_enable() to finialize init and use pm_runtime_set_active()
to tell the runtime PM core the device is enabled.

Tested on 2420/n810, 3530/Overo, 3530/Beagle, 3730/OveroSTORM,
3730/Beagle-xM, 4460/PandaES.

Suggested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
Applies to v3.7-rc1.
v2: call omap_device_enable() only after oh->mux has been initialized
    otherwise, IO ring wakeups not properly enabled.

 arch/arm/mach-omap2/serial.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 0405c81..a507cd6 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -329,6 +329,11 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
+	if (console_uart_id == bdata->id) {
+		omap_device_enable(pdev);
+		pm_runtime_set_active(&pdev->dev);
+	}
+
 	oh->dev_attr = uart;
 
 	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
-- 
1.7.9.2

^ permalink raw reply related

* [PATCH 1/2] cpufreq: return early from __cpufreq_driver_getavg()
From: Rafael J. Wysocki @ 2012-10-19 22:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <32e5bed743cc6cc4e614291a7080299f5f0d0933.1350677395.git.viresh.kumar@linaro.org>

On Saturday 20 of October 2012 01:42:05 Viresh Kumar wrote:
> There is no need to do cpufreq_get_cpu() and cpufreq_put_cpu() for drivers that
> don't support getavg() routine.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

The patch doesn't seem to follow the changelog or the other way around.

Thanks,
Rafael


> ---
>  drivers/cpufreq/cpufreq.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 85df538..f552d5f 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1511,12 +1511,14 @@ int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
>  {
>  	int ret = 0;
>  
> +	if (!(cpu_online(cpu) && cpufreq_driver->getavg))
> +		return 0;
> +
>  	policy = cpufreq_cpu_get(policy->cpu);
>  	if (!policy)
>  		return -EINVAL;
>  
> -	if (cpu_online(cpu) && cpufreq_driver->getavg)
> -		ret = cpufreq_driver->getavg(policy, cpu);
> +	ret = cpufreq_driver->getavg(policy, cpu);
>  
>  	cpufreq_cpu_put(policy);
>  	return ret;
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* [PATCH 7/7] crypto: omap_sham: Remove usage of private DMA API
From: Mark A. Greer @ 2012-10-19 21:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350683640-15044-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Remove usage of the private OMAP DMA API.
The dmaengine API will be used instead.

CC: Russell King <rmk+kernel@arm.linux.org.uk>
CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 drivers/crypto/omap-sham.c | 117 ---------------------------------------------
 1 file changed, 117 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index c782f60..627f75e 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -13,8 +13,6 @@
  * Some ideas are from old omap-sha1-md5.c driver.
  */
 
-#define OMAP_SHAM_DMA_PRIVATE
-
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/err.h>
@@ -29,10 +27,8 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
-#ifndef OMAP_SHAM_DMA_PRIVATE
 #include <linux/dmaengine.h>
 #include <linux/omap-dma.h>
-#endif
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
@@ -43,12 +39,6 @@
 #include <crypto/hash.h>
 #include <crypto/internal/hash.h>
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-#include <plat/cpu.h>
-#include <plat/dma.h>
-#include <mach/irqs.h>
-#endif
-
 #define SHA_REG_DIGEST(x)		(0x00 + ((x) * 0x04))
 #define SHA_REG_DIN(x)			(0x1C + ((x) * 0x04))
 
@@ -120,9 +110,7 @@ struct omap_sham_reqctx {
 
 	/* walk state */
 	struct scatterlist	*sg;
-#ifndef OMAP_SHAM_DMA_PRIVATE
 	struct scatterlist	sgl;
-#endif
 	unsigned int		offset;	/* offset in current sg */
 	unsigned int		total;	/* total request */
 
@@ -156,12 +144,7 @@ struct omap_sham_dev {
 	int			irq;
 	spinlock_t		lock;
 	int			err;
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	int			dma;
-	int			dma_lch;
-#else
 	struct dma_chan		*dma_lch;
-#endif
 	struct tasklet_struct	done_task;
 
 	unsigned long		flags;
@@ -329,7 +312,6 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
 	return -EINPROGRESS;
 }
 
-#ifndef OMAP_SHAM_DMA_PRIVATE
 static void omap_sham_dma_callback(void *param)
 {
 	struct omap_sham_dev *dd = param;
@@ -337,34 +319,18 @@ static void omap_sham_dma_callback(void *param)
 	set_bit(FLAGS_DMA_READY, &dd->flags);
 	tasklet_schedule(&dd->done_task);
 }
-#endif
 
 static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 			      size_t length, int final, int is_sg)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	int len32;
-#else
 	struct dma_async_tx_descriptor *tx;
 	struct dma_slave_config cfg;
 	int ret;
-#endif
 
 	dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
 						ctx->digcnt, length, final);
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	len32 = DIV_ROUND_UP(length, sizeof(u32));
-
-	omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32,
-			1, OMAP_DMA_SYNC_PACKET, dd->dma,
-				OMAP_DMA_DST_SYNC_PREFETCH);
-
-	omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_addr, 0, 0);
-
-#else
 	memset(&cfg, 0, sizeof(cfg));
 
 	cfg.dst_addr = dd->phys_base + SHA_REG_DIN(0);
@@ -404,7 +370,6 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 
 	tx->callback = omap_sham_dma_callback;
 	tx->callback_param = dd;
-#endif
 
 	omap_sham_write_ctrl(dd, length, final, 1);
 
@@ -415,12 +380,8 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 
 	set_bit(FLAGS_DMA_ACTIVE, &dd->flags);
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_start_dma(dd->dma_lch);
-#else
 	dmaengine_submit(tx);
 	dma_async_issue_pending(dd->dma_lch);
-#endif
 
 	return -EINPROGRESS;
 }
@@ -526,7 +487,6 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	if (ctx->bufcnt || ctx->offset)
 		return omap_sham_update_dma_slow(dd);
 
-#ifndef OMAP_SHAM_DMA_PRIVATE
 	/*
 	 * Don't use the sg interface when the transfer size is less
 	 * than the number of elements in a DMA frame.  Otherwise,
@@ -535,7 +495,6 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	 */
 	if (ctx->total < (DST_MAXBURST * sizeof(u32)))
 		return omap_sham_update_dma_slow(dd);
-#endif
 
 	dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n",
 			ctx->digcnt, ctx->bufcnt, ctx->total);
@@ -597,11 +556,7 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_stop_dma(dd->dma_lch);
-#else
 	dmaengine_terminate_all(dd->dma_lch);
-#endif
 
 	if (ctx->flags & BIT(FLAGS_SG)) {
 		dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
@@ -803,18 +758,6 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
 	if (err)
 		goto err1;
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_set_dma_dest_params(dd->dma_lch, 0,
-			OMAP_DMA_AMODE_CONSTANT,
-			dd->phys_base + SHA_REG_DIN(0), 0, 16);
-
-	omap_set_dma_dest_burst_mode(dd->dma_lch,
-			OMAP_DMA_DATA_BURST_16);
-
-	omap_set_dma_src_burst_mode(dd->dma_lch,
-			OMAP_DMA_DATA_BURST_4);
-#endif
-
 	if (ctx->digcnt)
 		/* request has changed - restore hash */
 		omap_sham_copy_hash(req, 0);
@@ -1205,55 +1148,13 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
-{
-	struct omap_sham_dev *dd = data;
-
-	if (ch_status != OMAP_DMA_BLOCK_IRQ) {
-		pr_err("omap-sham DMA error status: 0x%hx\n", ch_status);
-		dd->err = -EIO;
-		clear_bit(FLAGS_INIT, &dd->flags);/* request to re-initialize */
-	}
-
-	set_bit(FLAGS_DMA_READY, &dd->flags);
-	tasklet_schedule(&dd->done_task);
-}
-
-static int omap_sham_dma_init(struct omap_sham_dev *dd)
-{
-	int err;
-
-	dd->dma_lch = -1;
-
-	err = omap_request_dma(dd->dma, dev_name(dd->dev),
-			omap_sham_dma_callback, dd, &dd->dma_lch);
-	if (err) {
-		dev_err(dd->dev, "Unable to request DMA channel\n");
-		return err;
-	}
-
-	return 0;
-}
-
-static void omap_sham_dma_cleanup(struct omap_sham_dev *dd)
-{
-	if (dd->dma_lch >= 0) {
-		omap_free_dma(dd->dma_lch);
-		dd->dma_lch = -1;
-	}
-}
-#endif
-
 static int __devinit omap_sham_probe(struct platform_device *pdev)
 {
 	struct omap_sham_dev *dd;
 	struct device *dev = &pdev->dev;
 	struct resource *res;
-#ifndef OMAP_SHAM_DMA_PRIVATE
 	dma_cap_mask_t mask;
 	unsigned dma_chan;
-#endif
 	int err, i, j;
 
 	dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
@@ -1288,11 +1189,7 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		err = -ENODEV;
 		goto res_err;
 	}
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	dd->dma = res->start;
-#else
 	dma_chan = res->start;
-#endif
 
 	/* Get the IRQ */
 	dd->irq = platform_get_irq(pdev,  0);
@@ -1309,11 +1206,6 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		goto res_err;
 	}
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	err = omap_sham_dma_init(dd);
-	if (err)
-		goto dma_err;
-#else
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
@@ -1324,7 +1216,6 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		err = -ENXIO;
 		goto dma_err;
 	}
-#endif
 
 	dd->io_base = ioremap(dd->phys_base, SZ_4K);
 	if (!dd->io_base) {
@@ -1358,11 +1249,7 @@ err_algs:
 	iounmap(dd->io_base);
 	pm_runtime_disable(dev);
 io_err:
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_sham_dma_cleanup(dd);
-#else
 	dma_release_channel(dd->dma_lch);
-#endif
 dma_err:
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
@@ -1392,11 +1279,7 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
 	iounmap(dd->io_base);
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_sham_dma_cleanup(dd);
-#else
 	dma_release_channel(dd->dma_lch);
-#endif
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
 	kfree(dd);
-- 
1.7.12

^ permalink raw reply related

* [PATCH 6/7] crypto: omap-sham: Add code to use dmaengine API
From: Mark A. Greer @ 2012-10-19 21:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350683640-15044-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Add code to use the new dmaengine API alongside
the existing DMA code that uses the private
OMAP DMA API.  The API to use is chosen by
defining or undefining 'OMAP_SHAM_DMA_PRIVATE'.

CC: Russell King <rmk+kernel@arm.linux.org.uk>
CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 drivers/crypto/omap-sham.c | 150 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 145 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index acb85df..c782f60 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -13,6 +13,8 @@
  * Some ideas are from old omap-sha1-md5.c driver.
  */
 
+#define OMAP_SHAM_DMA_PRIVATE
+
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/err.h>
@@ -27,6 +29,10 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#ifndef OMAP_SHAM_DMA_PRIVATE
+#include <linux/dmaengine.h>
+#include <linux/omap-dma.h>
+#endif
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
@@ -37,9 +43,11 @@
 #include <crypto/hash.h>
 #include <crypto/internal/hash.h>
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 #include <plat/cpu.h>
 #include <plat/dma.h>
 #include <mach/irqs.h>
+#endif
 
 #define SHA_REG_DIGEST(x)		(0x00 + ((x) * 0x04))
 #define SHA_REG_DIN(x)			(0x1C + ((x) * 0x04))
@@ -47,6 +55,8 @@
 #define SHA1_MD5_BLOCK_SIZE		SHA1_BLOCK_SIZE
 #define MD5_DIGEST_SIZE			16
 
+#define	DST_MAXBURST			16 /* Really element number (en) */
+
 #define SHA_REG_DIGCNT			0x14
 
 #define SHA_REG_CTRL			0x18
@@ -110,6 +120,9 @@ struct omap_sham_reqctx {
 
 	/* walk state */
 	struct scatterlist	*sg;
+#ifndef OMAP_SHAM_DMA_PRIVATE
+	struct scatterlist	sgl;
+#endif
 	unsigned int		offset;	/* offset in current sg */
 	unsigned int		total;	/* total request */
 
@@ -143,8 +156,12 @@ struct omap_sham_dev {
 	int			irq;
 	spinlock_t		lock;
 	int			err;
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	int			dma;
 	int			dma_lch;
+#else
+	struct dma_chan		*dma_lch;
+#endif
 	struct tasklet_struct	done_task;
 
 	unsigned long		flags;
@@ -312,15 +329,32 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
 	return -EINPROGRESS;
 }
 
+#ifndef OMAP_SHAM_DMA_PRIVATE
+static void omap_sham_dma_callback(void *param)
+{
+	struct omap_sham_dev *dd = param;
+
+	set_bit(FLAGS_DMA_READY, &dd->flags);
+	tasklet_schedule(&dd->done_task);
+}
+#endif
+
 static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
-			      size_t length, int final)
+			      size_t length, int final, int is_sg)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	int len32;
+#else
+	struct dma_async_tx_descriptor *tx;
+	struct dma_slave_config cfg;
+	int ret;
+#endif
 
 	dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
 						ctx->digcnt, length, final);
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	len32 = DIV_ROUND_UP(length, sizeof(u32));
 
 	omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32,
@@ -330,6 +364,48 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 	omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC,
 				dma_addr, 0, 0);
 
+#else
+	memset(&cfg, 0, sizeof(cfg));
+
+	cfg.dst_addr = dd->phys_base + SHA_REG_DIN(0);
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.dst_maxburst = DST_MAXBURST;
+
+	ret = dmaengine_slave_config(dd->dma_lch, &cfg);
+	if (ret) {
+		pr_err("omap-sham: can't configure dmaengine slave: %d\n", ret);
+		return ret;
+	}
+
+	if (is_sg) {
+		/*
+		 * The SG entry passed in may not have the 'length' member
+		 * set correctly so use a local SG entry (sgl) with the
+		 * proper value for 'length' instead.  If this is not done,
+		 * the dmaengine may try to DMA the incorrect amount of data.
+		 */
+		sg_init_table(&ctx->sgl, 1);
+		ctx->sgl.page_link = ctx->sg->page_link;
+		ctx->sgl.offset = ctx->sg->offset;
+		sg_dma_len(&ctx->sgl) = length;
+		sg_dma_address(&ctx->sgl) = sg_dma_address(ctx->sg);
+
+		tx = dmaengine_prep_slave_sg(dd->dma_lch, &ctx->sgl, 1,
+			DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	} else {
+		tx = dmaengine_prep_slave_single(dd->dma_lch, dma_addr, length,
+			DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	}
+
+	if (!tx) {
+		dev_err(dd->dev, "prep_slave_sg/single() failed\n");
+		return -EINVAL;
+	}
+
+	tx->callback = omap_sham_dma_callback;
+	tx->callback_param = dd;
+#endif
+
 	omap_sham_write_ctrl(dd, length, final, 1);
 
 	ctx->digcnt += length;
@@ -339,7 +415,12 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 
 	set_bit(FLAGS_DMA_ACTIVE, &dd->flags);
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_start_dma(dd->dma_lch);
+#else
+	dmaengine_submit(tx);
+	dma_async_issue_pending(dd->dma_lch);
+#endif
 
 	return -EINPROGRESS;
 }
@@ -386,6 +467,8 @@ static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
 					struct omap_sham_reqctx *ctx,
 					size_t length, int final)
 {
+	int ret;
+
 	ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen,
 				       DMA_TO_DEVICE);
 	if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
@@ -395,8 +478,12 @@ static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
 
 	ctx->flags &= ~BIT(FLAGS_SG);
 
-	/* next call does not fail... so no unmap in the case of error */
-	return omap_sham_xmit_dma(dd, ctx->dma_addr, length, final);
+	ret = omap_sham_xmit_dma(dd, ctx->dma_addr, length, final, 0);
+	if (ret)
+		dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
+				 DMA_TO_DEVICE);
+
+	return ret;
 }
 
 static int omap_sham_update_dma_slow(struct omap_sham_dev *dd)
@@ -431,6 +518,7 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
 	unsigned int length, final, tail;
 	struct scatterlist *sg;
+	int ret;
 
 	if (!ctx->total)
 		return 0;
@@ -438,6 +526,17 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	if (ctx->bufcnt || ctx->offset)
 		return omap_sham_update_dma_slow(dd);
 
+#ifndef OMAP_SHAM_DMA_PRIVATE
+	/*
+	 * Don't use the sg interface when the transfer size is less
+	 * than the number of elements in a DMA frame.  Otherwise,
+	 * the dmaengine infrastructure will calculate that it needs
+	 * to transfer 0 frames which ultimately fails.
+	 */
+	if (ctx->total < (DST_MAXBURST * sizeof(u32)))
+		return omap_sham_update_dma_slow(dd);
+#endif
+
 	dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n",
 			ctx->digcnt, ctx->bufcnt, ctx->total);
 
@@ -475,8 +574,11 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 
 	final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
 
-	/* next call does not fail... so no unmap in the case of error */
-	return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final);
+	ret = omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final, 1);
+	if (ret)
+		dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
+
+	return ret;
 }
 
 static int omap_sham_update_cpu(struct omap_sham_dev *dd)
@@ -495,7 +597,12 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_stop_dma(dd->dma_lch);
+#else
+	dmaengine_terminate_all(dd->dma_lch);
+#endif
+
 	if (ctx->flags & BIT(FLAGS_SG)) {
 		dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
 		if (ctx->sg->length == ctx->offset) {
@@ -696,6 +803,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
 	if (err)
 		goto err1;
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_set_dma_dest_params(dd->dma_lch, 0,
 			OMAP_DMA_AMODE_CONSTANT,
 			dd->phys_base + SHA_REG_DIN(0), 0, 16);
@@ -705,6 +813,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
 
 	omap_set_dma_src_burst_mode(dd->dma_lch,
 			OMAP_DMA_DATA_BURST_4);
+#endif
 
 	if (ctx->digcnt)
 		/* request has changed - restore hash */
@@ -1096,6 +1205,7 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
 {
 	struct omap_sham_dev *dd = data;
@@ -1133,12 +1243,17 @@ static void omap_sham_dma_cleanup(struct omap_sham_dev *dd)
 		dd->dma_lch = -1;
 	}
 }
+#endif
 
 static int __devinit omap_sham_probe(struct platform_device *pdev)
 {
 	struct omap_sham_dev *dd;
 	struct device *dev = &pdev->dev;
 	struct resource *res;
+#ifndef OMAP_SHAM_DMA_PRIVATE
+	dma_cap_mask_t mask;
+	unsigned dma_chan;
+#endif
 	int err, i, j;
 
 	dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
@@ -1173,7 +1288,11 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		err = -ENODEV;
 		goto res_err;
 	}
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	dd->dma = res->start;
+#else
+	dma_chan = res->start;
+#endif
 
 	/* Get the IRQ */
 	dd->irq = platform_get_irq(pdev,  0);
@@ -1190,9 +1309,22 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		goto res_err;
 	}
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	err = omap_sham_dma_init(dd);
 	if (err)
 		goto dma_err;
+#else
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	dd->dma_lch = dma_request_channel(mask, omap_dma_filter_fn, &dma_chan);
+	if (!dd->dma_lch) {
+		dev_err(dev, "unable to obtain RX DMA engine channel %u\n",
+			dma_chan);
+		err = -ENXIO;
+		goto dma_err;
+	}
+#endif
 
 	dd->io_base = ioremap(dd->phys_base, SZ_4K);
 	if (!dd->io_base) {
@@ -1226,7 +1358,11 @@ err_algs:
 	iounmap(dd->io_base);
 	pm_runtime_disable(dev);
 io_err:
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_sham_dma_cleanup(dd);
+#else
+	dma_release_channel(dd->dma_lch);
+#endif
 dma_err:
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
@@ -1256,7 +1392,11 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
 	iounmap(dd->io_base);
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_sham_dma_cleanup(dd);
+#else
+	dma_release_channel(dd->dma_lch);
+#endif
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
 	kfree(dd);
-- 
1.7.12

^ permalink raw reply related

* [PATCH 5/7] crypto: omap-sham: Convert to use pm_runtime API
From: Mark A. Greer @ 2012-10-19 21:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350683640-15044-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Convert the omap-sham crypto driver to use the
pm_runtime API instead of the clk API.

CC: Kevin Hilman <khilman@deeprootsystems.com>
CC: Paul Walmsley <paul@pwsan.com>
CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 drivers/crypto/omap-sham.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index a3fd6fc..acb85df 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -22,12 +22,12 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
 #include <linux/cryptohash.h>
@@ -141,7 +141,6 @@ struct omap_sham_dev {
 	struct device		*dev;
 	void __iomem		*io_base;
 	int			irq;
-	struct clk		*iclk;
 	spinlock_t		lock;
 	int			err;
 	int			dma;
@@ -238,8 +237,6 @@ static void omap_sham_copy_ready_hash(struct ahash_request *req)
 
 static int omap_sham_hw_init(struct omap_sham_dev *dd)
 {
-	clk_enable(dd->iclk);
-
 	if (!test_bit(FLAGS_INIT, &dd->flags)) {
 		omap_sham_write_mask(dd, SHA_REG_MASK,
 			SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
@@ -653,7 +650,6 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
 	/* atomic operation is not needed here */
 	dd->flags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) |
 			BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY));
-	clk_disable(dd->iclk);
 
 	if (req->base.complete)
 		req->base.complete(&req->base, err);
@@ -1198,14 +1194,6 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 	if (err)
 		goto dma_err;
 
-	/* Initializing the clock */
-	dd->iclk = clk_get(dev, "ick");
-	if (IS_ERR(dd->iclk)) {
-		dev_err(dev, "clock intialization failed.\n");
-		err = PTR_ERR(dd->iclk);
-		goto clk_err;
-	}
-
 	dd->io_base = ioremap(dd->phys_base, SZ_4K);
 	if (!dd->io_base) {
 		dev_err(dev, "can't ioremap\n");
@@ -1213,11 +1201,12 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		goto io_err;
 	}
 
-	clk_enable(dd->iclk);
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
 	dev_info(dev, "hw accel on OMAP rev %u.%u\n",
 		(omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MAJOR) >> 4,
 		omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MINOR);
-	clk_disable(dd->iclk);
 
 	spin_lock(&sham.lock);
 	list_add_tail(&dd->list, &sham.dev_list);
@@ -1235,9 +1224,8 @@ err_algs:
 	for (j = 0; j < i; j++)
 		crypto_unregister_ahash(&algs[j]);
 	iounmap(dd->io_base);
+	pm_runtime_disable(dev);
 io_err:
-	clk_put(dd->iclk);
-clk_err:
 	omap_sham_dma_cleanup(dd);
 dma_err:
 	if (dd->irq >= 0)
@@ -1266,7 +1254,8 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
 		crypto_unregister_ahash(&algs[i]);
 	tasklet_kill(&dd->done_task);
 	iounmap(dd->io_base);
-	clk_put(dd->iclk);
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	omap_sham_dma_cleanup(dd);
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
-- 
1.7.12

^ permalink raw reply related

* [PATCH 4/7] ARM: OMAP2+: Remove unnecessary message when no SHA IP is present
From: Mark A. Greer @ 2012-10-19 21:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350683640-15044-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Remove the error message that prints when there is no SHA IP
present to make it consistent with all the other IPs.

CC: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/devices.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 40211de..8784812 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -472,8 +472,6 @@ static void __init omap_init_sham(void)
 		pdev = omap_device_build("omap-sham", -1, oh, NULL, 0, NULL,
 					 0, 0);
 		WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n");
-	} else {
-		pr_err("%s: platform not supported\n", __func__);
 	}
 }
 
-- 
1.7.12

^ permalink raw reply related

* [PATCH 3/7] ARM: OMAP3xxx: hwmod: Convert SHAM crypto device data to hwmod
From: Mark A. Greer @ 2012-10-19 21:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350683640-15044-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Convert the device data for the OMAP3 SHAM2 (SHA1/MD5) crypto IP
from explicit platform_data to hwmod. When bit 27 (OMAP3430_ST_SHA12_MASK)
of the CM_IDLEST1_CORE register is 0, the SHA2 IP is present.

CC: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/clock3xxx_data.c       |  1 +
 arch/arm/mach-omap2/devices.c              | 49 ++++--------------------
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 60 ++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 41 deletions(-)

diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 1f42c9d..63f9ec4 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3341,6 +3341,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"mmchs3_ick",	&mmchs3_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"icr_ick",	&icr_ick,	CK_34XX | CK_36XX),
 	CLK("omap-aes",	"ick",	&aes2_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"sha12_ick",	&sha12_ick,	CK_34XX | CK_36XX),
 	CLK("omap-sham",	"ick",	&sha12_ick,	CK_34XX | CK_36XX),
 	CLK(NULL,	"des2_ick",	&des2_ick,	CK_34XX | CK_36XX),
 	CLK("omap_hsmmc.1",	"ick",	&mmchs2_ick,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 5b613fa..40211de 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -36,6 +36,7 @@
 #include "devices.h"
 #include "cm2xxx_3xxx.h"
 #include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
 
 #define L3_MODULES_MAX_LEN 12
 #define L3_MODULES 3
@@ -453,40 +454,14 @@ static void omap_init_rng(void)
 	WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
 }
 
-#if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
-
-#ifdef CONFIG_ARCH_OMAP3
-static struct resource omap3_sham_resources[] = {
-	{
-		.start	= OMAP34XX_SEC_SHA1MD5_BASE,
-		.end	= OMAP34XX_SEC_SHA1MD5_BASE + 0x64,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= 49 + OMAP_INTC_START,
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= OMAP34XX_DMA_SHA1MD5_RX,
-		.flags	= IORESOURCE_DMA,
-	}
-};
-static int omap3_sham_resources_sz = ARRAY_SIZE(omap3_sham_resources);
-#else
-#define omap3_sham_resources		NULL
-#define omap3_sham_resources_sz		0
-#endif
-
-static struct platform_device sham_device = {
-	.name		= "omap-sham",
-	.id		= -1,
-};
-
-static void omap_init_sham(void)
+static void __init omap_init_sham(void)
 {
-	if (cpu_is_omap24xx() &&
-	    (omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_IDLEST4) &
-						 OMAP24XX_ST_SHA_MASK)) {
+	if ((cpu_is_omap24xx() &&
+	     (omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_IDLEST4) &
+						 OMAP24XX_ST_SHA_MASK)) ||
+	    (cpu_is_omap34xx() &&
+	     (!(omap2_cm_read_mod_reg(CORE_MOD, CM_IDLEST1) &
+						 OMAP3430_ST_SHA12_MASK)))) {
 		struct omap_hwmod *oh;
 		struct platform_device *pdev;
 
@@ -497,18 +472,10 @@ static void omap_init_sham(void)
 		pdev = omap_device_build("omap-sham", -1, oh, NULL, 0, NULL,
 					 0, 0);
 		WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n");
-	} else if (cpu_is_omap34xx()) {
-		sham_device.resource = omap3_sham_resources;
-		sham_device.num_resources = omap3_sham_resources_sz;
-		platform_device_register(&sham_device);
 	} else {
 		pr_err("%s: platform not supported\n", __func__);
-		return;
 	}
 }
-#else
-static inline void omap_init_sham(void) { }
-#endif
 
 #if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index f67b7ee..c09cc60 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3543,6 +3543,65 @@ static struct omap_hwmod_ocp_if omap3xxx_l3_main__gpmc = {
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_core -> SHAM2 (SHA1/MD5) (similar to omap24xx) */
+static struct omap_hwmod_class_sysconfig omap3_sham_sysc = {
+	.rev_offs	= 0x5c,
+	.sysc_offs	= 0x60,
+	.syss_offs	= 0x64,
+	.sysc_flags	= (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+			   SYSS_HAS_RESET_STATUS),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_sham_class = {
+	.name	= "sham",
+	.sysc	= &omap3_sham_sysc,
+};
+
+struct omap_hwmod_irq_info omap3_sham_mpu_irqs[] = {
+	{ .irq = 49 + OMAP_INTC_START, },
+	{ .irq = -1 }
+};
+
+struct omap_hwmod_dma_info omap3_sham_sdma_reqs[] = {
+	{ .name = "rx", .dma_req = OMAP34XX_DMA_SHA1MD5_RX, },
+	{ .dma_req = -1 }
+};
+
+struct omap_hwmod omap3xxx_sham_hwmod = {
+	.name		= "sham",
+	.mpu_irqs	= omap3_sham_mpu_irqs,
+	.sdma_reqs	= omap3_sham_sdma_reqs,
+	.main_clk	= "sha12_ick",
+	.prcm		= {
+		.omap2 = {
+			.module_offs = CORE_MOD,
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_SHA12_SHIFT,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_ST_SHA12_SHIFT,
+		},
+	},
+	.class		= &omap3xxx_sham_class,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_sham_addrs[] = {
+	{
+		.pa_start	= 0x480c3000,
+		.pa_end		= 0x480c3000 + 0x64 - 1,
+		.flags		= ADDR_TYPE_RT
+	},
+	{ }
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__sham = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap3xxx_sham_hwmod,
+	.clk		= "sha12_ick",
+	.addr		= omap3xxx_sham_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
 	&omap3xxx_l3_main__l4_core,
 	&omap3xxx_l3_main__l4_per,
@@ -3590,6 +3649,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
 	&omap34xx_l4_core__mcspi4,
 	&omap3xxx_l4_wkup__counter_32k,
 	&omap3xxx_l3_main__gpmc,
+	&omap3xxx_l4_core__sham,
 	NULL,
 };
 
-- 
1.7.12

^ permalink raw reply related

* [PATCH 2/7] ARM: OMAP2xxx: hwmod: Add DMA information for SHAM module
From: Mark A. Greer @ 2012-10-19 21:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350683640-15044-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Add the DMA information for the OMAP2 SHA module.

CC: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c      | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
index bb314c5..4b4fd5f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
@@ -405,5 +405,5 @@ struct omap_hwmod_ocp_if omap2xxx_l4_core__sham = {
 	.slave		= &omap2xxx_sham_hwmod,
 	.clk		= "sha_ick",
 	.addr		= omap2xxx_sham_addrs,
-	.user		= OCP_USER_MPU,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index a041670..703b269 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -873,9 +873,15 @@ struct omap_hwmod_irq_info omap2_sham_mpu_irqs[] = {
 	{ .irq = -1 }
 };
 
+struct omap_hwmod_dma_info omap2_sham_sdma_chs[] = {
+	{ .name = "rx", .dma_req = OMAP24XX_DMA_SHA1MD5_RX },
+	{ .dma_req = -1 }
+};
+
 struct omap_hwmod omap2xxx_sham_hwmod = {
 	.name		= "sham",
 	.mpu_irqs	= omap2_sham_mpu_irqs,
+	.sdma_reqs	= omap2_sham_sdma_chs,
 	.main_clk	= "l4_ck",
 	.prcm		= {
 		.omap2 = {
-- 
1.7.12

^ 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