Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 09/14] ACPI: platform: setup MSI domain for ACPI based platform device
From: Rafael J. Wysocki @ 2016-12-22 12:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482384922-21507-10-git-send-email-guohanjun@huawei.com>

On Thu, Dec 22, 2016 at 6:35 AM, Hanjun Guo <guohanjun@huawei.com> wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
>
> With the platform msi domain created, we can set up the msi domain
> for a platform device when it's probed.
>
> In order to do that, we need to get the domain that the platform
> device connecting to, so the iort_get_platform_device_domain() is
> introduced to retrieve the domain from iort.
>
> After the domain is retrieved, we need a proper way to set the
> domain to paltform device, as some platform devices such as an
> irqchip needs the msi irqdomain to be the interrupt parent domain,
> we need to get irqdomain before platform device is probed but after
> the platform device is allocated, so introduce a callback (pre_add_cb)
> in pdevinfo to prepare firmware related information which is needed
> for device probe, then set the msi domain in that callback.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Greg KH <gregkh@linuxfoundation.org>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> ---
>  drivers/acpi/acpi_platform.c    | 11 +++++++++++
>  drivers/acpi/arm64/iort.c       | 43 +++++++++++++++++++++++++++++++++++++++++
>  drivers/base/platform.c         |  3 +++
>  include/linux/acpi_iort.h       |  3 +++
>  include/linux/platform_device.h |  3 +++
>  5 files changed, 63 insertions(+)
>
> diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
> index b4c1a6a..5d8d61b4 100644
> --- a/drivers/acpi/acpi_platform.c
> +++ b/drivers/acpi/acpi_platform.c
> @@ -12,6 +12,7 @@
>   */
>
>  #include <linux/acpi.h>
> +#include <linux/acpi_iort.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
>  #include <linux/kernel.h>
> @@ -48,6 +49,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
>  }
>
>  /**
> + * acpi_platform_pre_add_cb - callback before platform device is added, to
> + * prepare firmware related information which is needed for device probe
> + */
> +static void acpi_platform_pre_add_cb(struct device *dev)
> +{
> +       acpi_configure_pmsi_domain(dev);
> +}
> +
> +/**
>   * acpi_create_platform_device - Create platform device for ACPI device node
>   * @adev: ACPI device node to create a platform device for.
>   * @properties: Optional collection of build-in properties.
> @@ -109,6 +119,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
>         pdevinfo.num_res = count;
>         pdevinfo.fwnode = acpi_fwnode_handle(adev);
>         pdevinfo.properties = properties;
> +       pdevinfo.pre_add_cb = acpi_platform_pre_add_cb;

Why don't you point that directly to acpi_configure_pmsi_domain()?  It
doesn't look like the wrapper is necessary at all.

And I'm not sure why the new callback is necessary ->

>
>         if (acpi_dma_supported(adev))
>                 pdevinfo.dma_mask = DMA_BIT_MASK(32);
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index bc68d93..6b72fcb 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -527,6 +527,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>         return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
>  }
>
> +/**
> + * iort_get_platform_device_domain() - Find MSI domain related to a
> + * platform device
> + * @dev: the dev pointer associated with the platform device
> + *
> + * Returns: the MSI domain for this device, NULL otherwise
> + */
> +static struct irq_domain *iort_get_platform_device_domain(struct device *dev)
> +{
> +       struct acpi_iort_node *node, *msi_parent;
> +       struct fwnode_handle *iort_fwnode;
> +       struct acpi_iort_its_group *its;
> +
> +       /* find its associated iort node */
> +       node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
> +                             iort_match_node_callback, dev);
> +       if (!node)
> +               return NULL;
> +
> +       /* then find its msi parent node */
> +       msi_parent = iort_node_get_id(node, NULL, IORT_MSI_TYPE, 0);
> +       if (!msi_parent)
> +               return NULL;
> +
> +       /* Move to ITS specific data */
> +       its = (struct acpi_iort_its_group *)msi_parent->node_data;
> +
> +       iort_fwnode = iort_find_domain_token(its->identifiers[0]);
> +       if (!iort_fwnode)
> +               return NULL;
> +
> +       return irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI);
> +}
> +
> +void acpi_configure_pmsi_domain(struct device *dev)
> +{
> +       struct irq_domain *msi_domain;
> +
> +       msi_domain = iort_get_platform_device_domain(dev);
> +       if (msi_domain)
> +               dev_set_msi_domain(dev, msi_domain);
> +}
> +
>  static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
>  {
>         u32 *rid = data;
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index c4af003..3e68f31 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -537,6 +537,9 @@ struct platform_device *platform_device_register_full(
>                         goto err;
>         }
>
> +       if (pdevinfo->pre_add_cb)
> +               pdevinfo->pre_add_cb(&pdev->dev);
> +

-> because it looks like this might be done in acpi_platform_notify()
for platform devices.

>         ret = platform_device_add(pdev);
>         if (ret) {

Thanks,
Rafael

^ permalink raw reply

* [PATCH 1/2] arm64: setup: introduce kaslr_offset()
From: Alexander Popov @ 2016-12-22 12:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161222061857.GA26502@yury-N73SV>

On 22.12.2016 09:18, Yury Norov wrote:
> On Sun, Dec 11, 2016 at 03:50:55AM +0300, Alexander Popov wrote:
>> Introduce kaslr_offset() similarly to x86_64 for fixing kcov.

[...]

> Hi Alexander,
> 
> I found today's linux-next master broken:

[...]

> It looks like you declare kaslr_offset() twice - in this patch, and in 7ede8665f
> (arm64: setup: introduce kaslr_offset()). 

Hello Yury,

There was a race during applying this patch. So currently linux-next has 2 versions of it.

The first one is 1a339a14b1f2c7a0dfdd6db79eee1e55d3cec357, which is original.
The second one is 7ede8665f27cde7da69e8b2fbeaa1ed0664879c5, updated by Will Deacon and
applied to the mainline.

I'm sorry for that. The first one should be definitely dropped.

Best regards,
Alexander

^ permalink raw reply

* [PATCH v4 06/12] dt: bindings: Add bindings for Marvell Xenon SD Host Controller
From: Ziji Hu @ 2016-12-22 12:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161222111802.GX14217@n2100.armlinux.org.uk>

Hi Russell,

On 2016/12/22 19:18, Russell King - ARM Linux wrote:
> On Tue, Dec 13, 2016 at 06:48:35PM +0100, Gregory CLEMENT wrote:
>> +Optional Properties:
>> +- mmc-card:
>> +  mmc-card child node must be provided when current SDHC is for eMMC.
>> +  Xenon SDHC often can support both SD and eMMC. This child node indicates that
>> +  current SDHC is for eMMC card. Thus Xenon eMMC specific configuration and
>> +  operations can be enabled prior to eMMC init sequence.
>> +  Please refer to Documentation/devicetree/bindings/mmc/mmc-card.txt.
>> +  This child node should not be set if current Xenon SDHC is for SD/SDIO.
> 
> This looks like a typo - shouldn't it be "mmccard" and not "mmc-card"?
> Your examples below use "mmccard" as does the documentation you point
> towards.
>

    Thanks a lot for the review.

    I might mix up it with compatible "mmc-card".
    I will change it to sub-node name in next version soon.

    Thank you.

Best regards,
Hu Ziji

^ permalink raw reply

* [RFC v4 15/16] vfio/type1: Check MSI remapping at irq domain level
From: Diana Madalina Craciun @ 2016-12-22 12:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481661034-3088-16-git-send-email-eric.auger@redhat.com>

Hi Eric,

On 12/13/2016 10:32 PM, Eric Auger wrote:
> In case the IOMMU does not bypass MSI transactions (typical
> case on ARM), we check all MSI controllers are IRQ remapping
> capable. If not the IRQ assignment may be unsafe.
>
> At this stage the arm-smmu-(v3) still advertise the
> IOMMU_CAP_INTR_REMAP capability at IOMMU level. This will be
> removed in subsequent patches.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>  drivers/vfio/vfio_iommu_type1.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index d07fe73..a05648b 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -37,6 +37,7 @@
>  #include <linux/vfio.h>
>  #include <linux/workqueue.h>
>  #include <linux/dma-iommu.h>
> +#include <linux/irqdomain.h>
>  
>  #define DRIVER_VERSION  "0.2"
>  #define DRIVER_AUTHOR   "Alex Williamson <alex.williamson@redhat.com>"
> @@ -765,7 +766,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>  	struct vfio_domain *domain, *d;
>  	struct bus_type *bus = NULL;
>  	int ret;
> -	bool resv_msi;
> +	bool resv_msi, msi_remap;
>  	phys_addr_t resv_msi_base;
>  
>  	mutex_lock(&iommu->lock);
> @@ -818,8 +819,10 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>  	INIT_LIST_HEAD(&domain->group_list);
>  	list_add(&group->next, &domain->group_list);
>  
> -	if (!allow_unsafe_interrupts &&
> -	    !iommu_capable(bus, IOMMU_CAP_INTR_REMAP)) {
> +	msi_remap = resv_msi ? irq_domain_check_msi_remap() :
> +			       iommu_capable(bus, IOMMU_CAP_INTR_REMAP);
> +
> +	if (!allow_unsafe_interrupts && !msi_remap) {
>  		pr_warn("%s: No interrupt remapping support.  Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",
>  		       __func__);
>  		ret = -EPERM;

I tested your v4.9-reserved-v4 branch on a ITS capable hardware (NXP
LS2080), so I did not set allow_unsafe_interrupts. It fails here
complaining that the there is no interrupt remapping support. The
irq_domain_check_msi_remap function returns false as none of the checked
domains has the IRQ_DOMAIN_FLAG_MSI_REMAP flag set. I think the reason
is that the flags are not propagated through the domain hierarchy when
the domain is created.

Thanks,

Diana

^ permalink raw reply

* [PATCH 3/3] dmaengine: pl330: Don't require irq-safe runtime PM
From: Marek Szyprowski @ 2016-12-22 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482408689-21971-1-git-send-email-m.szyprowski@samsung.com>

This patch replaces irq-safe runtime pm with non-irq-safe version.

Till now non-irq-safe runtime PM implementation was only possible by calling
pm_runtime_get/put functions from alloc/free_chan_resources. All other DMA
engine API functions cannot be called from a context, which allows sleeping.
Such implementation in practice resulted in keeping PL330 DMA controller
device active almost all the time, because most of the slave device drivers
(DMA engine clients) acquired DMA channel in their probe() function and
released it during driver removal.

This patch provides a new approach. The main assumption for it is an
observation that there can be only one slave device using each DMA channel.
Using recently introduced device dependencies (links) infrastructure one can
ensure proper runtime PM state of PL330 DMA controller. In this approach in
pl330_alloc_chan_resources() function a new dependency is being created
between PL330 DMA controller device (as supplier) and given slave device
(as consumer). This way PL330 DMA controller device runtime active counter
is increased when the slave device is resumed and decreased the same time
when given slave device is put to suspend. This way it has been ensured to
keep PL330 DMA controller runtime active if there is an active used of any
of its DMA channels. Slave device pointer is initially stored in per-channel
data in of_dma_xlate callback. This is similar to what has been already
implemented in Exynos IOMMU driver in commit 2f5f44f205cc958b
("iommu/exynos: Use device dependency links to control runtime pm").

If one requests memory-to-memory chanel, runtime active counter is
increased unconditionally. This might be a drawback of this approach, but
PL330 is not really used for memory-to-memory operations due to poor
performance in such operations compared to CPU.

Introducing non-irq-safe runtime power management finally allows to turn
audio power domain off on Exynos5 SoCs.

Removal of irq-safe runtime pm is based on the revert of the following
commits:
1. "dmaengine: pl330: fix runtime pm support" commit <no stable id yet>
2. "dmaengine: pl330: Fix hang on dmaengine_terminate_all on certain boards"
   commit 81cc6edc08705ac0146fe6ac14a0982a31ce6f3d
3. "ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12"
   commit ae43b3289186480f81c78bb63d788a85a3631f47

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/dma/pl330.c | 133 +++++++++++++++++++++++++++-------------------------
 1 file changed, 70 insertions(+), 63 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 3c80e71..2cffbb4 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -268,9 +268,6 @@ enum pl330_byteswap {
 
 #define NR_DEFAULT_DESC	16
 
-/* Delay for runtime PM autosuspend, ms */
-#define PL330_AUTOSUSPEND_DELAY 20
-
 /* Populated by the PL330 core driver for DMA API driver's info */
 struct pl330_config {
 	u32	periph_id;
@@ -449,7 +446,8 @@ struct dma_pl330_chan {
 	bool cyclic;
 
 	/* for runtime pm tracking */
-	bool active;
+	struct device *slave;
+	struct device_link *slave_link;
 };
 
 struct pl330_dmac {
@@ -2015,7 +2013,6 @@ static void pl330_tasklet(unsigned long data)
 	struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data;
 	struct dma_pl330_desc *desc, *_dt;
 	unsigned long flags;
-	bool power_down = false;
 
 	spin_lock_irqsave(&pch->lock, flags);
 
@@ -2030,18 +2027,10 @@ static void pl330_tasklet(unsigned long data)
 	/* Try to submit a req imm. next to the last completed cookie */
 	fill_queue(pch);
 
-	if (list_empty(&pch->work_list)) {
-		spin_lock(&pch->thread->dmac->lock);
-		_stop(pch->thread);
-		spin_unlock(&pch->thread->dmac->lock);
-		power_down = true;
-		pch->active = false;
-	} else {
-		/* Make sure the PL330 Channel thread is active */
-		spin_lock(&pch->thread->dmac->lock);
-		_start(pch->thread);
-		spin_unlock(&pch->thread->dmac->lock);
-	}
+	/* Make sure the PL330 Channel thread is active */
+	spin_lock(&pch->thread->dmac->lock);
+	_start(pch->thread);
+	spin_unlock(&pch->thread->dmac->lock);
 
 	while (!list_empty(&pch->completed_list)) {
 		struct dmaengine_desc_callback cb;
@@ -2054,13 +2043,6 @@ static void pl330_tasklet(unsigned long data)
 		if (pch->cyclic) {
 			desc->status = PREP;
 			list_move_tail(&desc->node, &pch->work_list);
-			if (power_down) {
-				pch->active = true;
-				spin_lock(&pch->thread->dmac->lock);
-				_start(pch->thread);
-				spin_unlock(&pch->thread->dmac->lock);
-				power_down = false;
-			}
 		} else {
 			desc->status = FREE;
 			list_move_tail(&desc->node, &pch->dmac->desc_pool);
@@ -2075,12 +2057,6 @@ static void pl330_tasklet(unsigned long data)
 		}
 	}
 	spin_unlock_irqrestore(&pch->lock, flags);
-
-	/* If work list empty, power down */
-	if (power_down) {
-		pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
-		pm_runtime_put_autosuspend(pch->dmac->ddma.dev);
-	}
 }
 
 bool pl330_filter(struct dma_chan *chan, void *param)
@@ -2113,14 +2089,63 @@ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
 	if (chan_id >= pl330->num_peripherals)
 		return NULL;
 
+	if (!pl330->peripherals[chan_id].slave)
+		pl330->peripherals[chan_id].slave = slave;
+	else if (pl330->peripherals[chan_id].slave != slave) {
+		dev_err(pl330->ddma.dev,
+			"Can't use same channel with multiple slave devices!\n");
+		return NULL;
+	}
+
 	return dma_get_slave_channel(&pl330->peripherals[chan_id].chan);
 }
 
+static int pl330_add_slave_link(struct pl330_dmac *pl330,
+				struct dma_pl330_chan *pch)
+{
+	struct device_link *link;
+	int i;
+
+	if (pch->slave_link)
+		return 0;
+
+	link = device_link_add(pch->slave, pl330->ddma.dev,
+				       DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+	if (!link)
+		return -ENODEV;
+
+	for (i = 0; i < pl330->num_peripherals; i++)
+		if (pl330->peripherals[i].slave == pch->slave)
+			pl330->peripherals[i].slave_link = link;
+	return 0;
+}
+
+static void pl330_del_slave_link(struct pl330_dmac *pl330,
+				 struct dma_pl330_chan *pch)
+{
+	struct device_link *link = pch->slave_link;
+	int i, count = 0;
+
+	for (i = 0; i < pl330->num_peripherals; i++)
+		if (pl330->peripherals[i].slave == pch->slave &&
+		    pl330->peripherals[i].thread)
+			count++;
+
+	if (count > 0)
+		return;
+
+	device_link_del(link);
+	for (i = 0; i < pl330->num_peripherals; i++)
+		if (pl330->peripherals[i].slave == pch->slave)
+			pch->slave_link = NULL;
+}
+
 static int pl330_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
 	struct pl330_dmac *pl330 = pch->dmac;
 	unsigned long flags;
+	int ret = 0;
 
 	spin_lock_irqsave(&pch->lock, flags);
 
@@ -2137,6 +2162,14 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
 
 	spin_unlock_irqrestore(&pch->lock, flags);
 
+	if (pch->slave)
+		ret = pl330_add_slave_link(pl330, pch);
+	else
+		ret = pm_runtime_get_sync(pl330->ddma.dev);
+
+	if (ret < 0)
+		return ret;
+
 	return 1;
 }
 
@@ -2171,9 +2204,7 @@ static int pl330_terminate_all(struct dma_chan *chan)
 	unsigned long flags;
 	struct pl330_dmac *pl330 = pch->dmac;
 	LIST_HEAD(list);
-	bool power_down = false;
 
-	pm_runtime_get_sync(pl330->ddma.dev);
 	spin_lock_irqsave(&pch->lock, flags);
 	spin_lock(&pl330->lock);
 	_stop(pch->thread);
@@ -2182,8 +2213,6 @@ static int pl330_terminate_all(struct dma_chan *chan)
 	pch->thread->req[0].desc = NULL;
 	pch->thread->req[1].desc = NULL;
 	pch->thread->req_running = -1;
-	power_down = pch->active;
-	pch->active = false;
 
 	/* Mark all desc done */
 	list_for_each_entry(desc, &pch->submitted_list, node) {
@@ -2200,10 +2229,6 @@ static int pl330_terminate_all(struct dma_chan *chan)
 	list_splice_tail_init(&pch->work_list, &pl330->desc_pool);
 	list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
 	spin_unlock_irqrestore(&pch->lock, flags);
-	pm_runtime_mark_last_busy(pl330->ddma.dev);
-	if (power_down)
-		pm_runtime_put_autosuspend(pl330->ddma.dev);
-	pm_runtime_put_autosuspend(pl330->ddma.dev);
 
 	return 0;
 }
@@ -2221,7 +2246,6 @@ static int pl330_pause(struct dma_chan *chan)
 	struct pl330_dmac *pl330 = pch->dmac;
 	unsigned long flags;
 
-	pm_runtime_get_sync(pl330->ddma.dev);
 	spin_lock_irqsave(&pch->lock, flags);
 
 	spin_lock(&pl330->lock);
@@ -2229,8 +2253,6 @@ static int pl330_pause(struct dma_chan *chan)
 	spin_unlock(&pl330->lock);
 
 	spin_unlock_irqrestore(&pch->lock, flags);
-	pm_runtime_mark_last_busy(pl330->ddma.dev);
-	pm_runtime_put_autosuspend(pl330->ddma.dev);
 
 	return 0;
 }
@@ -2238,11 +2260,11 @@ static int pl330_pause(struct dma_chan *chan)
 static void pl330_free_chan_resources(struct dma_chan *chan)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
+	struct pl330_dmac *pl330 = pch->dmac;
 	unsigned long flags;
 
 	tasklet_kill(&pch->task);
 
-	pm_runtime_get_sync(pch->dmac->ddma.dev);
 	spin_lock_irqsave(&pch->lock, flags);
 
 	pl330_release_channel(pch->thread);
@@ -2252,19 +2274,20 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
 		list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool);
 
 	spin_unlock_irqrestore(&pch->lock, flags);
-	pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
-	pm_runtime_put_autosuspend(pch->dmac->ddma.dev);
+
+	if (pch->slave)
+		pl330_del_slave_link(pl330, pch);
+	else
+		pm_runtime_put(pl330->ddma.dev);
 }
 
 static int pl330_get_current_xferred_count(struct dma_pl330_chan *pch,
 					   struct dma_pl330_desc *desc)
 {
 	struct pl330_thread *thrd = pch->thread;
-	struct pl330_dmac *pl330 = pch->dmac;
 	void __iomem *regs = thrd->dmac->base;
 	u32 val, addr;
 
-	pm_runtime_get_sync(pl330->ddma.dev);
 	val = addr = 0;
 	if (desc->rqcfg.src_inc) {
 		val = readl(regs + SA(thrd->id));
@@ -2273,8 +2296,6 @@ static int pl330_get_current_xferred_count(struct dma_pl330_chan *pch,
 		val = readl(regs + DA(thrd->id));
 		addr = desc->px.dst_addr;
 	}
-	pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
-	pm_runtime_put_autosuspend(pl330->ddma.dev);
 
 	/* If DMAMOV hasn't finished yet, SAR/DAR can be zero */
 	if (!val)
@@ -2360,16 +2381,6 @@ static void pl330_issue_pending(struct dma_chan *chan)
 	unsigned long flags;
 
 	spin_lock_irqsave(&pch->lock, flags);
-	if (list_empty(&pch->work_list)) {
-		/*
-		 * Warn on nothing pending. Empty submitted_list may
-		 * break our pm_runtime usage counter as it is
-		 * updated on work_list emptiness status.
-		 */
-		WARN_ON(list_empty(&pch->submitted_list));
-		pch->active = true;
-		pm_runtime_get_sync(pch->dmac->ddma.dev);
-	}
 	list_splice_tail_init(&pch->submitted_list, &pch->work_list);
 	spin_unlock_irqrestore(&pch->lock, flags);
 
@@ -2987,11 +2998,7 @@ static int __maybe_unused pl330_resume(struct device *dev)
 		pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan,
 		pcfg->num_peri, pcfg->num_events);
 
-	pm_runtime_irq_safe(&adev->dev);
-	pm_runtime_use_autosuspend(&adev->dev);
-	pm_runtime_set_autosuspend_delay(&adev->dev, PL330_AUTOSUSPEND_DELAY);
-	pm_runtime_mark_last_busy(&adev->dev);
-	pm_runtime_put_autosuspend(&adev->dev);
+	pm_runtime_put(&adev->dev);
 
 	return 0;
 probe_err3:
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/3] dmaengine: Forward slave device pointer to of_xlate callback
From: Marek Szyprowski @ 2016-12-22 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482408689-21971-1-git-send-email-m.szyprowski@samsung.com>

Add pointer to slave struct device to of_dma_xlate to let DMA engine
driver to know which slave device is using given DMA channel. This
will be later used to implement non-irqsafe runtime PM for DMA engine
driver.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/dma/amba-pl08x.c        |  2 +-
 drivers/dma/at_hdmac.c          |  4 ++--
 drivers/dma/at_xdmac.c          |  2 +-
 drivers/dma/bcm2835-dma.c       |  2 +-
 drivers/dma/coh901318.c         |  2 +-
 drivers/dma/cppi41.c            |  2 +-
 drivers/dma/dma-jz4780.c        |  2 +-
 drivers/dma/dmaengine.c         |  2 +-
 drivers/dma/dw/platform.c       |  2 +-
 drivers/dma/edma.c              |  4 ++--
 drivers/dma/fsl-edma.c          |  2 +-
 drivers/dma/img-mdc-dma.c       |  2 +-
 drivers/dma/imx-dma.c           |  2 +-
 drivers/dma/imx-sdma.c          |  2 +-
 drivers/dma/k3dma.c             |  2 +-
 drivers/dma/mmp_pdma.c          |  2 +-
 drivers/dma/mmp_tdma.c          |  2 +-
 drivers/dma/moxart-dma.c        |  2 +-
 drivers/dma/mxs-dma.c           |  2 +-
 drivers/dma/nbpfaxi.c           |  2 +-
 drivers/dma/of-dma.c            | 20 ++++++++++++--------
 drivers/dma/pl330.c             |  3 ++-
 drivers/dma/pxa_dma.c           |  2 +-
 drivers/dma/qcom/bam_dma.c      |  2 +-
 drivers/dma/sh/rcar-dmac.c      |  2 +-
 drivers/dma/sh/shdma-of.c       |  2 +-
 drivers/dma/sh/usb-dmac.c       |  2 +-
 drivers/dma/sirf-dma.c          |  2 +-
 drivers/dma/st_fdma.c           |  2 +-
 drivers/dma/ste_dma40.c         |  2 +-
 drivers/dma/stm32-dma.c         |  2 +-
 drivers/dma/sun4i-dma.c         |  2 +-
 drivers/dma/sun6i-dma.c         |  2 +-
 drivers/dma/tegra20-apb-dma.c   |  2 +-
 drivers/dma/tegra210-adma.c     |  2 +-
 drivers/dma/xilinx/xilinx_dma.c |  2 +-
 drivers/dma/xilinx/zynqmp_dma.c |  2 +-
 drivers/dma/zx296702_dma.c      |  2 +-
 include/linux/of_dma.h          | 17 +++++++++--------
 39 files changed, 61 insertions(+), 55 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 0b7c6ce..194089c 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -2059,7 +2059,7 @@ static struct dma_chan *pl08x_find_chan_id(struct pl08x_driver_data *pl08x,
 }
 
 static struct dma_chan *pl08x_of_xlate(struct of_phandle_args *dma_spec,
-				       struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct pl08x_driver_data *pl08x = ofdma->of_dma_data;
 	struct dma_chan *dma_chan;
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 1baf340..b228b26 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1788,7 +1788,7 @@ static bool at_dma_filter(struct dma_chan *chan, void *slave)
 }
 
 static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
-				     struct of_dma *of_dma)
+				    struct of_dma *of_dma, struct device *slave)
 {
 	struct dma_chan *chan;
 	struct at_dma_chan *atchan;
@@ -1847,7 +1847,7 @@ static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
 }
 #else
 static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
-				     struct of_dma *of_dma)
+				    struct of_dma *of_dma, struct device *slave)
 {
 	return NULL;
 }
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 7d4e0bc..9ddd868 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -508,7 +508,7 @@ static inline void at_xdmac_increment_block_count(struct dma_chan *chan,
 }
 
 static struct dma_chan *at_xdmac_xlate(struct of_phandle_args *dma_spec,
-				       struct of_dma *of_dma)
+				    struct of_dma *of_dma, struct device *slave)
 {
 	struct at_xdmac		*atxdmac = of_dma->of_dma_data;
 	struct at_xdmac_chan	*atchan;
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index e18dc596c..e9c417a 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -877,7 +877,7 @@ static void bcm2835_dma_free(struct bcm2835_dmadev *od)
 MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
 
 static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct bcm2835_dmadev *d = ofdma->of_dma_data;
 	struct dma_chan *chan;
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 74794c9..dbc4fb4 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -1779,7 +1779,7 @@ static bool coh901318_filter_base_and_id(struct dma_chan *chan, void *data)
 }
 
 static struct dma_chan *coh901318_xlate(struct of_phandle_args *dma_spec,
-					struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct coh901318_filter_args args = {
 		.base = ofdma->of_dma_data,
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
index d5ba43a..389a227 100644
--- a/drivers/dma/cppi41.c
+++ b/drivers/dma/cppi41.c
@@ -932,7 +932,7 @@ static bool cpp41_dma_filter_fn(struct dma_chan *chan, void *param)
 };
 
 static struct dma_chan *cppi41_dma_xlate(struct of_phandle_args *dma_spec,
-		struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	int count = dma_spec->args_count;
 	struct of_dma_filter_info *info = ofdma->of_dma_data;
diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c
index 7373b7a..f65f716 100644
--- a/drivers/dma/dma-jz4780.c
+++ b/drivers/dma/dma-jz4780.c
@@ -707,7 +707,7 @@ static bool jz4780_dma_filter_fn(struct dma_chan *chan, void *param)
 }
 
 static struct dma_chan *jz4780_of_dma_xlate(struct of_phandle_args *dma_spec,
-	struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct jz4780_dma_dev *jzdma = ofdma->of_dma_data;
 	dma_cap_mask_t mask = jzdma->dma_device.cap_mask;
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 6b53526..9204ae8 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -708,7 +708,7 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name)
 
 	/* If device-tree is present get slave info from here */
 	if (dev->of_node)
-		chan = of_dma_request_slave_channel(dev->of_node, name);
+		chan = of_dma_request_slave_channel(dev, name);
 
 	/* If device was enumerated by ACPI get slave info from here */
 	if (has_acpi_companion(dev) && !chan)
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index b1655e4..7567b19 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -29,7 +29,7 @@
 #define DRV_NAME	"dw_dmac"
 
 static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
-					struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct dw_dma *dw = ofdma->of_dma_data;
 	struct dw_dma_slave slave = {
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 3879f80..d2e7d89 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -2117,7 +2117,7 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
 }
 
 static struct dma_chan *of_edma_xlate(struct of_phandle_args *dma_spec,
-				      struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct edma_cc *ecc = ofdma->of_dma_data;
 	struct dma_chan *chan = NULL;
@@ -2161,7 +2161,7 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
 }
 
 static struct dma_chan *of_edma_xlate(struct of_phandle_args *dma_spec,
-				      struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	return NULL;
 }
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index 6775f2c..915aa81 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -750,7 +750,7 @@ static void fsl_edma_issue_pending(struct dma_chan *chan)
 }
 
 static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
-		struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
 	struct dma_chan *chan, *_chan;
diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
index 54db141..9a969cb 100644
--- a/drivers/dma/img-mdc-dma.c
+++ b/drivers/dma/img-mdc-dma.c
@@ -793,7 +793,7 @@ static irqreturn_t mdc_chan_irq(int irq, void *dev_id)
 }
 
 static struct dma_chan *mdc_of_xlate(struct of_phandle_args *dma_spec,
-				     struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct mdc_dma *mdma = ofdma->of_dma_data;
 	struct dma_chan *chan;
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index ab0fb80..b145bab 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -1032,7 +1032,7 @@ static bool imxdma_filter_fn(struct dma_chan *chan, void *param)
 }
 
 static struct dma_chan *imxdma_xlate(struct of_phandle_args *dma_spec,
-						struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	int count = dma_spec->args_count;
 	struct imxdma_engine *imxdma = ofdma->of_dma_data;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index d1651a5..7c3cdb3 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1659,7 +1659,7 @@ static bool sdma_filter_fn(struct dma_chan *chan, void *fn_param)
 }
 
 static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
-				   struct of_dma *ofdma)
+				   struct of_dma *ofdma, struct device *slave)
 {
 	struct sdma_engine *sdma = ofdma->of_dma_data;
 	dma_cap_mask_t mask = sdma->dma_device.cap_mask;
diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
index 01e25c6..dd0e7fe 100644
--- a/drivers/dma/k3dma.c
+++ b/drivers/dma/k3dma.c
@@ -786,7 +786,7 @@ static int k3_dma_transfer_resume(struct dma_chan *chan)
 MODULE_DEVICE_TABLE(of, k3_pdma_dt_ids);
 
 static struct dma_chan *k3_of_dma_simple_xlate(struct of_phandle_args *dma_spec,
-						struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct k3_dma_dev *d = ofdma->of_dma_data;
 	unsigned int request = dma_spec->args[0];
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index eb3a1f4..569ec8f 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -993,7 +993,7 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
 MODULE_DEVICE_TABLE(of, mmp_pdma_dt_ids);
 
 static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct mmp_pdma_device *d = ofdma->of_dma_data;
 	struct dma_chan *chan;
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index 13c68b6..ca56e73 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -591,7 +591,7 @@ static bool mmp_tdma_filter_fn(struct dma_chan *chan, void *fn_param)
 }
 
 static struct dma_chan *mmp_tdma_xlate(struct of_phandle_args *dma_spec,
-			       struct of_dma *ofdma)
+			       struct of_dma *ofdma, struct device *slave)
 {
 	struct mmp_tdma_device *tdev = ofdma->of_dma_data;
 	dma_cap_mask_t mask = tdev->device.cap_mask;
diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c
index e1a5c22..d7c32a3 100644
--- a/drivers/dma/moxart-dma.c
+++ b/drivers/dma/moxart-dma.c
@@ -330,7 +330,7 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg(
 }
 
 static struct dma_chan *moxart_of_xlate(struct of_phandle_args *dma_spec,
-					struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct moxart_dmadev *mdc = ofdma->of_dma_data;
 	struct dma_chan *chan;
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index e217268..3cc0e6b 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -747,7 +747,7 @@ static bool mxs_dma_filter_fn(struct dma_chan *chan, void *fn_param)
 }
 
 static struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
-			       struct of_dma *ofdma)
+			       struct of_dma *ofdma, struct device *slave)
 {
 	struct mxs_dma_engine *mxs_dma = ofdma->of_dma_data;
 	dma_cap_mask_t mask = mxs_dma->dma_device.cap_mask;
diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c
index 3f45b9b..cb6a981 100644
--- a/drivers/dma/nbpfaxi.c
+++ b/drivers/dma/nbpfaxi.c
@@ -1096,7 +1096,7 @@ static void nbpf_free_chan_resources(struct dma_chan *dchan)
 }
 
 static struct dma_chan *nbpf_of_xlate(struct of_phandle_args *dma_spec,
-				      struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct nbpf_device *nbpf = ofdma->of_dma_data;
 	struct dma_chan *dchan;
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index faae0bf..b6fd9e1 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -54,7 +54,8 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
  * to request channel from the real DMA controller.
  */
 static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
-					    struct of_dma *ofdma)
+					    struct of_dma *ofdma,
+					    struct device *slave)
 {
 	struct dma_chan		*chan;
 	struct of_dma		*ofdma_target;
@@ -71,7 +72,8 @@ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
 	if (!ofdma_target)
 		return NULL;
 
-	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
+	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target,
+					  slave);
 	if (chan) {
 		chan->router = ofdma->dma_router;
 		chan->route_data = route_data;
@@ -103,7 +105,8 @@ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
  */
 int of_dma_controller_register(struct device_node *np,
 				struct dma_chan *(*of_dma_xlate)
-				(struct of_phandle_args *, struct of_dma *),
+				(struct of_phandle_args *, struct of_dma *,
+				 struct device *),
 				void *data)
 {
 	struct of_dma	*ofdma;
@@ -229,14 +232,15 @@ static int of_dma_match_channel(struct device_node *np, const char *name,
 
 /**
  * of_dma_request_slave_channel - Get the DMA slave channel
- * @np:		device node to get DMA request from
+ * @slave:		device to get DMA request from
  * @name:	name of desired channel
  *
  * Returns pointer to appropriate DMA channel on success or an error pointer.
  */
-struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
+struct dma_chan *of_dma_request_slave_channel(struct device *slave,
 					      const char *name)
 {
+	struct device_node	*np = slave->of_node;
 	struct of_phandle_args	dma_spec;
 	struct of_dma		*ofdma;
 	struct dma_chan		*chan;
@@ -275,7 +279,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 		ofdma = of_dma_find_controller(&dma_spec);
 
 		if (ofdma) {
-			chan = ofdma->of_dma_xlate(&dma_spec, ofdma);
+			chan = ofdma->of_dma_xlate(&dma_spec, ofdma, slave);
 		} else {
 			ret_no_channel = -EPROBE_DEFER;
 			chan = NULL;
@@ -305,7 +309,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
  * pointer to appropriate dma channel on success or NULL on error.
  */
 struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
-						struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	int count = dma_spec->args_count;
 	struct of_dma_filter_info *info = ofdma->of_dma_data;
@@ -335,7 +339,7 @@ struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
  * Returns pointer to appropriate dma channel on success or NULL on error.
  */
 struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
-					 struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct dma_device *dev = ofdma->of_dma_data;
 	struct dma_chan *chan, *candidate = NULL;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 27cc5d2..3c80e71 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2096,7 +2096,8 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 EXPORT_SYMBOL(pl330_filter);
 
 static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
-						struct of_dma *ofdma)
+					   struct of_dma *ofdma,
+					   struct device *slave)
 {
 	int count = dma_spec->args_count;
 	struct pl330_dmac *pl330 = ofdma->of_dma_data;
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index b53fb61..434764b 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -1336,7 +1336,7 @@ static int pxad_init_phys(struct platform_device *op,
 MODULE_DEVICE_TABLE(of, pxad_dt_ids);
 
 static struct dma_chan *pxad_dma_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct pxad_device *d = ofdma->of_dma_data;
 	struct dma_chan *chan;
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 03c4eb3..7ff3075 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -1049,7 +1049,7 @@ static void bam_dma_free_desc(struct virt_dma_desc *vd)
 }
 
 static struct dma_chan *bam_dma_xlate(struct of_phandle_args *dma_spec,
-		struct of_dma *of)
+				      struct of_dma *of, struct device *slave)
 {
 	struct bam_device *bdev = container_of(of->of_dma_data,
 					struct bam_device, common);
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index 2e441d0..7cecf03 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -1552,7 +1552,7 @@ static bool rcar_dmac_chan_filter(struct dma_chan *chan, void *arg)
 }
 
 static struct dma_chan *rcar_dmac_of_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct rcar_dmac_chan *rchan;
 	struct dma_chan *chan;
diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c
index f999f9b..9953be9 100644
--- a/drivers/dma/sh/shdma-of.c
+++ b/drivers/dma/sh/shdma-of.c
@@ -20,7 +20,7 @@
 #define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
 
 static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec,
-				       struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	u32 id = dma_spec->args[0];
 	dma_cap_mask_t mask;
diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c
index 72c6497..0f06a94 100644
--- a/drivers/dma/sh/usb-dmac.c
+++ b/drivers/dma/sh/usb-dmac.c
@@ -650,7 +650,7 @@ static bool usb_dmac_chan_filter(struct dma_chan *chan, void *arg)
 }
 
 static struct dma_chan *usb_dmac_of_xlate(struct of_phandle_args *dma_spec,
-					  struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct dma_chan *chan;
 	dma_cap_mask_t mask;
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index a0733ac3e..ed6f07b 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -826,7 +826,7 @@ bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id)
 	BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
 
 static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec,
-	struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct sirfsoc_dma *sdma = ofdma->of_dma_data;
 	unsigned int request = dma_spec->args[0];
diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
index bfb79bd..6a92a65 100644
--- a/drivers/dma/st_fdma.c
+++ b/drivers/dma/st_fdma.c
@@ -167,7 +167,7 @@ static irqreturn_t st_fdma_irq_handler(int irq, void *dev_id)
 }
 
 static struct dma_chan *st_fdma_of_xlate(struct of_phandle_args *dma_spec,
-					 struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct st_fdma_dev *fdev = ofdma->of_dma_data;
 	struct dma_chan *chan;
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 8684d11..d7b0662 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2334,7 +2334,7 @@ static void d40_set_prio_realtime(struct d40_chan *d40c)
 #define D40_DT_FLAGS_HIGH_PRIO(flags)  ((flags >> 4) & 0x1)
 
 static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec,
-				  struct of_dma *ofdma)
+				  struct of_dma *ofdma, struct device *slave)
 {
 	struct stedma40_chan_cfg cfg;
 	dma_cap_mask_t cap;
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 3688d08..8e8e592 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -965,7 +965,7 @@ static void stm32_dma_set_config(struct stm32_dma_chan *chan,
 }
 
 static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct stm32_dma_device *dmadev = ofdma->of_dma_data;
 	struct stm32_dma_cfg cfg;
diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c
index 57aa227..c1a0763 100644
--- a/drivers/dma/sun4i-dma.c
+++ b/drivers/dma/sun4i-dma.c
@@ -909,7 +909,7 @@ static int sun4i_dma_config(struct dma_chan *chan,
 }
 
 static struct dma_chan *sun4i_dma_of_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct sun4i_dma_dev *priv = ofdma->of_dma_data;
 	struct sun4i_dma_vchan *vchan;
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index a235878..240e4a9 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -930,7 +930,7 @@ static void sun6i_dma_free_chan_resources(struct dma_chan *chan)
 }
 
 static struct dma_chan *sun6i_dma_of_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct sun6i_dma_dev *sdev = ofdma->of_dma_data;
 	struct sun6i_vchan *vchan;
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 3722b9d..e0eb581 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -1239,7 +1239,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
 }
 
 static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct tegra_dma *tdma = ofdma->of_dma_data;
 	struct dma_chan *chan;
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
index b10cbaa..525af32 100644
--- a/drivers/dma/tegra210-adma.c
+++ b/drivers/dma/tegra210-adma.c
@@ -605,7 +605,7 @@ static void tegra_adma_free_chan_resources(struct dma_chan *dc)
 }
 
 static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
-					   struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct tegra_adma *tdma = ofdma->of_dma_data;
 	struct tegra_adma_chan *tdc;
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 8288fe4..69cdfc3 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -2461,7 +2461,7 @@ static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev,
  * Return: DMA channel pointer on success and NULL on error
  */
 static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
-						struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct xilinx_dma_device *xdev = ofdma->of_dma_data;
 	int chan_id = dma_spec->args[0];
diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index 6d221e5..6aa133c 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -1040,7 +1040,7 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev,
  * Return: DMA channel pointer on success and NULL on error
  */
 static struct dma_chan *of_zynqmp_dma_xlate(struct of_phandle_args *dma_spec,
-					    struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct zynqmp_dma_device *zdev = ofdma->of_dma_data;
 
diff --git a/drivers/dma/zx296702_dma.c b/drivers/dma/zx296702_dma.c
index 380276d..a07f1c1 100644
--- a/drivers/dma/zx296702_dma.c
+++ b/drivers/dma/zx296702_dma.c
@@ -731,7 +731,7 @@ static void zx_dma_free_desc(struct virt_dma_desc *vd)
 MODULE_DEVICE_TABLE(of, zx6702_dma_dt_ids);
 
 static struct dma_chan *zx_of_dma_simple_xlate(struct of_phandle_args *dma_spec,
-					       struct of_dma *ofdma)
+				     struct of_dma *ofdma, struct device *slave)
 {
 	struct zx_dma_dev *d = ofdma->of_dma_data;
 	unsigned int request = dma_spec->args[0];
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index b90d8ec..a0a6c8c 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -22,7 +22,8 @@ struct of_dma {
 	struct list_head	of_dma_controllers;
 	struct device_node	*of_node;
 	struct dma_chan		*(*of_dma_xlate)
-				(struct of_phandle_args *, struct of_dma *);
+				(struct of_phandle_args *, struct of_dma *,
+				 struct device *);
 	void			*(*of_dma_route_allocate)
 				(struct of_phandle_args *, struct of_dma *);
 	struct dma_router	*dma_router;
@@ -37,7 +38,7 @@ struct of_dma_filter_info {
 #ifdef CONFIG_DMA_OF
 extern int of_dma_controller_register(struct device_node *np,
 		struct dma_chan *(*of_dma_xlate)
-		(struct of_phandle_args *, struct of_dma *),
+		(struct of_phandle_args *, struct of_dma *, struct device *),
 		void *data);
 extern void of_dma_controller_free(struct device_node *np);
 
@@ -47,17 +48,17 @@ extern int of_dma_router_register(struct device_node *np,
 		struct dma_router *dma_router);
 #define of_dma_router_free of_dma_controller_free
 
-extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
+extern struct dma_chan *of_dma_request_slave_channel(struct device *slave,
 						     const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
-		struct of_dma *ofdma);
+		struct of_dma *ofdma, struct device *slave);
 extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
-		struct of_dma *ofdma);
+		struct of_dma *ofdma, struct device *slave);
 
 #else
 static inline int of_dma_controller_register(struct device_node *np,
 		struct dma_chan *(*of_dma_xlate)
-		(struct of_phandle_args *, struct of_dma *),
+		(struct of_phandle_args *, struct of_dma *, struct device *),
 		void *data)
 {
 	return -ENODEV;
@@ -77,14 +78,14 @@ static inline int of_dma_router_register(struct device_node *np,
 
 #define of_dma_router_free of_dma_controller_free
 
-static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
+static inline struct dma_chan *of_dma_request_slave_channel(struct device *slave,
 						     const char *name)
 {
 	return ERR_PTR(-ENODEV);
 }
 
 static inline struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
-		struct of_dma *ofdma)
+		struct of_dma *ofdma, struct device *slave)
 {
 	return NULL;
 }
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/3] dmaengine: pl330: remove pdata based initialization
From: Marek Szyprowski @ 2016-12-22 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482408689-21971-1-git-send-email-m.szyprowski@samsung.com>

This driver is now used only on platforms which supports device tree, so
it is safe to remove legacy platform data based initialization code.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/dma/pl330.c        | 30 ++++++++----------------------
 include/linux/amba/pl330.h | 35 -----------------------------------
 2 files changed, 8 insertions(+), 57 deletions(-)
 delete mode 100644 include/linux/amba/pl330.h

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 740bbb9..27cc5d2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -22,7 +22,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/amba/bus.h>
-#include <linux/amba/pl330.h>
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 #include <linux/of_dma.h>
@@ -2839,7 +2838,6 @@ static int __maybe_unused pl330_resume(struct device *dev)
 static int
 pl330_probe(struct amba_device *adev, const struct amba_id *id)
 {
-	struct dma_pl330_platdata *pdat;
 	struct pl330_config *pcfg;
 	struct pl330_dmac *pl330;
 	struct dma_pl330_chan *pch, *_p;
@@ -2849,8 +2847,6 @@ static int __maybe_unused pl330_resume(struct device *dev)
 	int num_chan;
 	struct device_node *np = adev->dev.of_node;
 
-	pdat = dev_get_platdata(&adev->dev);
-
 	ret = dma_set_mask_and_coherent(&adev->dev, DMA_BIT_MASK(32));
 	if (ret)
 		return ret;
@@ -2863,7 +2859,7 @@ static int __maybe_unused pl330_resume(struct device *dev)
 	pd = &pl330->ddma;
 	pd->dev = &adev->dev;
 
-	pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
+	pl330->mcbufsz = 0;
 
 	/* get quirk */
 	for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
@@ -2907,10 +2903,7 @@ static int __maybe_unused pl330_resume(struct device *dev)
 	INIT_LIST_HEAD(&pd->channels);
 
 	/* Initialize channel parameters */
-	if (pdat)
-		num_chan = max_t(int, pdat->nr_valid_peri, pcfg->num_chan);
-	else
-		num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan);
+	num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan);
 
 	pl330->num_peripherals = num_chan;
 
@@ -2922,11 +2915,8 @@ static int __maybe_unused pl330_resume(struct device *dev)
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pl330->peripherals[i];
-		if (!adev->dev.of_node)
-			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
-		else
-			pch->chan.private = adev->dev.of_node;
 
+		pch->chan.private = adev->dev.of_node;
 		INIT_LIST_HEAD(&pch->submitted_list);
 		INIT_LIST_HEAD(&pch->work_list);
 		INIT_LIST_HEAD(&pch->completed_list);
@@ -2939,15 +2929,11 @@ static int __maybe_unused pl330_resume(struct device *dev)
 		list_add_tail(&pch->chan.device_node, &pd->channels);
 	}
 
-	if (pdat) {
-		pd->cap_mask = pdat->cap_mask;
-	} else {
-		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-		if (pcfg->num_peri) {
-			dma_cap_set(DMA_SLAVE, pd->cap_mask);
-			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
-			dma_cap_set(DMA_PRIVATE, pd->cap_mask);
-		}
+	dma_cap_set(DMA_MEMCPY, pd->cap_mask);
+	if (pcfg->num_peri) {
+		dma_cap_set(DMA_SLAVE, pd->cap_mask);
+		dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+		dma_cap_set(DMA_PRIVATE, pd->cap_mask);
 	}
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
deleted file mode 100644
index fe93758..0000000
--- a/include/linux/amba/pl330.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* linux/include/linux/amba/pl330.h
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef	__AMBA_PL330_H_
-#define	__AMBA_PL330_H_
-
-#include <linux/dmaengine.h>
-
-struct dma_pl330_platdata {
-	/*
-	 * Number of valid peripherals connected to DMAC.
-	 * This may be different from the value read from
-	 * CR0, as the PL330 implementation might have 'holes'
-	 * in the peri list or the peri could also be reached
-	 * from another DMAC which the platform prefers.
-	 */
-	u8 nr_valid_peri;
-	/* Array of valid peripherals */
-	u8 *peri_id;
-	/* Operational capabilities */
-	dma_cap_mask_t cap_mask;
-	/* Bytes to allocate for MC buffer */
-	unsigned mcbuf_sz;
-};
-
-extern bool pl330_filter(struct dma_chan *chan, void *param);
-#endif	/* __AMBA_PL330_H_ */
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/3] DMA Engine: switch PL330 driver to non-irq-safe runtime PM
From: Marek Szyprowski @ 2016-12-22 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CGME20161222121148epcas5p11d4e49a3724e375a989aa173f731346f@epcas5p1.samsung.com>

Hello,

This patchset changes the way the runtime PM is implemented in PL330 DMA
engine driver. The main goal of such change is to add support for audio
power domain to Exynos5 SoCs (5250, 542x, 5433, probably others) and let
it to be properly turned off, when no audio is being used. Switching to
non-irq-safe runtime PM is needed to properly let power domain to be
turned off (irqsafe runtime PM keeps power domain turned on all the time)
and to integrate with clock controller's runtime PM (this cannot be
workarounded any other way, PL330 uses clocks from the controller, which
belongs to the same power domain).

For more details of the proposed change to PL330 driver see patch #3.

Audio power domain on Exynos5 SoCs contains following hardware modules:
1. clock controller
2. pin controller
3. PL330 DMA controller
4. I2S audio controller

Patches for adding/fixing runtime PM for each of the above device will be
handled separately.

Runtime PM patches for clock controllers is possible and has been proposed
in the following thread (pending review, patch for runtime PM for Exynos
Audio subsystem will be added in v4 soon):
https://www.spinics.net/lists/arm-kernel/msg538122.html

Runtime PM support for Exynos pin controller will be posted soon in
a separate thread.

Exynos I2S driver already supports runtime PM, but some fixes are needed
for it and they will be also posted soon.

Patches are based on linux-next with my PL330 runtime PM fix patch
applied (which I assume will be merged as a fix to v4.10):
https://patchwork.kernel.org/patch/9477695/

Best regards
Marek Szyprowski
Samsung R&D Institute Poland


Patch summary:

Marek Szyprowski (3):
  dmaengine: pl330: remove pdata based initialization
  dmaengine: Forward slave device pointer to of_xlate callback
  dmaengine: pl330: Don't require irq-safe runtime PM

 drivers/dma/amba-pl08x.c        |   2 +-
 drivers/dma/at_hdmac.c          |   4 +-
 drivers/dma/at_xdmac.c          |   2 +-
 drivers/dma/bcm2835-dma.c       |   2 +-
 drivers/dma/coh901318.c         |   2 +-
 drivers/dma/cppi41.c            |   2 +-
 drivers/dma/dma-jz4780.c        |   2 +-
 drivers/dma/dmaengine.c         |   2 +-
 drivers/dma/dw/platform.c       |   2 +-
 drivers/dma/edma.c              |   4 +-
 drivers/dma/fsl-edma.c          |   2 +-
 drivers/dma/img-mdc-dma.c       |   2 +-
 drivers/dma/imx-dma.c           |   2 +-
 drivers/dma/imx-sdma.c          |   2 +-
 drivers/dma/k3dma.c             |   2 +-
 drivers/dma/mmp_pdma.c          |   2 +-
 drivers/dma/mmp_tdma.c          |   2 +-
 drivers/dma/moxart-dma.c        |   2 +-
 drivers/dma/mxs-dma.c           |   2 +-
 drivers/dma/nbpfaxi.c           |   2 +-
 drivers/dma/of-dma.c            |  20 +++--
 drivers/dma/pl330.c             | 166 +++++++++++++++++++---------------------
 drivers/dma/pxa_dma.c           |   2 +-
 drivers/dma/qcom/bam_dma.c      |   2 +-
 drivers/dma/sh/rcar-dmac.c      |   2 +-
 drivers/dma/sh/shdma-of.c       |   2 +-
 drivers/dma/sh/usb-dmac.c       |   2 +-
 drivers/dma/sirf-dma.c          |   2 +-
 drivers/dma/st_fdma.c           |   2 +-
 drivers/dma/ste_dma40.c         |   2 +-
 drivers/dma/stm32-dma.c         |   2 +-
 drivers/dma/sun4i-dma.c         |   2 +-
 drivers/dma/sun6i-dma.c         |   2 +-
 drivers/dma/tegra20-apb-dma.c   |   2 +-
 drivers/dma/tegra210-adma.c     |   2 +-
 drivers/dma/xilinx/xilinx_dma.c |   2 +-
 drivers/dma/xilinx/zynqmp_dma.c |   2 +-
 drivers/dma/zx296702_dma.c      |   2 +-
 include/linux/amba/pl330.h      |  35 ---------
 include/linux/of_dma.h          |  17 ++--
 40 files changed, 139 insertions(+), 175 deletions(-)
 delete mode 100644 include/linux/amba/pl330.h

-- 
1.9.1

^ permalink raw reply

* [PATCH] clk: mvebu: adjust AP806 CPU clock frequencies to production chip
From: Thomas Petazzoni @ 2016-12-22 12:08 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adjusts the list of possible "Sample At Reset" values that
define the CPU clock frequency of the AP806 (part of Marvell Armada
7K/8K) to the values that have been validated with the production
chip. Earlier values were preliminary.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 drivers/clk/mvebu/ap806-system-controller.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c
index 02023ba..962e0c5 100644
--- a/drivers/clk/mvebu/ap806-system-controller.c
+++ b/drivers/clk/mvebu/ap806-system-controller.c
@@ -55,21 +55,39 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
 
 	freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;
 	switch (freq_mode) {
-	case 0x0 ... 0x5:
+	case 0x0:
+	case 0x1:
 		cpuclk_freq = 2000;
 		break;
-	case 0x6 ... 0xB:
+	case 0x6:
+	case 0x7:
 		cpuclk_freq = 1800;
 		break;
-	case 0xC ... 0x11:
+	case 0x4:
+	case 0xB:
+	case 0xD:
 		cpuclk_freq = 1600;
 		break;
-	case 0x12 ... 0x16:
+	case 0x1a:
 		cpuclk_freq = 1400;
 		break;
-	case 0x17 ... 0x19:
+	case 0x14:
+	case 0x17:
 		cpuclk_freq = 1300;
 		break;
+	case 0x19:
+		cpuclk_freq = 1200;
+		break;
+	case 0x13:
+	case 0x1d:
+		cpuclk_freq = 1000;
+		break;
+	case 0x1c:
+		cpuclk_freq = 800;
+		break;
+	case 0x1b:
+		cpuclk_freq = 600;
+		break;
 	default:
 		dev_err(&pdev->dev, "invalid SAR value\n");
 		return -EINVAL;
-- 
2.7.4

^ permalink raw reply related

* [PATCH] arm64: print bad_frame in handle_signal
From: bamvor.zhangjian at huawei.com @ 2016-12-22 11:35 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>

Sometims handle_signal will fail due to the bad frame and send to
segfault to process consequently. But there is no information in system
log which lead to hard to debug the root issue.

This patch add as same bad frame print as sys_rt_sigreturn.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
---
 arch/arm64/kernel/signal.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index c7b6de6..cd6b81b 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -316,6 +316,10 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 	if (!ret)
 		user_fastforward_single_step(tsk);
 
+	if (show_unhandled_signals)
+		pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
+				    current->comm, task_pid_nr(current),
+				    __func__, regs->pc, regs->sp);
 	signal_setup_done(ret, ksig, 0);
 }
 
-- 
2.10.2

^ permalink raw reply related

* [PATCH v4 00/12] mmc: Add support to Marvell Xenon SD Host Controller
From: Russell King - ARM Linux @ 2016-12-22 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.67d726f70f6bd48d38a2023513f2711080bc66c8.1481651244.git-series.gregory.clement@free-electrons.com>

On Tue, Dec 13, 2016 at 06:48:29PM +0100, Gregory CLEMENT wrote:
> This the forth version of the series adding support for the SDHCI
> Xenon controller. It can be currently found on the Armada 37xx and the
> Armada 7K/8K but will be also used in more Marvell SoC (and not only
> the mvebu ones actually).

With the problems and niggles fixed, it seems to work here on my 8040
board (along with dma-coherent):

sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
sdhci-pltfm: SDHCI platform and OF driver helper
mmc0: SDHCI controller on f06e0000.sdhci [f06e0000.sdhci] using ADMA 64-bit
mmc0: new high speed MMC card at address 0001
mmcblk0: mmc0:0001 8GND3R 7.28 GiB
mmc1: SDHCI controller on f2780000.sdhci [f2780000.sdhci] using ADMA 64-bit
mmcblk0boot0: mmc0:0001 8GND3R partition 1 4.00 MiB
mmcblk0boot1: mmc0:0001 8GND3R partition 2 4.00 MiB
mmcblk0rpmb: mmc0:0001 8GND3R partition 3 512 KiB
mmc1: new high speed SDHC card at address 0001
mmcblk1: mmc1:0001 00000 14.6 GiB
 mmcblk1: p1 p2 p3

Thanks.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [PATCH v4 11/12] arm64: dts: marvell: add sdhci support for Armada 7K/8K
From: Russell King - ARM Linux @ 2016-12-22 11:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2564fe18eb9cc8a0a1a3311cdf7e7141f35211bd.1481651244.git-series.gregory.clement@free-electrons.com>

On Tue, Dec 13, 2016 at 06:48:40PM +0100, Gregory CLEMENT wrote:
> diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> index 7b6136182ad0..181e8c5de3bf 100644
> --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> @@ -229,6 +229,15 @@
>  
>  			};
>  
> +			ap_sdhci0: sdhci at 6e0000 {
> +				compatible = "marvell,armada-7000-sdhci";
> +				reg = <0x6e0000 0x300>;
> +				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> +				clock-names = "core";
> +				clocks = <&cpm_syscon0 1 4>;
> +				status = "disabled";
> +			};
> +
>  			ap_syscon: system-controller at 6f4000 {
>  				compatible = "marvell,ap806-system-controller",
>  					     "syscon";
> diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
> index e5e3ed678b6f..035b2b2fc9ca 100644
> --- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
> @@ -164,6 +164,16 @@
>  				clocks = <&cpm_syscon0 1 21>;
>  				status = "disabled";
>  			};
> +
> +			cpm_sdhci0: sdhci at 780000 {
> +				compatible = "marvell,armada-7000-sdhci";
> +				reg = <0x780000 0x300>;
> +				interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
> +				clock-names = "core";
> +				clocks = <&cpm_syscon0 1 4>;
> +				status = "disabled";
> +			};
> +

One other point - aren't the SDHCI interfaces dma-coherent on the AP806
and CP110?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [PATCH v4 06/12] dt: bindings: Add bindings for Marvell Xenon SD Host Controller
From: Russell King - ARM Linux @ 2016-12-22 11:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b8acb86f1e7977648977ed5c6b4eb86323e4b777.1481651244.git-series.gregory.clement@free-electrons.com>

On Tue, Dec 13, 2016 at 06:48:35PM +0100, Gregory CLEMENT wrote:
> +Optional Properties:
> +- mmc-card:
> +  mmc-card child node must be provided when current SDHC is for eMMC.
> +  Xenon SDHC often can support both SD and eMMC. This child node indicates that
> +  current SDHC is for eMMC card. Thus Xenon eMMC specific configuration and
> +  operations can be enabled prior to eMMC init sequence.
> +  Please refer to Documentation/devicetree/bindings/mmc/mmc-card.txt.
> +  This child node should not be set if current Xenon SDHC is for SD/SDIO.

This looks like a typo - shouldn't it be "mmccard" and not "mmc-card"?
Your examples below use "mmccard" as does the documentation you point
towards.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [PATCH v4 11/12] arm64: dts: marvell: add sdhci support for Armada 7K/8K
From: Thomas Petazzoni @ 2016-12-22 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161222104502.GV14217@n2100.armlinux.org.uk>

Hello,

On Thu, 22 Dec 2016 10:45:02 +0000, Russell King - ARM Linux wrote:
> On Tue, Dec 13, 2016 at 06:48:40PM +0100, Gregory CLEMENT wrote:
> > diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> > index 7b6136182ad0..181e8c5de3bf 100644
> > --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> > +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> > @@ -229,6 +229,15 @@
> >  
> >  			};
> >  
> > +			ap_sdhci0: sdhci at 6e0000 {
> > +				compatible = "marvell,armada-7000-sdhci";
> > +				reg = <0x6e0000 0x300>;
> > +				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> > +				clock-names = "core";
> > +				clocks = <&cpm_syscon0 1 4>;  
> 
> This seems to be the wrong clock - how can the AP SDHCI core be connected
> to the CPM syscon (which is on a different die.)

Agreed. This cannot be the right clock.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH v4 11/12] arm64: dts: marvell: add sdhci support for Armada 7K/8K
From: Russell King - ARM Linux @ 2016-12-22 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2564fe18eb9cc8a0a1a3311cdf7e7141f35211bd.1481651244.git-series.gregory.clement@free-electrons.com>

On Tue, Dec 13, 2016 at 06:48:40PM +0100, Gregory CLEMENT wrote:
> diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
> index e5e3ed678b6f..035b2b2fc9ca 100644
> --- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
> @@ -164,6 +164,16 @@
>  				clocks = <&cpm_syscon0 1 21>;
>  				status = "disabled";
>  			};
> +
> +			cpm_sdhci0: sdhci at 780000 {
> +				compatible = "marvell,armada-7000-sdhci";
> +				reg = <0x780000 0x300>;
> +				interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
> +				clock-names = "core";
> +				clocks = <&cpm_syscon0 1 4>;
> +				status = "disabled";
> +			};
> +

Oh, and a nitpick, since I've already commented on this patch - there's
a needless extra blank line here...

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [PATCH v4 11/12] arm64: dts: marvell: add sdhci support for Armada 7K/8K
From: Russell King - ARM Linux @ 2016-12-22 10:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2564fe18eb9cc8a0a1a3311cdf7e7141f35211bd.1481651244.git-series.gregory.clement@free-electrons.com>

On Tue, Dec 13, 2016 at 06:48:40PM +0100, Gregory CLEMENT wrote:
> diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> index 7b6136182ad0..181e8c5de3bf 100644
> --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
> @@ -229,6 +229,15 @@
>  
>  			};
>  
> +			ap_sdhci0: sdhci at 6e0000 {
> +				compatible = "marvell,armada-7000-sdhci";
> +				reg = <0x6e0000 0x300>;
> +				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> +				clock-names = "core";
> +				clocks = <&cpm_syscon0 1 4>;

This seems to be the wrong clock - how can the AP SDHCI core be connected
to the CPM syscon (which is on a different die.)

I think you first need a patch to add this clock to the AP syscon...

Thanks.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [linux-sunxi] Re: Problems to Allwinner H3's eFUSE/SID
From: Hans de Goede @ 2016-12-22 10:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGb2v64s08tey0ZevivFpxBk-dRjrApiyyh3mwYyVARHQV=Www@mail.gmail.com>

Hi,

On 22-12-16 11:31, Chen-Yu Tsai wrote:
> On Tue, Dec 20, 2016 at 12:17 AM, Hans de Goede <hdegoede@redhat.com> wrote:
>> Hi,
>>
>>
>> On 19-12-16 17:06, Icenowy Zheng wrote:
>>>
>>>
>>>
>>> 19.12.2016, 23:30, "Hans de Goede" <hdegoede@redhat.com>:
>>>>
>>>> Hi,
>>>>
>>>> On 19-12-16 16:22, Icenowy Zheng wrote:
>>>>>
>>>>>  Hi everyone,
>>>>>
>>>>>  Today, I and KotCzarny on IRC of linux-sunxi found a problem in the SID
>>>>>  controller of H3 (incl. H2+).
>>>>>
>>>>>  See https://irclog.whitequark.org/linux-sunxi/2016-12-19 .
>>>>>
>>>>>  Two read method of the H3 eFUSE is used in the BSP: by register
>>>>> accessing, or
>>>>>  directly access 0x01c14200.
>>>>>
>>>>>  From http://linux-sunxi.org/SID_Register_Guide we can see a difference
>>>>> between
>>>>>  the H3 SIDs read out by sunxi-fel and the H3 SIDs read out by devmem2
>>>>> (in
>>>>>  legacy kernel).
>>>>>
>>>>>  According to the source of H2+ BSP[1], H2+ and H3 can be differed by
>>>>> the last
>>>>>  byte of the first word of SID. (0x42 and 0x83 is H2+, 0x00 and 0x81 is
>>>>> H3,
>>>>>  0x58 is H3D (currently not known SoC) )
>>>>>
>>>>>  However, all the SIDs retrieved by `sunxi-fel sid`, both H2+ and H3,
>>>>> start
>>>>>  with 0x02004620, which do not match this rule.
>>>>>
>>>>>  The readout by devmem2 is satisfying this rule: their first word is
>>>>>  0x02c00081, matches H3.
>>>>>
>>>>>  Then I found the SID-reading code from BSP U-Boot[2], which is based on
>>>>>  register operations. With this kind of code (I wrote one prototype in
>>>>>  userspace with /dev/mem), I got "02c00081 74004620 50358720 3c27048e"
>>>>> on
>>>>>  my Orange Pi One. ("02004620 74358720 5027048e 3c0000c3" with sunxi-fel
>>>>> sid)
>>>>>  And, after accessing to the SID by registers, the value of *0x01c14200
>>>>> become
>>>>>  also "02c00081".
>>>>>
>>>>>  With direct access to 0x01c14200 after boot with mainline kernel, I got
>>>>> also
>>>>>  "02004620".
>>>>>
>>>>>  Then I altered the program to do the register operations with
>>>>> sunxi-fel, the
>>>>>  result is also "02c00081", and changed `sunxi-fel sid` result to
>>>>> "02c00081".
>>>>>
>>>>>  Summary:
>>>>>
>>>>>  +-----------------------------------------------+----------------+
>>>>>  | Read situation | The first word |
>>>>>  +-----------------------------------------------+----------------+
>>>>>  | Direct read by sunxi-fel | 02004620 |
>>>>>  | Direct read in mainline /dev/mem | 02004620 |
>>>>>  | Direct read in legacy /dev/mem | 02c00081 |
>>>>>  | Register access in FEL | 02c00081 |
>>>>>  | Register access in mainline | 02c00081 |
>>>>>  | Direct read after register access in FEL | 02c00081 |
>>>>>  | Direct read after register access in mainline | 02c00081 |
>>>>>  +-----------------------------------------------+----------------+
>>>>>
>>>>>  According to some facts:
>>>>>  - The register based access to SID is weird: it needs ~5 register
>>>>>    operations per word of SID.
>>>>>  - Reading via register access will change the value when reading by
>>>>> accessing
>>>>>    0x01c14200.
>>>>>  - In the u-boot code[2] there's some functions which read out the SID
>>>>> by
>>>>>    registers and then abandoned the value.
>>>>>  - This mismatch do not exist on A64.
>>>>>
>>>>>  I think that: Allwinner designed a "cache" to the SID to make the
>>>>> simplify the
>>>>>  code to read it, and it automatically loaded the cache when booting;
>>>>> however,
>>>>>  when doing first cache on H3, some byte shifts occured, and the value
>>>>> become
>>>>>  wrong. A manual read on H3 can make the cache right again. This is a
>>>>> silicon
>>>>>  bug, and fixed in A64.
>>>>>
>>>>>  This raises a problem: currently many systems has used the misread SID
>>>>> value to
>>>>>  generated lots of MAC addresses, and workaround this SID bug will
>>>>> change them.
>>>>>
>>>>>  However, if this bug is not workarounded, the sun8i-ths driver won't
>>>>> work well
>>>>>  (as some calibartion value lies in eFUSE). I think some early user of
>>>>> this
>>>>>  driver has already experienced bad readout value.
>>>>>  (The calibration value differs on my opi1 and KotCzarny's opipc)
>>>>>
>>>>>  And many wrong SID values have been generated by `sunxi-fel sid`.
>>>>> (Although I
>>>>>  think sunxi-fel must have the workaround)
>>>>>
>>>>>  Note: in this email, "SID" and "eFUSE" both indicate the controller on
>>>>> H3/A64
>>>>>  at 0x01c14000, which is a OTP memory implemented by eFUSE technique.
>>>>>
>>>>>  Furthermore, A83T may also have this problem, testers are welcome!
>>>>>
>>>>>  [1]
>>>>> http://filez.zoobab.com/allwinner/h2/201609022/lichee/linux-3.4/arch/arm/mach-sunxi/sun8i.c
>>>>>  [2]
>>>>> http://filez.zoobab.com/allwinner/h2/201609022/lichee/brandy/u-boot-2011.09/arch/arm/cpu/armv7/sun8iw7/efuse.c
>>>>>
>>>>>  Experiments:
>>>>>  - https://gist.github.com/Icenowy/2f4859ab1bc05814522fc7445179a8c9
>>>>>    A SID readout shell script via FEL with register access.
>>>>>  - https://31.135.195.151:20281/d/efuse/
>>>>>    A SID readout program via /dev/mem with register access by KotCzarny.
>>>>>    (with statically compiled binary)
>>>>
>>>>
>>>> Good detective work!
>>>>
>>>> I believe this would best be fixed by making u-boot use the register
>>>> access
>>>> method to get the SID on affected chips, and make sure u-boot reads the
>>>> SID at-least once.
>>>
>>>
>>> Yes.
>>>
>>> However, what I considered is that fixing this bug will change H3 devices'
>>> MAC addresses, as they are derived from SID.
>>
>>
>> I know, but I think we will just need to accept this onetime change
>> of the fixed MAC addresses to fix this bug. I don't think this is
>> a big problem since the driver for the H3 ethernet has not been
>> merged into the mainline kernel yet.
>
> Do we still need to do the CRC32 across the SID values to generate
> the MAC addresses?

Yes this does not change that a single word has not enough
randomness in it.

Regards,

Hans

^ permalink raw reply

* [linux-sunxi] Re: Problems to Allwinner H3's eFUSE/SID
From: Chen-Yu Tsai @ 2016-12-22 10:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <12fa0112-b0e2-21e0-f369-7372944153d5@redhat.com>

On Tue, Dec 20, 2016 at 12:17 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
>
> On 19-12-16 17:06, Icenowy Zheng wrote:
>>
>>
>>
>> 19.12.2016, 23:30, "Hans de Goede" <hdegoede@redhat.com>:
>>>
>>> Hi,
>>>
>>> On 19-12-16 16:22, Icenowy Zheng wrote:
>>>>
>>>>  Hi everyone,
>>>>
>>>>  Today, I and KotCzarny on IRC of linux-sunxi found a problem in the SID
>>>>  controller of H3 (incl. H2+).
>>>>
>>>>  See https://irclog.whitequark.org/linux-sunxi/2016-12-19 .
>>>>
>>>>  Two read method of the H3 eFUSE is used in the BSP: by register
>>>> accessing, or
>>>>  directly access 0x01c14200.
>>>>
>>>>  From http://linux-sunxi.org/SID_Register_Guide we can see a difference
>>>> between
>>>>  the H3 SIDs read out by sunxi-fel and the H3 SIDs read out by devmem2
>>>> (in
>>>>  legacy kernel).
>>>>
>>>>  According to the source of H2+ BSP[1], H2+ and H3 can be differed by
>>>> the last
>>>>  byte of the first word of SID. (0x42 and 0x83 is H2+, 0x00 and 0x81 is
>>>> H3,
>>>>  0x58 is H3D (currently not known SoC) )
>>>>
>>>>  However, all the SIDs retrieved by `sunxi-fel sid`, both H2+ and H3,
>>>> start
>>>>  with 0x02004620, which do not match this rule.
>>>>
>>>>  The readout by devmem2 is satisfying this rule: their first word is
>>>>  0x02c00081, matches H3.
>>>>
>>>>  Then I found the SID-reading code from BSP U-Boot[2], which is based on
>>>>  register operations. With this kind of code (I wrote one prototype in
>>>>  userspace with /dev/mem), I got "02c00081 74004620 50358720 3c27048e"
>>>> on
>>>>  my Orange Pi One. ("02004620 74358720 5027048e 3c0000c3" with sunxi-fel
>>>> sid)
>>>>  And, after accessing to the SID by registers, the value of *0x01c14200
>>>> become
>>>>  also "02c00081".
>>>>
>>>>  With direct access to 0x01c14200 after boot with mainline kernel, I got
>>>> also
>>>>  "02004620".
>>>>
>>>>  Then I altered the program to do the register operations with
>>>> sunxi-fel, the
>>>>  result is also "02c00081", and changed `sunxi-fel sid` result to
>>>> "02c00081".
>>>>
>>>>  Summary:
>>>>
>>>>  +-----------------------------------------------+----------------+
>>>>  | Read situation | The first word |
>>>>  +-----------------------------------------------+----------------+
>>>>  | Direct read by sunxi-fel | 02004620 |
>>>>  | Direct read in mainline /dev/mem | 02004620 |
>>>>  | Direct read in legacy /dev/mem | 02c00081 |
>>>>  | Register access in FEL | 02c00081 |
>>>>  | Register access in mainline | 02c00081 |
>>>>  | Direct read after register access in FEL | 02c00081 |
>>>>  | Direct read after register access in mainline | 02c00081 |
>>>>  +-----------------------------------------------+----------------+
>>>>
>>>>  According to some facts:
>>>>  - The register based access to SID is weird: it needs ~5 register
>>>>    operations per word of SID.
>>>>  - Reading via register access will change the value when reading by
>>>> accessing
>>>>    0x01c14200.
>>>>  - In the u-boot code[2] there's some functions which read out the SID
>>>> by
>>>>    registers and then abandoned the value.
>>>>  - This mismatch do not exist on A64.
>>>>
>>>>  I think that: Allwinner designed a "cache" to the SID to make the
>>>> simplify the
>>>>  code to read it, and it automatically loaded the cache when booting;
>>>> however,
>>>>  when doing first cache on H3, some byte shifts occured, and the value
>>>> become
>>>>  wrong. A manual read on H3 can make the cache right again. This is a
>>>> silicon
>>>>  bug, and fixed in A64.
>>>>
>>>>  This raises a problem: currently many systems has used the misread SID
>>>> value to
>>>>  generated lots of MAC addresses, and workaround this SID bug will
>>>> change them.
>>>>
>>>>  However, if this bug is not workarounded, the sun8i-ths driver won't
>>>> work well
>>>>  (as some calibartion value lies in eFUSE). I think some early user of
>>>> this
>>>>  driver has already experienced bad readout value.
>>>>  (The calibration value differs on my opi1 and KotCzarny's opipc)
>>>>
>>>>  And many wrong SID values have been generated by `sunxi-fel sid`.
>>>> (Although I
>>>>  think sunxi-fel must have the workaround)
>>>>
>>>>  Note: in this email, "SID" and "eFUSE" both indicate the controller on
>>>> H3/A64
>>>>  at 0x01c14000, which is a OTP memory implemented by eFUSE technique.
>>>>
>>>>  Furthermore, A83T may also have this problem, testers are welcome!
>>>>
>>>>  [1]
>>>> http://filez.zoobab.com/allwinner/h2/201609022/lichee/linux-3.4/arch/arm/mach-sunxi/sun8i.c
>>>>  [2]
>>>> http://filez.zoobab.com/allwinner/h2/201609022/lichee/brandy/u-boot-2011.09/arch/arm/cpu/armv7/sun8iw7/efuse.c
>>>>
>>>>  Experiments:
>>>>  - https://gist.github.com/Icenowy/2f4859ab1bc05814522fc7445179a8c9
>>>>    A SID readout shell script via FEL with register access.
>>>>  - https://31.135.195.151:20281/d/efuse/
>>>>    A SID readout program via /dev/mem with register access by KotCzarny.
>>>>    (with statically compiled binary)
>>>
>>>
>>> Good detective work!
>>>
>>> I believe this would best be fixed by making u-boot use the register
>>> access
>>> method to get the SID on affected chips, and make sure u-boot reads the
>>> SID at-least once.
>>
>>
>> Yes.
>>
>> However, what I considered is that fixing this bug will change H3 devices'
>> MAC addresses, as they are derived from SID.
>
>
> I know, but I think we will just need to accept this onetime change
> of the fixed MAC addresses to fix this bug. I don't think this is
> a big problem since the driver for the H3 ethernet has not been
> merged into the mainline kernel yet.

Do we still need to do the CRC32 across the SID values to generate
the MAC addresses?

ChenYu

>> Maybe we should add #ifdef's to MAC generation code after this fix.
>
>
> I would rather not see #ifdefs for this, see above, but that is no
> longer my call, see below.
>
>>
>> (This is why I will create this discussion)
>>
>> P.S. Are you still the maintainer of sunxi boards support of u-boot? The
>> MAINTAINER file in board/sunxi indicates this.
>
>
> No I'm no longer the maintainer, I'm still the MAINTAINER file because
> I have a lot of boards and as such I'm still the point of contact for
> those boards (if there are any board specific issues / questions), but
> as indicated in the main MAINTAINERS file Jagan Teki <jagan@openedev.com>
> is the maintainer now.
>
>
> Regards,
>
> Hans
>
> --
> You received this message because you are subscribed to the Google Groups
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to linux-sunxi+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* [RFT PATCH] ARM64: dts: meson-gxbb: Add reserved memory zone and usable memory range
From: Heinrich Schuchardt @ 2016-12-22 10:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <56869b90-6bee-f6ae-a7b1-884b4c0d72c0@baylibre.com>

On 12/14/2016 10:52 AM, Neil Armstrong wrote:

> Hi Heinrich,
> 
> Thanks for testing and for the report,
> we are still struggling into finding what are these zones and how to label them correctly.
> 
> We need to identify the zones on all boards, the patch I provided works on a non-odroid-c2 and gxm and gxl boards.
> 
> Neil
> 
Hello Neil,

the configuration below works for me on the Hardkernel Odroid C2.

ramoops is needed for CONFIG_PSTORE_RAM.
Debian Stretch has CONFIG_PSTORE_RAM=m. Same is true for Fedora.
I have chosen the address arbitrarily. To accommodate 512 MB boards we
would have to put it below 0x20000000.
The size parameters are the same as in hisilicon/hi6220-hikey.dts and
qcom-apq8064-asus-nexus7-flo.dts.

linux,cma is used for contiguous memory assignment. I have taken the
align parameter from arm-src-kernel-2016-08-18-26e194264c.tar.gz
provided by Amlogic at
http://openlinux.amlogic.com:8000/download/ARM/kernel/ .
See Documentation/DMA-API.txt for the usage of align.
They use the same value 0x400000 for all GXBB boards.
So we want to put this zone into meson-gxbb.dtsi.

secmon is used by drivers/firmware/meson/meson_sm.c.
Amlogic uses the same address range for all 64bit boards.

	memory at 0 {
		device_type = "memory";
		linux,usable-memory = <0x0 0x1000000 0x0 0x7f000000>;
	};

	reserved-memory {
		#address-cells = <0x2>;
		#size-cells = <0x2>;
		ranges;

		ramoops at 0x23f00000 {
			compatible = "ramoops";
			reg = <0x0 0x23f00000 0x0 0x100000>;
			record-size = <0x20000>;
			console-size = <0x20000>;
			ftrace-size = <0x20000>;
		};

		secmon: secmon {
			compatible = "amlogic, aml_secmon_memory";
			reg = <0x0 0x10000000 0x0 0x200000>;
			no-map;
		};

		linux,cma {
			compatible = "shared-dma-pool";
			reusable;
			size = <0x0 0xbc00000>;
			alignment = <0x0 0x400000>;
			linux,cma-default;
		};
	};

Best regards

Heinrich Schuchardt

^ permalink raw reply

* [PATCH v2] ARM: dts: turris-omnia: add support for ethernet switch
From: Uwe Kleine-König @ 2016-12-22  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

The Turris Omnia features a Marvell MV88E7176 ethernet switch. Add it to
the dts.

Signed-off-by: Uwe Kleine-K?nig <uwe@kleine-koenig.org>
---
Changes since (implicit) v1:
 - drop mdio bus and per port phy-handle as they match the default
   setup.

One thing I was surprised is that the mv88e6xxx module isn't autoloaded
by udev. Is this expected?

Best regards
Uwe

 arch/arm/boot/dts/armada-385-turris-omnia.dts | 66 ++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
index ab49acb2d452..f8e55fa7f0fa 100644
--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
+++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
@@ -122,7 +122,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&ge0_rgmii_pins>;
 	status = "okay";
-	phy-mode = "rgmii-id";
+	phy-mode = "rgmii";
 
 	fixed-link {
 		speed = <1000>;
@@ -135,7 +135,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&ge1_rgmii_pins>;
 	status = "okay";
-	phy-mode = "rgmii-id";
+	phy-mode = "rgmii";
 
 	fixed-link {
 		speed = <1000>;
@@ -274,6 +274,68 @@
 	};
 
 	/* Switch MV88E7176 at address 0x10 */
+	switch at 10 {
+		compatible = "marvell,mv88e6085";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		dsa,member = <0 0>;
+
+		reg = <0x10>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			ports at 0 {
+				reg = <0>;
+				label = "lan0";
+			};
+
+			ports at 1 {
+				reg = <1>;
+				label = "lan1";
+			};
+
+			ports at 2 {
+				reg = <2>;
+				label = "lan2";
+			};
+
+			ports at 3 {
+				reg = <3>;
+				label = "lan3";
+			};
+
+			ports at 4 {
+				reg = <4>;
+				label = "lan4";
+			};
+
+			ports at 5 {
+				reg = <5>;
+				label = "cpu";
+				ethernet = <&eth1>;
+				phy-mode = "rgmii-id";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			ports at 6 {
+				reg = <6>;
+				label = "cpu";
+				ethernet = <&eth0>;
+				phy-mode = "rgmii-id";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+		};
+	};
 };
 
 &pinctrl {
-- 
2.11.0

^ permalink raw reply related

* [PATCH] mm: pmd dirty emulation in page fault handler
From: Kirill A. Shutemov @ 2016-12-22  8:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482364101-16204-1-git-send-email-minchan@kernel.org>

On Thu, Dec 22, 2016 at 08:48:21AM +0900, Minchan Kim wrote:
> Andreas reported [1] made a test in jemalloc hang in THP mode in arm64.

I guess you wanted put b8d3c4c3009d before [1], right?

> http://lkml.kernel.org/r/mvmmvfy37g1.fsf at hawking.suse.de
> 
> The problem is page fault handler supports only accessed flag emulation
> for THP page of SW-dirty/accessed architecture.
> 
> This patch enables dirty-bit emulation for those architectures.
> Without it, MADV_FREE makes application hang by repeated fault forever.
> 
> [1] mm/huge_memory.c: don't split THP page when MADV_FREE syscall is called
> 
> Cc: Jason Evans <je@fb.com>
> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: linux-arch at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: <stable@vger.kernel.org> [4.5+]
> Fixes: b8d3c4c3009d ("mm/huge_memory.c: don't split THP page when MADV_FREE syscall is called")
> Reported-by: Andreas Schwab <schwab@suse.de>
> Signed-off-by: Minchan Kim <minchan@kernel.org>
> ---
>  mm/huge_memory.c |  6 ++++--
>  mm/memory.c      | 18 ++++++++++--------
>  2 files changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 10eedbf..29ec8a4 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -883,15 +883,17 @@ void huge_pmd_set_accessed(struct vm_fault *vmf, pmd_t orig_pmd)
>  {
>  	pmd_t entry;
>  	unsigned long haddr;
> +	bool write = vmf->flags & FAULT_FLAG_WRITE;
>  
>  	vmf->ptl = pmd_lock(vmf->vma->vm_mm, vmf->pmd);
>  	if (unlikely(!pmd_same(*vmf->pmd, orig_pmd)))
>  		goto unlock;
>  
>  	entry = pmd_mkyoung(orig_pmd);
> +	if (write)
> +		entry = pmd_mkdirty(entry);
>  	haddr = vmf->address & HPAGE_PMD_MASK;
> -	if (pmdp_set_access_flags(vmf->vma, haddr, vmf->pmd, entry,
> -				vmf->flags & FAULT_FLAG_WRITE))
> +	if (pmdp_set_access_flags(vmf->vma, haddr, vmf->pmd, entry, write))
>  		update_mmu_cache_pmd(vmf->vma, vmf->address, vmf->pmd);
>  
>  unlock:
> diff --git a/mm/memory.c b/mm/memory.c
> index 36c774f..7408ddc 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -3637,18 +3637,20 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
>  			if (pmd_protnone(orig_pmd) && vma_is_accessible(vma))
>  				return do_huge_pmd_numa_page(&vmf, orig_pmd);
>  
> -			if ((vmf.flags & FAULT_FLAG_WRITE) &&
> -					!pmd_write(orig_pmd)) {
> -				ret = wp_huge_pmd(&vmf, orig_pmd);
> -				if (!(ret & VM_FAULT_FALLBACK))
> +			if (vmf.flags & FAULT_FLAG_WRITE) {
> +				if (!pmd_write(orig_pmd)) {
> +					ret = wp_huge_pmd(&vmf, orig_pmd);
> +					if (ret == VM_FAULT_FALLBACK)

In theory, more than one flag can be set and it would lead to
false-negative. Bit check was the right thing.

And I don't understand why do you need to change code in
__handle_mm_fault() at all.
>From what I see change to huge_pmd_set_accessed() should be enough.

> +						goto pte_fault;
>  					return ret;
> -			} else {
> -				huge_pmd_set_accessed(&vmf, orig_pmd);
> -				return 0;
> +				}
>  			}
> +
> +			huge_pmd_set_accessed(&vmf, orig_pmd);
> +			return 0;
>  		}
>  	}
> -
> +pte_fault:
>  	return handle_pte_fault(&vmf);
>  }
>  
> -- 
> 2.7.4
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo at kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email at kvack.org </a>

-- 
 Kirill A. Shutemov

^ permalink raw reply

* [PATCH V5 1/3] ARM64 LPC: Indirect ISA port IO introduced
From: Ming Lei @ 2016-12-22  8:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478576829-112707-2-git-send-email-yuanzhichang@hisilicon.com>

Hi Guys,

On Tue, Nov 8, 2016 at 11:47 AM, zhichang.yuan
<yuanzhichang@hisilicon.com> wrote:
> For arm64, there is no I/O space as other architectural platforms, such as
> X86. Most I/O accesses are achieved based on MMIO. But for some arm64 SoCs,
> such as Hip06, when accessing some legacy ISA devices connected to LPC, those
> known port addresses are used to control the corresponding target devices, for
> example, 0x2f8 is for UART, 0xe4 is for ipmi-bt. It is different from the
> normal MMIO mode in using.
>
> To drive these devices, this patch introduces a method named indirect-IO.
> In this method the in/out pair in arch/arm64/include/asm/io.h will be
> redefined. When upper layer drivers call in/out with those known legacy port
> addresses to access the peripherals, the hooking functions corrresponding to
> those target peripherals will be called. Through this way, those upper layer
> drivers which depend on in/out can run on Hip06 without any changes.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: zhichang.yuan <yuanzhichang@hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> ---
>  arch/arm64/Kconfig             |  6 +++
>  arch/arm64/include/asm/extio.h | 94 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm64/include/asm/io.h    | 29 +++++++++++++
>  arch/arm64/kernel/Makefile     |  1 +
>  arch/arm64/kernel/extio.c      | 27 ++++++++++++
>  5 files changed, 157 insertions(+)

When I applied these three patches against current linus tree and
enable CONFIG_HISILICON_LPC, the following build failure[1] is
triggered when running 'make modules'.


Thanks,
Ming

[1] 'make modules' failure log

  Building modules, stage 2.
  MODPOST 2260 modules
ERROR: "inb" [drivers/watchdog/wdt_pci.ko] undefined!
ERROR: "outb" [drivers/watchdog/wdt_pci.ko] undefined!
ERROR: "outb" [drivers/watchdog/pcwd_pci.ko] undefined!
ERROR: "inb" [drivers/watchdog/pcwd_pci.ko] undefined!
ERROR: "outw" [drivers/video/vgastate.ko] undefined!
ERROR: "outb" [drivers/video/vgastate.ko] undefined!
ERROR: "inb" [drivers/video/vgastate.ko] undefined!
ERROR: "outw" [drivers/video/fbdev/vt8623fb.ko] undefined!
ERROR: "inb" [drivers/video/fbdev/vt8623fb.ko] undefined!
ERROR: "outb" [drivers/video/fbdev/vt8623fb.ko] undefined!
ERROR: "outw" [drivers/video/fbdev/tridentfb.ko] undefined!
ERROR: "inb" [drivers/video/fbdev/tridentfb.ko] undefined!
ERROR: "outb" [drivers/video/fbdev/tridentfb.ko] undefined!
ERROR: "inb" [drivers/video/fbdev/tdfxfb.ko] undefined!
.....
ERROR: "inb" [drivers/ata/pata_cmd64x.ko] undefined!
ERROR: "inb" [drivers/ata/pata_artop.ko] undefined!
scripts/Makefile.modpost:91: recipe for target '__modpost' failed
make[1]: *** [__modpost] Error 1
Makefile:1196: recipe for target 'modules' failed
make: *** [modules] Error 2


>  create mode 100644 arch/arm64/include/asm/extio.h
>  create mode 100644 arch/arm64/kernel/extio.c
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 969ef88..b44070b 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -163,6 +163,12 @@ config ARCH_MMAP_RND_COMPAT_BITS_MIN
>  config ARCH_MMAP_RND_COMPAT_BITS_MAX
>         default 16
>
> +config ARM64_INDIRECT_PIO
> +       bool "access peripherals with legacy I/O port"
> +       help
> +         Support special accessors for ISA I/O devices. This is needed for
> +         SoCs that do not support standard read/write for the ISA range.
> +
>  config NO_IOPORT_MAP
>         def_bool y if !PCI
>
> diff --git a/arch/arm64/include/asm/extio.h b/arch/arm64/include/asm/extio.h
> new file mode 100644
> index 0000000..6ae0787
> --- /dev/null
> +++ b/arch/arm64/include/asm/extio.h
> @@ -0,0 +1,94 @@
> +/*
> + * Copyright (C) 2016 Hisilicon Limited, All Rights Reserved.
> + * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __LINUX_EXTIO_H
> +#define __LINUX_EXTIO_H
> +
> +struct extio_ops {
> +       unsigned long start;/* inclusive, sys io addr */
> +       unsigned long end;/* inclusive, sys io addr */
> +
> +       u64 (*pfin)(void *devobj, unsigned long ptaddr, size_t dlen);
> +       void (*pfout)(void *devobj, unsigned long ptaddr, u32 outval,
> +                                       size_t dlen);
> +       u64 (*pfins)(void *devobj, unsigned long ptaddr, void *inbuf,
> +                               size_t dlen, unsigned int count);
> +       void (*pfouts)(void *devobj, unsigned long ptaddr,
> +                               const void *outbuf, size_t dlen,
> +                               unsigned int count);
> +       void *devpara;
> +};
> +
> +extern struct extio_ops *arm64_extio_ops;
> +
> +#define DECLARE_EXTIO(bw, type)                                                \
> +extern type in##bw(unsigned long addr);                                        \
> +extern void out##bw(type value, unsigned long addr);                   \
> +extern void ins##bw(unsigned long addr, void *buffer, unsigned int count);\
> +extern void outs##bw(unsigned long addr, const void *buffer, unsigned int count);
> +
> +#define BUILD_EXTIO(bw, type)                                          \
> +type in##bw(unsigned long addr)                                                \
> +{                                                                      \
> +       if (!arm64_extio_ops || arm64_extio_ops->start > addr ||        \
> +                       arm64_extio_ops->end < addr)                    \
> +               return read##bw(PCI_IOBASE + addr);                     \
> +       return arm64_extio_ops->pfin ?                                  \
> +               arm64_extio_ops->pfin(arm64_extio_ops->devpara,         \
> +                       addr, sizeof(type)) : -1;                       \
> +}                                                                      \
> +                                                                       \
> +void out##bw(type value, unsigned long addr)                           \
> +{                                                                      \
> +       if (!arm64_extio_ops || arm64_extio_ops->start > addr ||        \
> +                       arm64_extio_ops->end < addr)                    \
> +               write##bw(value, PCI_IOBASE + addr);                    \
> +       else                                                            \
> +               if (arm64_extio_ops->pfout)                             \
> +                       arm64_extio_ops->pfout(arm64_extio_ops->devpara,\
> +                               addr, value, sizeof(type));             \
> +}                                                                      \
> +                                                                       \
> +void ins##bw(unsigned long addr, void *buffer, unsigned int count)     \
> +{                                                                      \
> +       if (!arm64_extio_ops || arm64_extio_ops->start > addr ||        \
> +                       arm64_extio_ops->end < addr)                    \
> +               reads##bw(PCI_IOBASE + addr, buffer, count);            \
> +       else                                                            \
> +               if (arm64_extio_ops->pfins)                             \
> +                       arm64_extio_ops->pfins(arm64_extio_ops->devpara,\
> +                               addr, buffer, sizeof(type), count);     \
> +}                                                                      \
> +                                                                       \
> +void outs##bw(unsigned long addr, const void *buffer, unsigned int count)      \
> +{                                                                      \
> +       if (!arm64_extio_ops || arm64_extio_ops->start > addr ||        \
> +                       arm64_extio_ops->end < addr)                    \
> +               writes##bw(PCI_IOBASE + addr, buffer, count);           \
> +       else                                                            \
> +               if (arm64_extio_ops->pfouts)                            \
> +                       arm64_extio_ops->pfouts(arm64_extio_ops->devpara,\
> +                               addr, buffer, sizeof(type), count);     \
> +}
> +
> +static inline void arm64_set_extops(struct extio_ops *ops)
> +{
> +       if (ops)
> +               WRITE_ONCE(arm64_extio_ops, ops);
> +}
> +
> +#endif /* __LINUX_EXTIO_H*/
> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> index 0bba427..136735d 100644
> --- a/arch/arm64/include/asm/io.h
> +++ b/arch/arm64/include/asm/io.h
> @@ -31,6 +31,7 @@
>  #include <asm/early_ioremap.h>
>  #include <asm/alternative.h>
>  #include <asm/cpufeature.h>
> +#include <asm/extio.h>
>
>  #include <xen/xen.h>
>
> @@ -149,6 +150,34 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
>  #define IO_SPACE_LIMIT         (PCI_IO_SIZE - 1)
>  #define PCI_IOBASE             ((void __iomem *)PCI_IO_START)
>
> +
> +/*
> + * redefine the in(s)b/out(s)b for indirect-IO.
> + */
> +#ifdef CONFIG_ARM64_INDIRECT_PIO
> +#define inb inb
> +#define outb outb
> +#define insb insb
> +#define outsb outsb
> +/* external declaration */
> +DECLARE_EXTIO(b, u8)
> +
> +#define inw inw
> +#define outw outw
> +#define insw insw
> +#define outsw outsw
> +
> +DECLARE_EXTIO(w, u16)
> +
> +#define inl inl
> +#define outl outl
> +#define insl insl
> +#define outsl outsl
> +
> +DECLARE_EXTIO(l, u32)
> +#endif
> +
> +
>  /*
>   * String version of I/O memory access operations.
>   */
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 7d66bba..60e0482 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -31,6 +31,7 @@ arm64-obj-$(CONFIG_COMPAT)            += sys32.o kuser32.o signal32.o         \
>                                            sys_compat.o entry32.o
>  arm64-obj-$(CONFIG_FUNCTION_TRACER)    += ftrace.o entry-ftrace.o
>  arm64-obj-$(CONFIG_MODULES)            += arm64ksyms.o module.o
> +arm64-obj-$(CONFIG_ARM64_INDIRECT_PIO) += extio.o
>  arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)  += module-plts.o
>  arm64-obj-$(CONFIG_PERF_EVENTS)                += perf_regs.o perf_callchain.o
>  arm64-obj-$(CONFIG_HW_PERF_EVENTS)     += perf_event.o
> diff --git a/arch/arm64/kernel/extio.c b/arch/arm64/kernel/extio.c
> new file mode 100644
> index 0000000..647b3fa
> --- /dev/null
> +++ b/arch/arm64/kernel/extio.c
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 2016 Hisilicon Limited, All Rights Reserved.
> + * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/io.h>
> +
> +struct extio_ops *arm64_extio_ops;
> +
> +
> +BUILD_EXTIO(b, u8)
> +
> +BUILD_EXTIO(w, u16)
> +
> +BUILD_EXTIO(l, u32)
> --
> 1.9.1
>



-- 
Ming Lei

^ permalink raw reply

* How to remove warn msg "cache: parent cpui should not be sleeping" i=1, 2, 3...
From: Jisheng Zhang @ 2016-12-22  7:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a793d088-2faf-3ea8-41b6-f0b614a71e19@arm.com>

On Wed, 21 Dec 2016 16:54:22 +0000 Sudeep Holla wrote:

> On 21/12/16 11:37, Jisheng Zhang wrote:
> > Hi all,
> > 
> > I'm not sure this is a bug, when wake up from s2ram, I could get something
> > like:
> > 
> > [  313.271464] Enabling non-boot CPUs ...
> > [  313.271551] CPU1: Booted secondary processor
> > [  313.271556] Detected VIPT I-cache on CPU1
> > [  313.301378]  cache: parent cpu1 should not be sleeping
> > [  313.301504] CPU1 is up
> > [  313.301582] CPU2: Booted secondary processor
> > [  313.301585] Detected VIPT I-cache on CPU2
> > [  313.331485]  cache: parent cpu2 should not be sleeping
> > [  313.331605] CPU2 is up
> > [  313.331683] CPU3: Booted secondary processor
> > [  313.331686] Detected VIPT I-cache on CPU3
> > [  313.361599]  cache: parent cpu3 should not be sleeping
> > [  313.361719] CPU3 is up
> > 
> > This is because we call cpu_device_create() when secondary cpu is brought
> > online, the cpu_cache device's parent device: cpu device isn't already
> > resumed, all device resume will resume after secondary cores are brought
> > up.
> > 
> > What's the elegant solution to remove this warning msg?
> >   
> 
> It is not a serious warning as you can see a comment in the code:
> "/*
>  * This is a fib.  But we'll allow new children to be added below
>  * a resumed device, even if the device hasn't been completed yet.
>  */"
> 

Great, make sense, I agree with "this is not a serious warn msg".

Thanks for the help,
Jisheng


> But if we think it needs to be removed, I have something like below in
> my mind. I am not sure if this is hacky or not(completely untested, not
> even compiled).
> 
> Regards,
> Sudeep
> 
> -->8  
> 
> diff --git i/drivers/base/cpu.c w/drivers/base/cpu.c
> index 4c28e1a09786..2a5c04377adf 100644
> --- i/drivers/base/cpu.c
> +++ w/drivers/base/cpu.c
> @@ -344,6 +344,14 @@ static int cpu_uevent(struct device *dev, struct
> kobj_uevent_env *env)
>  }
>  #endif
> 
> +static int cpu_dev_pm_unset_is_prepared(unsigned int cpu)
> +{
> +       struct device *cpu_dev = get_cpu_device(cpu);
> +
> +       if(cpu_dev)
> +               cpu_dev->power.is_prepared = false;
> +       return 0;
> +}
>  /*
>   * register_cpu - Setup a sysfs device for a CPU.
>   * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
> @@ -377,7 +385,9 @@ int register_cpu(struct cpu *cpu, int num)
>         per_cpu(cpu_sys_devices, num) = &cpu->dev;
>         register_cpu_under_node(num, cpu_to_node(num));
> 
> -       return 0;
> +       return cpuhp_setup_state_nocalls(CPUHP_CPUDEV_PM_PREPARE,
> +                                "base/cpu/dev_pm:prepare",
> +                                cpu_dev_pm_unset_is_prepared, NULL);
>  }
> 
>  struct device *get_cpu_device(unsigned cpu)
> diff --git i/include/linux/cpuhotplug.h w/include/linux/cpuhotplug.h
> index 2ab7bf53d529..5bfe3c1aa148 100644
> --- i/include/linux/cpuhotplug.h
> +++ w/include/linux/cpuhotplug.h
> @@ -51,6 +51,7 @@ enum cpuhp_state {
>         CPUHP_SLAB_PREPARE,
>         CPUHP_MD_RAID5_PREPARE,
>         CPUHP_RCUTREE_PREP,
> +       CPUHP_CPUDEV_PM_PREPARE,
>         CPUHP_CPUIDLE_COUPLED_PREPARE,
>         CPUHP_POWERPC_PMAC_PREPARE,
>         CPUHP_POWERPC_MMU_CTX_PREPARE,

^ permalink raw reply

* [PATCH] ARM64: zynqmp: Fix i2c node's compatible string
From: Michal Simek @ 2016-12-22  7:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482385788-7187-1-git-send-email-moritz.fischer@ettus.com>

On 22.12.2016 06:49, Moritz Fischer wrote:
> From: Moritz Fischer <mdf@kernel.org>
> 
> The Zynq Ultrascale MP uses version 1.4 of the Cadence IP core
> which fixes some silicon bugs that needed software workarounds
> in Version 1.0 that was used on Zynq systems.
> 
> Signed-off-by: Moritz Fischer <mdf@kernel.org>
> Cc: Michal Simek <michal.simek@xilinx.com>
> Cc: S?ren Brinkmann <soren.brinkmann@xilinx.com>
> Cc: U-Boot List <u-boot@lists.denx.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> ---
> 
> Hi Michal,
> 
> I think this is a slip up and should be r1p14 for
> Ultrascale ZynqMP. drivers/i2c/i2c-cadence.c already uses this.
> I Cc'd the u-boot list, because the same change would be required there.
> 
> Cheers,
> 
> Moritz
> 
> ---
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 68a90833..a5a5f91 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -175,7 +175,7 @@
>  		};
>  
>  		i2c0: i2c at ff020000 {
> -			compatible = "cdns,i2c-r1p10";
> +			compatible = "cdns,i2c-r1p14";

I was checking this internally and p10 is doing something what p14
doesn't need to do. That's why this should be

compatible = "cdns,i2c-r1p14", "cdns,i2c-r1p10";

The same of course for u-boot where also p14 should be added to the driver.

Thanks,
Michal

^ permalink raw reply

* hi
From: Ellis Andrew @ 2016-12-22  7:20 UTC (permalink / raw)
  To: linux-arm-kernel

Good afternoon 


http://oknaprozivot.cz/wp-content/uploads/eop/thank-you.php?well=q21v8dtggf8r3b





Ellis Andrew

^ permalink raw reply


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