* Re: [PATCH v2 4/6] irqchip/irq-pruss-intc: Add helper functions to configure internal mapping
From: David Lechner @ 2019-08-08 18:31 UTC (permalink / raw)
To: Suman Anna, Marc Zyngier, Thomas Gleixner, Jason Cooper
Cc: devicetree, Grygorii Strashko, Tony Lindgren, Sekhar Nori,
linux-kernel, Andrew F. Davis, Lokesh Vutla, Rob Herring,
Murali Karicheri, linux-omap, linux-arm-kernel, Roger Quadros
In-Reply-To: <124b03b8-f8e7-682b-8767-13a739329da2@lechnology.com>
On 8/8/19 12:09 PM, David Lechner wrote:
>
> Then we can provide a vendor resource hook in the remoteproc driver to handle
> these resources:
>
> static int ti_pru_rproc_handle_rsc(struct rproc *rproc, u32 rsc_type, void *rsc,
> int offset, int avail)
> {
> struct ti_pru_data *pru = rproc->priv;
> struct irq_fwspec fwspec;
> unsigned int virq;
>
> switch (rsc_type) {
> case TI_PRU_VENDOR_RESOURCE_IRQ:
> {
> struct ti_pru_vendor_resource_irq *rsc_irq = rsc;
>
> fwspec.fwnode = pru->intc_fwnode;
> fwspec.param[0] = le32_to_cpu(rsc_irq->event);
> fwspec.param[1] = le32_to_cpu(rsc_irq->channel);
> fwspec.param[2] = le32_to_cpu(rsc_irq->host);
> fwspec.param[3] = le32_to_cpu(rsc_irq->domain);
> fwspec.param_count = 4;
> }
> break;
> case TI_PRU_VENDOR_RESOURCE_IRQ2:
> {
> struct ti_pru_vendor_resource_irq2 *rsc_irq2 = rsc;
>
> fwspec.fwnode = pru->intc_fwnode;
> fwspec.param[0] = le32_to_cpu(rsc_irq2->event);
> fwspec.param[1] = le32_to_cpu(rsc_irq2->evt_sel);
> fwspec.param[2] = le32_to_cpu(rsc_irq2->channel);
> fwspec.param[3] = le32_to_cpu(rsc_irq2->host);
> fwspec.param[4] = le32_to_cpu(rsc_irq2->domain);
> fwspec.param_count = 5;
> break;
> }
> default:
> return RSC_IGNORED;
> }
>
> virq = irq_create_fwspec_mapping(&fwspec);
> if (!virq)
> return -EINVAL;
>
> /* TODO: save virq (and other metadata) for later use */
>
> return RSC_HANDLED;
> }
>
> static const struct rproc_ops ti_pru_rproc_ops = {
> .start = ti_pru_rproc_start,
> .stop = ti_pru_rproc_stop,
> .kick = ti_pru_rproc_kick,
> .da_to_va = ti_pru_rproc_da_to_va,
> .handle_rsc = ti_pru_rproc_handle_rsc,
> };
>
After re-reading some of the previous discussions, it sounds like
we wouldn't want to always map every IRQ in the firmware resource
table.
In that case, we could implement the rproc_ops parse_fw callback
instead. All firmware nodes could be collected (from both the
firmware resource table and device tree) and the remoteproc driver
could decide which ones need to be mapped and which ones don't.
Then it could call irq_create_fwspec_mapping() only the nodes
that need to be mapped based on the current application.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: next/master build: 230 builds: 5 failed, 225 passed, 6 errors, 1344 warnings (next-20190805)
From: Guenter Roeck @ 2019-08-08 18:41 UTC (permalink / raw)
To: Mark Brown
Cc: linux-arm-kernel, David Zhou, kernel-build-reports, David Airlie,
Tao Zhou, amd-gfx, linux-next, dri-devel, Daniel Vetter,
Alex Deucher, Christian König, Dennis Li
In-Reply-To: <20190805111205.GB6432@sirena.org.uk>
On Mon, Aug 05, 2019 at 12:12:05PM +0100, Mark Brown wrote:
> On Mon, Aug 05, 2019 at 02:40:32AM -0700, kernelci.org bot wrote:
>
> Today's -next fails to build an arm allmodconfig due to:
>
> > allmodconfig (arm, gcc-8) — FAIL, 2 errors, 16 warnings, 0 section mismatches
> >
> > Errors:
> > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:279:9: error: implicit declaration of function 'readq'; did you mean 'readb'? [-Werror=implicit-function-declaration]
> > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:298:3: error: implicit declaration of function 'writeq'; did you mean 'writeb'? [-Werror=implicit-function-declaration]
>
> due to 4fa1c6a679bb0 (drm/amdgpu: add RREG64/WREG64(_PCIE) operations)
> which introduces use of readq() and writeq().
AFAICS this problem affects all 32-bit builds, including i386.
Is it in the process of being fixed, or should we submit a
patch limiting DRM_AMDGPU to 64-bit builds ?
Guenter
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v1 0/8] arm64: MMU enabled kexec relocation
From: Pavel Tatashin @ 2019-08-08 18:44 UTC (permalink / raw)
To: Pavel Tatashin, James Morris, Sasha Levin, Eric W. Biederman,
kexec mailing list, LKML, Jonathan Corbet, Catalin Marinas, will,
Linux ARM, Marc Zyngier, James Morse, Vladimir Murzin,
Matthias Brugger, Bhupesh Sharma, linux-mm
In-Reply-To: <20190801152439.11363-1-pasha.tatashin@soleen.com>
Just a friendly reminder, please send your comments on this series.
It's been a week since I sent out these patches, and no feedback yet.
Also, I'd appreciate if anyone could test this series on vhe hardware
with vhe kernel, it does not look like QEMU can emulate it yet
Thank you,
Pasha
On Thu, Aug 1, 2019 at 11:24 AM Pavel Tatashin
<pasha.tatashin@soleen.com> wrote:
>
> Enable MMU during kexec relocation in order to improve reboot performance.
>
> If kexec functionality is used for a fast system update, with a minimal
> downtime, the relocation of kernel + initramfs takes a significant portion
> of reboot.
>
> The reason for slow relocation is because it is done without MMU, and thus
> not benefiting from D-Cache.
>
> Performance data
> ----------------
> For this experiment, the size of kernel plus initramfs is small, only 25M.
> If initramfs was larger, than the improvements would be greater, as time
> spent in relocation is proportional to the size of relocation.
>
> Previously:
> kernel shutdown 0.022131328s
> relocation 0.440510736s
> kernel startup 0.294706768s
>
> Relocation was taking: 58.2% of reboot time
>
> Now:
> kernel shutdown 0.032066576s
> relocation 0.022158152s
> kernel startup 0.296055880s
>
> Now: Relocation takes 6.3% of reboot time
>
> Total reboot is x2.16 times faster.
>
> Previous approaches and discussions
> -----------------------------------
> https://lore.kernel.org/lkml/20190709182014.16052-1-pasha.tatashin@soleen.com
> reserve space for kexec to avoid relocation, involves changes to generic code
> to optimize a problem that exists on arm64 only:
>
> https://lore.kernel.org/lkml/20190716165641.6990-1-pasha.tatashin@soleen.com
> The first attempt to enable MMU, some bugs that prevented performance
> improvement. The page tables unnecessary configured idmap for the whole
> physical space.
>
> https://lore.kernel.org/lkml/20190731153857.4045-1-pasha.tatashin@soleen.com
> No linear copy, bug with EL2 reboots.
>
> Pavel Tatashin (8):
> kexec: quiet down kexec reboot
> arm64, mm: transitional tables
> arm64: hibernate: switch to transtional page tables.
> kexec: add machine_kexec_post_load()
> arm64, kexec: move relocation function setup and clean up
> arm64, kexec: add expandable argument to relocation function
> arm64, kexec: configure transitional page table for kexec
> arm64, kexec: enable MMU during kexec relocation
>
> arch/arm64/Kconfig | 4 +
> arch/arm64/include/asm/kexec.h | 51 ++++-
> arch/arm64/include/asm/pgtable-hwdef.h | 1 +
> arch/arm64/include/asm/trans_table.h | 68 ++++++
> arch/arm64/kernel/asm-offsets.c | 14 ++
> arch/arm64/kernel/cpu-reset.S | 4 +-
> arch/arm64/kernel/cpu-reset.h | 8 +-
> arch/arm64/kernel/hibernate.c | 261 ++++++-----------------
> arch/arm64/kernel/machine_kexec.c | 199 ++++++++++++++----
> arch/arm64/kernel/relocate_kernel.S | 196 +++++++++---------
> arch/arm64/mm/Makefile | 1 +
> arch/arm64/mm/trans_table.c | 273 +++++++++++++++++++++++++
> kernel/kexec.c | 4 +
> kernel/kexec_core.c | 8 +-
> kernel/kexec_file.c | 4 +
> kernel/kexec_internal.h | 2 +
> 16 files changed, 758 insertions(+), 340 deletions(-)
> create mode 100644 arch/arm64/include/asm/trans_table.h
> create mode 100644 arch/arm64/mm/trans_table.c
>
> --
> 2.22.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: next/master build: 230 builds: 5 failed, 225 passed, 6 errors, 1344 warnings (next-20190805)
From: Alex Deucher @ 2019-08-08 18:53 UTC (permalink / raw)
To: Guenter Roeck
Cc: David Zhou, kernel-build-reports, David Airlie,
Maling list - DRI developers, Tao Zhou, amd-gfx list, Dennis Li,
Mark Brown, Linux-Next Mailing List, Daniel Vetter, Alex Deucher,
Christian König, linux-arm-kernel
In-Reply-To: <20190808184149.GA441@roeck-us.net>
On Thu, Aug 8, 2019 at 2:53 PM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Mon, Aug 05, 2019 at 12:12:05PM +0100, Mark Brown wrote:
> > On Mon, Aug 05, 2019 at 02:40:32AM -0700, kernelci.org bot wrote:
> >
> > Today's -next fails to build an arm allmodconfig due to:
> >
> > > allmodconfig (arm, gcc-8) — FAIL, 2 errors, 16 warnings, 0 section mismatches
> > >
> > > Errors:
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:279:9: error: implicit declaration of function 'readq'; did you mean 'readb'? [-Werror=implicit-function-declaration]
> > > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:298:3: error: implicit declaration of function 'writeq'; did you mean 'writeb'? [-Werror=implicit-function-declaration]
> >
> > due to 4fa1c6a679bb0 (drm/amdgpu: add RREG64/WREG64(_PCIE) operations)
> > which introduces use of readq() and writeq().
>
> AFAICS this problem affects all 32-bit builds, including i386.
> Is it in the process of being fixed, or should we submit a
> patch limiting DRM_AMDGPU to 64-bit builds ?
Yes, the fix is being discussed here:
https://patchwork.freedesktop.org/patch/322213/
Alex
>
> Guenter
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] soc: xilinx: Set CAP_UNUSABLE requirement for versal while powering down domain
From: Jolly Shah @ 2019-08-08 19:00 UTC (permalink / raw)
To: matthias.bgg, andy.gross, shawnguo, geert+renesas,
bjorn.andersson, sean.wang, m.szyprowski, michal.simek
Cc: Tejas Patel, Jolly Shah, rajanv, linux-kernel, linux-arm-kernel
From: Tejas Patel <tejas.patel@xilinx.com>
For "0" requirement which is used to inform firmware that
device is not required currently by master, Versal LibPM disables
clock, power it down and reset the device. genpd_power_off()
is being called during runtime suspend also. So, if any device
goes to runtime suspend state during resumes it needs to be
re-initialized again. It is possible that drivers do not
reinitialize device upon resume from runtime suspend every time.
In LibPM new PM_CAP_UNUSABLE capability is added, which disables
clock only and avoids power down and reset.
So, set CAPABILITY_UNUSABLE requirement during zynqmp_gpd_power_off()
if platform is other than zynqmp.
Signed-off-by: Tejas Patel <tejas.patel@xilinx.com>
Signed-off-by: Jolly Shah <jollys@xilinx.com>
---
drivers/soc/xilinx/zynqmp_pm_domains.c | 10 ++++++++--
include/linux/firmware/xlnx-zynqmp.h | 3 ++-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/xilinx/zynqmp_pm_domains.c b/drivers/soc/xilinx/zynqmp_pm_domains.c
index 600f57c..23d90cb 100644
--- a/drivers/soc/xilinx/zynqmp_pm_domains.c
+++ b/drivers/soc/xilinx/zynqmp_pm_domains.c
@@ -2,7 +2,7 @@
/*
* ZynqMP Generic PM domain support
*
- * Copyright (C) 2015-2018 Xilinx, Inc.
+ * Copyright (C) 2015-2019 Xilinx, Inc.
*
* Davorin Mista <davorin.mista@aggios.com>
* Jolly Shah <jollys@xilinx.com>
@@ -25,6 +25,8 @@
static const struct zynqmp_eemi_ops *eemi_ops;
+static int min_capability;
+
/**
* struct zynqmp_pm_domain - Wrapper around struct generic_pm_domain
* @gpd: Generic power domain
@@ -106,7 +108,7 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
int ret;
struct pm_domain_data *pdd, *tmp;
struct zynqmp_pm_domain *pd;
- u32 capabilities = 0;
+ u32 capabilities = min_capability;
bool may_wakeup;
if (!eemi_ops->set_requirement)
@@ -283,6 +285,10 @@ static int zynqmp_gpd_probe(struct platform_device *pdev)
if (!domains)
return -ENOMEM;
+ if (!of_device_is_compatible(dev->parent->of_node,
+ "xlnx,zynqmp-firmware"))
+ min_capability = ZYNQMP_PM_CAPABILITY_UNUSABLE;
+
for (i = 0; i < ZYNQMP_NUM_DOMAINS; i++, pd++) {
pd->node_id = 0;
pd->gpd.name = kasprintf(GFP_KERNEL, "domain%d", i);
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 778abbb..b8a7c22 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -2,7 +2,7 @@
/*
* Xilinx Zynq MPSoC Firmware layer
*
- * Copyright (C) 2014-2018 Xilinx
+ * Copyright (C) 2014-2019 Xilinx
*
* Michal Simek <michal.simek@xilinx.com>
* Davorin Mista <davorin.mista@aggios.com>
@@ -46,6 +46,7 @@
#define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U
#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U
#define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U
+#define ZYNQMP_PM_CAPABILITY_UNUSABLE 0x8U
/*
* Firmware FPGA Manager flags
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] coresight: Serialize enabling/disabling a link device.
From: Yabin Cui @ 2019-08-08 19:17 UTC (permalink / raw)
To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
Cc: Yabin Cui, linux-kernel, linux-arm-kernel
When tracing etm data of multiple threads on multiple cpus through perf
interface, some link devices are shared between paths of different cpus.
It creates race conditions when different cpus wants to enable/disable
the same link device at the same time.
Example 1:
Two cpus want to enable different ports of a coresight funnel, thus
calling the funnel enable operation at the same time. But the funnel
enable operation isn't reentrantable.
Example 2:
For an enabled coresight dynamic replicator with refcnt=1, one cpu wants
to disable it, while another cpu wants to enable it. Ideally we still have
an enabled replicator with refcnt=1 at the end. But in reality the result
is uncertain.
Since coresight devices claim themselves when enabled for self-hosted
usage, the race conditions above usually make the link devices not usable
after many cycles.
To fix the race conditions, this patch adds a spinlock to serialize
enabling/disabling a link device.
Signed-off-by: Yabin Cui <yabinc@google.com>
---
drivers/hwtracing/coresight/coresight.c | 8 ++++++++
include/linux/coresight.h | 3 +++
2 files changed, 11 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 55db77f6410b..90f97f4f99b2 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -256,6 +256,7 @@ static int coresight_enable_link(struct coresight_device *csdev,
int ret;
int link_subtype;
int refport, inport, outport;
+ unsigned long flags;
if (!parent || !child)
return -EINVAL;
@@ -274,15 +275,18 @@ static int coresight_enable_link(struct coresight_device *csdev,
if (refport < 0)
return refport;
+ spin_lock_irqsave(&csdev->spinlock, flags);
if (atomic_inc_return(&csdev->refcnt[refport]) == 1) {
if (link_ops(csdev)->enable) {
ret = link_ops(csdev)->enable(csdev, inport, outport);
if (ret) {
atomic_dec(&csdev->refcnt[refport]);
+ spin_unlock_irqrestore(&csdev->spinlock, flags);
return ret;
}
}
}
+ spin_unlock_irqrestore(&csdev->spinlock, flags);
csdev->enable = true;
@@ -296,6 +300,7 @@ static void coresight_disable_link(struct coresight_device *csdev,
int i, nr_conns;
int link_subtype;
int refport, inport, outport;
+ unsigned long flags;
if (!parent || !child)
return;
@@ -315,10 +320,12 @@ static void coresight_disable_link(struct coresight_device *csdev,
nr_conns = 1;
}
+ spin_lock_irqsave(&csdev->spinlock, flags);
if (atomic_dec_return(&csdev->refcnt[refport]) == 0) {
if (link_ops(csdev)->disable)
link_ops(csdev)->disable(csdev, inport, outport);
}
+ spin_unlock_irqrestore(&csdev->spinlock, flags);
for (i = 0; i < nr_conns; i++)
if (atomic_read(&csdev->refcnt[i]) != 0)
@@ -1225,6 +1232,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
csdev->subtype = desc->subtype;
csdev->ops = desc->ops;
csdev->orphan = false;
+ spin_lock_init(&csdev->spinlock);
csdev->dev.type = &coresight_dev_type[desc->type];
csdev->dev.groups = desc->groups;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index a2b68823717b..dd28d9ab841d 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/perf_event.h>
#include <linux/sched.h>
+#include <linux/spinlock.h>
/* Peripheral id registers (0xFD0-0xFEC) */
#define CORESIGHT_PERIPHIDR4 0xfd0
@@ -153,6 +154,7 @@ struct coresight_connection {
* activated but not yet enabled. Enabling for a _sink_
* appens when a source has been selected for that it.
* @ea: Device attribute for sink representation under PMU directory.
+ * @spinlock: Serialize enabling/disabling this device.
*/
struct coresight_device {
struct coresight_platform_data *pdata;
@@ -166,6 +168,7 @@ struct coresight_device {
/* sink specific fields */
bool activated; /* true only if a sink is part of a path */
struct dev_ext_attribute *ea;
+ spinlock_t spinlock;
};
/*
--
2.22.0.770.g0f2c4a37fd-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: next/master build: 230 builds: 5 failed, 225 passed, 6 errors, 1344 warnings (next-20190805)
From: Guenter Roeck @ 2019-08-08 19:20 UTC (permalink / raw)
To: Alex Deucher
Cc: David Zhou, kernel-build-reports, David Airlie,
Maling list - DRI developers, Tao Zhou, amd-gfx list, Dennis Li,
Mark Brown, Linux-Next Mailing List, Daniel Vetter, Alex Deucher,
Christian König, linux-arm-kernel
In-Reply-To: <CADnq5_NL6+AohC-3HJa+84k50ewqYLMy_VuFmgY=aw872JFf-A@mail.gmail.com>
On 8/8/19 11:53 AM, Alex Deucher wrote:
> On Thu, Aug 8, 2019 at 2:53 PM Guenter Roeck <linux@roeck-us.net> wrote:
>>
>> On Mon, Aug 05, 2019 at 12:12:05PM +0100, Mark Brown wrote:
>>> On Mon, Aug 05, 2019 at 02:40:32AM -0700, kernelci.org bot wrote:
>>>
>>> Today's -next fails to build an arm allmodconfig due to:
>>>
>>>> allmodconfig (arm, gcc-8) — FAIL, 2 errors, 16 warnings, 0 section mismatches
>>>>
>>>> Errors:
>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:279:9: error: implicit declaration of function 'readq'; did you mean 'readb'? [-Werror=implicit-function-declaration]
>>>> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:298:3: error: implicit declaration of function 'writeq'; did you mean 'writeb'? [-Werror=implicit-function-declaration]
>>>
>>> due to 4fa1c6a679bb0 (drm/amdgpu: add RREG64/WREG64(_PCIE) operations)
>>> which introduces use of readq() and writeq().
>>
>> AFAICS this problem affects all 32-bit builds, including i386.
>> Is it in the process of being fixed, or should we submit a
>> patch limiting DRM_AMDGPU to 64-bit builds ?
>
> Yes, the fix is being discussed here:
> https://patchwork.freedesktop.org/patch/322213/
>
Please note that this does fail for i386 (32-bit x86) builds, contrary to the information
in that discussion. Also, from looking into the kernel, I only see readq/writeq defined
for arch/x86 in 64-bit mode; see arch/x86/include/asm/io.h.
Guenter
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: drm/amdgpu: replace readq/writeq with atomic64 operations
From: Guenter Roeck @ 2019-08-08 19:25 UTC (permalink / raw)
To: Tao Zhou
Cc: linux-arm-kernel, kernel-build-reports, amd-gfx, broonie,
linux-next, alexander.deucher, akpm, christian.koenig, dennis.li,
hawking.zhang
In-Reply-To: <20190807025640.682-1-tao.zhou1@amd.com>
On Wed, Aug 07, 2019 at 10:56:40AM +0800, Tao Zhou wrote:
> readq/writeq are not supported on all architectures
>
> Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Regarding the claim that this would work for 32-bit x86 builds:
make ARCH=i386 allmodconfig
make ARCH=i386 drivers/gpu/drm/amd/amdgpu/amdgpu_device.o
results in:
...
CC [M] drivers/gpu/drm/amd/amdgpu/amdgpu_device.o
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c: In function ‘amdgpu_mm_rreg64’:
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:279:9: error: implicit declaration of function ‘readq’;
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c: In function ‘amdgpu_mm_wreg64’:
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:298:3: error: implicit declaration of function ‘writeq’
This is with next-20190808.
Guenter
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] coresight: tmc-etr: Remove perf_data check.
From: Yabin Cui @ 2019-08-08 19:31 UTC (permalink / raw)
To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
Cc: Yabin Cui, linux-kernel, linux-arm-kernel
When tracing etm data of multiple threads on multiple cpus through
perf interface, each cpu has a unique etr_perf_buffer while sharing
the same etr device. There is no guarantee that the last cpu starts
etm tracing also stops last. So the perf_data check is no longer valid.
Signed-off-by: Yabin Cui <yabinc@google.com>
---
drivers/hwtracing/coresight/coresight-tmc-etr.c | 9 ---------
drivers/hwtracing/coresight/coresight-tmc.h | 2 --
2 files changed, 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 17006705287a..0418440e0141 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1484,20 +1484,12 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
goto out;
}
- if (WARN_ON(drvdata->perf_data != etr_perf)) {
- lost = true;
- spin_unlock_irqrestore(&drvdata->spinlock, flags);
- goto out;
- }
-
CS_UNLOCK(drvdata->base);
tmc_flush_and_stop(drvdata);
tmc_sync_etr_buf(drvdata);
CS_LOCK(drvdata->base);
- /* Reset perf specific data */
- drvdata->perf_data = NULL;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
size = etr_buf->len;
@@ -1556,7 +1548,6 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
}
etr_perf->head = PERF_IDX2OFF(handle->head, etr_perf);
- drvdata->perf_data = etr_perf;
/*
* No HW configuration is needed if the sink is already in
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 1ed50411cc3c..3881a9ee565a 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -178,7 +178,6 @@ struct etr_buf {
* device configuration register (DEVID)
* @idr: Holds etr_bufs allocated for this ETR.
* @idr_mutex: Access serialisation for idr.
- * @perf_data: PERF buffer for ETR.
* @sysfs_data: SYSFS buffer for ETR.
*/
struct tmc_drvdata {
@@ -202,7 +201,6 @@ struct tmc_drvdata {
struct idr idr;
struct mutex idr_mutex;
struct etr_buf *sysfs_buf;
- void *perf_data;
};
struct etr_buf_operations {
--
2.22.0.770.g0f2c4a37fd-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: drm/amdgpu: replace readq/writeq with atomic64 operations
From: Alex Deucher @ 2019-08-08 19:33 UTC (permalink / raw)
To: Guenter Roeck
Cc: kernel-build-reports, Mark Brown, Tao Zhou, amd-gfx list,
Linux-Next Mailing List, Dennis Li, Deucher, Alexander,
Andrew Morton, Christian Koenig, linux-arm-kernel, Hawking Zhang
In-Reply-To: <20190808192535.GA18697@roeck-us.net>
On Thu, Aug 8, 2019 at 3:31 PM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Wed, Aug 07, 2019 at 10:56:40AM +0800, Tao Zhou wrote:
> > readq/writeq are not supported on all architectures
> >
> > Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
> > Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
>
> Regarding the claim that this would work for 32-bit x86 builds:
I wasn't talking about readq/writeq, I was talking about the atomic64
interfaces.
Alex
>
> make ARCH=i386 allmodconfig
> make ARCH=i386 drivers/gpu/drm/amd/amdgpu/amdgpu_device.o
>
> results in:
>
> ...
> CC [M] drivers/gpu/drm/amd/amdgpu/amdgpu_device.o
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c: In function ‘amdgpu_mm_rreg64’:
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:279:9: error: implicit declaration of function ‘readq’;
>
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c: In function ‘amdgpu_mm_wreg64’:
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:298:3: error: implicit declaration of function ‘writeq’
>
> This is with next-20190808.
>
> Guenter
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 1/2] clk: Add clk_min/max_rate entries in debugfs
From: Stephen Boyd @ 2019-08-08 19:46 UTC (permalink / raw)
To: Geert Uytterhoeven, Leonard Crestez
Cc: Michael Turquette, linux-clk@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <VI1PR04MB7023C8A78321E34492290E56EED70@VI1PR04MB7023.eurprd04.prod.outlook.com>
Quoting Leonard Crestez (2019-08-08 09:46:48)
> On 8/8/2019 6:00 PM, Stephen Boyd wrote:
> > Quoting Leonard Crestez (2019-07-02 06:27:09)
> >> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
>
> >> static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
> >> {
> >> + clk_core_get_boundaries(c, &min_rate, &max_rate);
> >> + if (min_rate != 0)
> >> + seq_printf(s, "\"min_rate\": %lu,", min_rate);
> >> + if (max_rate != ULONG_MAX)
> >> + seq_printf(s, "\"max_rate\": %lu,", max_rate);
> >
> > What are the if conditions about? We always output the values in the
> > individual files, but for some reason we don't want to do that in the
> > json output?
>
> These if conditions are an easy way to avoid spamming "min_rate": 0,
> "max_rate": 18446744073709551615 in json. If you object to the
> inconsistency a nice solution would to be show "null" in both debugfs
> and json.
Aren't those the min and max values though? I don't see it as spam, it's
just more data that is the "default". Given that json is for machine
parsing maybe the parser of this can ignore them if it wants to when the
values match 0 and ULONG_MAX?
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 2/6] thermal: amlogic: Add thermal driver to support G12 SoCs
From: Martin Blumenstingl @ 2019-08-08 19:47 UTC (permalink / raw)
To: Kevin Hilman
Cc: devicetree, linux-pm, daniel.lezcano, linux-kernel,
guillaume La Roque, linux-amlogic, linux-arm-kernel
In-Reply-To: <7hblx0fjkw.fsf@baylibre.com>
Hi Kevin,
On Thu, Aug 8, 2019 at 4:59 AM Kevin Hilman <khilman@baylibre.com> wrote:
>
> Martin Blumenstingl <martin.blumenstingl@googlemail.com> writes:
>
> > Hi Guillaume,
> >
> > On Mon, Aug 5, 2019 at 2:48 PM guillaume La Roque <glaroque@baylibre.com> wrote:
> >>
> >> Hi Martin,
> >>
> >> again thanks for your review.
> > you're welcome - thank you for working on the driver :-)
> >
> > [...]
> >> > The IP block has more functionality, which may be added to this driver
> >> > in the future:
> >> > - reading up to 16 stored temperature samples
> >>
> >> it's not working, you can verify it if you check the regmap define in the driver. in fact temp is only write in one register, it's confirmed by amlogic.
> > I missed that - so please skip this part
> >
> > [...]
> >> >> +config AMLOGIC_THERMAL
> >> > we typically use "MESON" in the Kconfig symbols:
> >> > $ grep -c AMLOGIC .config
> >> > 1
> >> > $ grep -c MESON .config
> >> > 33
> >> >
> >> > I also wonder if we should add G12 or G12A so we don't conflict with
> >> > upcoming thermal sensors with a different design (assuming that this
> >> > will be a thing).
> >> > for example we already have three different USB2 PHY drivers
> >> >
> >> > [...]
> >>
> >> i check with Neil and for new family it's better to use Amlogic instead of meson.
> > can you please share the considerations behind this decision?
> > if new drivers should use AMLOGIC_* Kconfig symbols instead of MESON_*
> > then we all should know about it
> >
> >> i don't add G12 because we already know it's same sensors for SM1 SoC family [0].
> > my idea behind this was to avoid conflicts in the future
> > in case of the thermal driver we may be fine with using a generic name
> > assuming that Amlogic will not switch to a new IP block in the next
> > years
> > I'm not saying you have to change the name - I'm bringing this up so
> > you can decide for yourself based on examples from the past
> >
> > here are a few examples:
> > - when Kevin upstreamed the MMC driver for GX he decided to use
> > MMC_MESON_GX for the Kconfig symbol name. it turns out that this is
> > smart because there are at least two other MMC controller IPs on the
> > 32-bit SoCs. due to him including GX in the name the drivers are easy
> > to differentiate (MMC_MESON_MX_SDIO and MMC_MESON_MX_SDHC being the
> > other ones, while the latter is not upstream yet)
> > - when Carlo upstreamed the eFuse driver he decided to use MESON_EFUSE
> > for the Kconfig symbol name. I found out much later that the 32-bit
> > SoCs use a different IP (or at least direct register access instead of
> > going through Secure Monitor). the driver for the 32-bit SoCs now uses
> > MESON_MX_EFUSE. if you don't know which driver applies where then it's
> > easy to mix up MESON_EFUSE and MESON_MX_EFUSE
> > - when Jerome upstreamed the ALSA driver for AXG (which is also used
> > on G12A and G12B) he decided to use the SND_MESON_AXG_* prefix for the
> > Kconfig symbol names. in my opinion this was a good choice because GXM
> > and everything earlier (including the 32-bit SoCs) use a different
> > audio IP block. we won't have a Kconfig symbol name clash when a
> > driver for the "older" SoCs is upstreamed
> > - (there are more examples, Meson8b USB PHY driver, Meson8b DWMAC
> > glue, ... - just like there's many examples where the IP block is
> > mostly compatible with older generations: SAR ADC, RNG, SPI, ...)
>
> While these are all good examples, you can see it can go both ways, so
> there's really no way know up front what is the "right" way. We only
> know after the fact. Unfortunately, we simply have no visibility into
> future chips and where IP blocks may be shared or not (there are other
> examples where vendors add a new version of an IP *and* keep the old
> version. ;)
>
> Even having worked inside a (different) SoC vendor and having some
> knowledge about what IPs are shared, it's difficult to get this right.
right. The fact that it'll be the IP block in SM1 will be backwards
compatible (or even the same) means that it has a longer life-span
than some of the USB PHY IP.
so I'm fine either way
Martin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] clk: fix devm_platform_ioremap_resource.cocci warnings
From: Stephen Boyd @ 2019-08-08 19:48 UTC (permalink / raw)
To: Jonas Gorski, Julia Lawall
Cc: Florian Fainelli, Michael Turquette, Philippe Mathieu-Daud??,
linux-kernel, bcm-kernel-feedback-list, kbuild-all, linux-clk,
linux-arm-kernel
In-Reply-To: <alpine.DEB.2.21.1908081809160.2995@hadrien>
Quoting Julia Lawall (2019-08-08 09:10:53)
> From: kbuild test robot <lkp@intel.com>
>
> drivers/clk/bcm/clk-bcm63xx-gate.c:174:1-9: WARNING: Use devm_platform_ioremap_resource for hw -> regs
>
> Use devm_platform_ioremap_resource helper which wraps
> platform_get_resource() and devm_ioremap_resource() together.
>
> Generated by: scripts/coccinelle/api/devm_platform_ioremap_resource.cocci
>
> Fixes: 1c099779c1e2 ("clk: add BCM63XX gated clock controller driver")
Is it fixing anything? As far as I can tell it's reducing lines of code
with another function.
> CC: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: kbuild test robot <lkp@intel.com>
> Signed-off-by: Julia Lawall <julia.lawall@lip6.fr>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 7/9] dt-bindings: phy: meson-g12a-usb3-pcie-phy: convert to yaml
From: Martin Blumenstingl @ 2019-08-08 19:50 UTC (permalink / raw)
To: Neil Armstrong
Cc: devicetree, Rob Herring, kishon, robh+dt, linux-amlogic,
linux-arm-kernel
In-Reply-To: <20190808085139.21438-8-narmstrong@baylibre.com>
On Thu, Aug 8, 2019 at 10:54 AM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Amlogic G12A USB3 + PCIE Combo PHY over to a YAML schemas.
>
> While the original phy bindings specifies phy-supply as required,
> the examples and implementations makes it optional, thus phy-supply
> is not present in the properties and required lists.
nit-pick: the original bindings didn't mention the phy-supply property at all
I'm not sure if you have to re-send it, maybe this can be fixed up
while applying?
> Reviewed-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] clk: fix devm_platform_ioremap_resource.cocci warnings
From: Julia Lawall @ 2019-08-08 19:51 UTC (permalink / raw)
To: Stephen Boyd
Cc: Florian Fainelli, Michael Turquette, linux-kernel,
Philippe Mathieu-Daud??, bcm-kernel-feedback-list, kbuild-all,
Jonas Gorski, linux-clk, linux-arm-kernel
In-Reply-To: <20190808194821.825AD21743@mail.kernel.org>
On Thu, 8 Aug 2019, Stephen Boyd wrote:
> Quoting Julia Lawall (2019-08-08 09:10:53)
> > From: kbuild test robot <lkp@intel.com>
> >
> > drivers/clk/bcm/clk-bcm63xx-gate.c:174:1-9: WARNING: Use devm_platform_ioremap_resource for hw -> regs
> >
> > Use devm_platform_ioremap_resource helper which wraps
> > platform_get_resource() and devm_ioremap_resource() together.
> >
> > Generated by: scripts/coccinelle/api/devm_platform_ioremap_resource.cocci
> >
> > Fixes: 1c099779c1e2 ("clk: add BCM63XX gated clock controller driver")
>
> Is it fixing anything? As far as I can tell it's reducing lines of code
> with another function.
No, it doesn't fix anything.
julia
>
> > CC: Jonas Gorski <jonas.gorski@gmail.com>
> > Signed-off-by: kbuild test robot <lkp@intel.com>
> > Signed-off-by: Julia Lawall <julia.lawall@lip6.fr>
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] arm64: dts: allwinner: a64: Drop PMU node
From: Vasily Khoruzhick @ 2019-08-08 19:59 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mark Rutland, devicetree, Jared D . McNeill, Chen-Yu Tsai,
Rob Herring, Harald Geyer, Robin Murphy, arm-linux
In-Reply-To: <20190808162628.pthvy3tgf3naj76s@flea>
On Thu, Aug 8, 2019 at 9:26 AM Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> On Wed, Aug 07, 2019 at 10:36:08AM -0700, Vasily Khoruzhick wrote:
> > On Wed, Aug 7, 2019 at 4:56 AM Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> > >
> > > On Tue, Aug 06, 2019 at 07:39:26PM -0700, Vasily Khoruzhick wrote:
> > > > On Tue, Aug 6, 2019 at 2:14 PM Robin Murphy <robin.murphy@arm.com> wrote:
> > > > >
> > > > > On 2019-08-06 9:52 pm, Vasily Khoruzhick wrote:
> > > > > > On Tue, Aug 6, 2019 at 1:19 PM Harald Geyer <harald@ccbib.org> wrote:
> > > > > >>
> > > > > >> Vasily Khoruzhick writes:
> > > > > >>> On Tue, Aug 6, 2019 at 7:35 AM Robin Murphy <robin.murphy@arm.com> wrote:
> > > > > >>>>
> > > > > >>>> On 06/08/2019 15:01, Vasily Khoruzhick wrote:
> > > > > >>>>> Looks like PMU in A64 is broken, it generates no interrupts at all and
> > > > > >>>>> as result 'perf top' shows no events.
> > > > > >>>>
> > > > > >>>> Does something like 'perf stat sleep 1' at least count cycles correctly?
> > > > > >>>> It could well just be that the interrupt numbers are wrong...
> > > > > >>>
> > > > > >>> Looks like it does, at least result looks plausible:
> > > > > >>
> > > > > >> I'm using perf stat regularly (cache benchmarks) and it works fine.
> > > > > >>
> > > > > >> Unfortunately I wasn't aware that perf stat is a poor test for
> > > > > >> the interrupts part of the node, when I added it. So I'm not too
> > > > > >> surprised I got it wrong.
> > > > > >>
> > > > > >> However, it would be unfortunate if the node got removed completely,
> > > > > >> because perf stat would not work anymore. Maybe we can only remove
> > > > > >> the interrupts or just fix them even if the HW doesn't work?
> > > > > >
> > > > > > I'm not familiar with PMU driver. Is it possible to get it working
> > > > > > without interrupts?
> > > > >
> > > > > Yup - you get a grumpy message from the driver, it will refuse sampling
> > > > > events (the ones which weren't working anyway), and if you measure
> > > > > anything for long enough that a counter overflows you'll get wonky
> > > > > results. But for counting hardware events over relatively short periods
> > > > > it'll still do the job.
> > > >
> > > > I tried to drop interrupts completely from the node but 'perf top' is
> > > > still broken. Though now in different way: it complains "cycles: PMU
> > > > Hardware doesn't support sampling/overflow-interrupts. Try 'perf
> > > > stat'"
> > >
> > > I have no idea if that's the culprit, but what is the state of the
> > > 0x09010000 register?
> >
> > What register is that and how do I check it?
>
> It's in the CPUX Configuration block, and the bits are labelled as CPU
> Debug Reset.
>
> And if you have busybox, you can use devmem.
CPUX configuration block is at 0x01700000 according to A64 user
manual, and particular register you're interested in is at 0x01700080,
its value is 0x1110110F.
Bits 16-19 are not defined in user manual and are not set.
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: i2c: imx: support slave mode for imx I2C driver
From: Wolfram Sang @ 2019-08-08 20:02 UTC (permalink / raw)
To: Biwen Li, Joshua Frkuska
Cc: shawnguo, s.hauer, linux-kernel, linux-imx, kernel,
laurentiu.tudor, festevam, linux-arm-kernel, linux-i2c
In-Reply-To: <20190808035343.34120-1-biwen.li@nxp.com>
[-- Attachment #1.1: Type: text/plain, Size: 7905 bytes --]
On Thu, Aug 08, 2019 at 11:53:43AM +0800, Biwen Li wrote:
> The patch supports slave mode for imx I2C driver
>
> Signed-off-by: Biwen Li <biwen.li@nxp.com>
Wow, this is much simpler than the other approach flying around:
http://patchwork.ozlabs.org/patch/1124048/
Can this one be master and slave on the same bus, too?
CCing the author of the other patch.
> ---
> drivers/i2c/busses/i2c-imx.c | 199 ++++++++++++++++++++++++++++++++---
> 1 file changed, 185 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index b1b8b938d7f4..f7583a9fa56f 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -202,6 +202,9 @@ struct imx_i2c_struct {
> struct pinctrl_state *pinctrl_pins_gpio;
>
> struct imx_i2c_dma *dma;
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> + struct i2c_client *slave;
> +#endif /* CONFIG_I2C_SLAVE */
> };
>
> static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
> @@ -583,23 +586,40 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
> imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> }
>
> -static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> +/* Clear interrupt flag bit */
> +static void i2c_imx_clr_if_bit(struct imx_i2c_struct *i2c_imx)
> {
> - struct imx_i2c_struct *i2c_imx = dev_id;
> - unsigned int temp;
> + unsigned int status;
>
> - temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> - if (temp & I2SR_IIF) {
> - /* save status register */
> - i2c_imx->i2csr = temp;
> - temp &= ~I2SR_IIF;
> - temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
> - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> - wake_up(&i2c_imx->queue);
> - return IRQ_HANDLED;
> - }
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + status &= ~I2SR_IIF;
> + status |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
> + imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
> +}
> +
> +/* Clear arbitration lost bit */
> +static void i2c_imx_clr_al_bit(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int status;
> +
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + status &= ~I2SR_IAL;
> + imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
> +}
>
> - return IRQ_NONE;
> +static irqreturn_t i2c_imx_master_isr(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int status;
> +
> + dev_dbg(&i2c_imx->adapter.dev, "<%s>: master interrupt\n", __func__);
> +
> + /* Save status register */
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + i2c_imx->i2csr = status | I2SR_IIF;
> +
> + wake_up(&i2c_imx->queue);
> +
> + return IRQ_HANDLED;
> }
>
> static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
> @@ -1043,11 +1063,162 @@ static u32 i2c_imx_func(struct i2c_adapter *adapter)
> | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
> }
>
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> +static void i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int temp;
> +
> + dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> +
> + /* Set slave addr. */
> + imx_i2c_write_reg((i2c_imx->slave->addr << 1), i2c_imx, IMX_I2C_IADR);
> +
> + /* Disable i2c module */
> + temp = i2c_imx->hwdata->i2cr_ien_opcode
> + ^ I2CR_IEN;
> + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> +
> + /* Reset status register */
> + imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx,
> + IMX_I2C_I2SR);
> +
> + /* Enable module and enable interrupt from i2c module */
> + temp = i2c_imx->hwdata->i2cr_ien_opcode
> + | I2CR_IIEN;
> + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> +
> + /* Wait controller to be stable */
> + usleep_range(50, 150);
> +}
> +
> +static irqreturn_t i2c_imx_slave_isr(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int status, ctl;
> + u8 value;
> +
> + if (!i2c_imx->slave) {
> + dev_err(&i2c_imx->adapter.dev, "cannot deal with slave irq,i2c_imx->slave is null");
> + return IRQ_NONE;
> + }
> +
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + ctl = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
> + if (status & I2SR_IAL) { /* Arbitration lost */
> + i2c_imx_clr_al_bit(i2c_imx);
> + } else if (status & I2SR_IAAS) { /* Addressed as a slave */
> + if (status & I2SR_SRW) { /* Master wants to read from us*/
> + dev_dbg(&i2c_imx->adapter.dev, "read requested");
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_READ_REQUESTED, &value);
> +
> + /* Slave transimt */
> + ctl |= I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> +
> + /* Send data */
> + imx_i2c_write_reg(value, i2c_imx, IMX_I2C_I2DR);
> + } else { /* Master wants to write to us */
> + dev_dbg(&i2c_imx->adapter.dev, "write requested");
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
> +
> + /* Slave receive */
> + ctl &= ~I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> + /* Dummy read */
> + value = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
> + }
> + } else {
> + if (!(ctl & I2CR_MTX)) { /* Receive mode */
> + if (status & I2SR_IBB) { /* No STOP signal detected */
> + ctl &= ~I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> +
> + value = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
> + } else { /* STOP signal is detected */
> + dev_dbg(&i2c_imx->adapter.dev,
> + "STOP signal detected");
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_STOP, &value);
> + }
> + } else { /* Transmit mode */
> + if (!(status & I2SR_RXAK)) { /* Received ACK */
> + ctl |= I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> +
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_READ_PROCESSED, &value);
> +
> + imx_i2c_write_reg(value, i2c_imx, IMX_I2C_I2DR);
> + } else { /* Received NAK */
> + ctl &= ~I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> + value = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
> + }
> + }
> + }
> + return IRQ_HANDLED;
> +}
> +
> +static int i2c_imx_reg_slave(struct i2c_client *client)
> +{
> + struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
> +
> + if (i2c_imx->slave)
> + return -EINVAL;
> +
> + dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> + i2c_imx->slave = client;
> +
> + i2c_imx_slave_init(i2c_imx);
> +
> + return 0;
> +}
> +
> +static int i2c_imx_unreg_slave(struct i2c_client *client)
> +{
> + struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
> +
> + if (!i2c_imx->slave)
> + return -EINVAL;
> +
> + i2c_imx->slave = NULL;
> +
> + return 0;
> +}
> +#endif /* CONFIG_I2C_SLAVE */
> +
> static const struct i2c_algorithm i2c_imx_algo = {
> .master_xfer = i2c_imx_xfer,
> .functionality = i2c_imx_func,
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> + .reg_slave = i2c_imx_reg_slave,
> + .unreg_slave = i2c_imx_unreg_slave,
> +#endif /* CONFIG_I2C_SLAVE */
> };
>
> +static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> +{
> + struct imx_i2c_struct *i2c_imx = dev_id;
> + unsigned int status, ctl;
> + irqreturn_t irq_status = IRQ_NONE;
> +
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + ctl = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
> +
> + if (status & I2SR_IIF) {
> + i2c_imx_clr_if_bit(i2c_imx);
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> + if (ctl & I2CR_MSTA)
> + irq_status = i2c_imx_master_isr(i2c_imx);
> + else
> + irq_status = i2c_imx_slave_isr(i2c_imx);
> +#else
> + irq_status = i2c_imx_master_isr(i2c_imx);
> +
> +#endif /* CONFIG_I2C_SLAVE */
> + }
> +
> + return irq_status;
> +}
> +
> static int i2c_imx_probe(struct platform_device *pdev)
> {
> const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
> --
> 2.17.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2 v2] tracing: Document the stack trace algorithm in the comments
From: Joel Fernandes @ 2019-08-08 20:17 UTC (permalink / raw)
To: Steven Rostedt
Cc: Jiping Ma, catalin.marinas, will.deacon, linux-kernel, mingo,
linux-arm-kernel
In-Reply-To: <20190807172907.310138647@goodmis.org>
On Wed, Aug 07, 2019 at 01:28:28PM -0400, Steven Rostedt wrote:
> From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
>
> As the max stack tracer algorithm is not that easy to understand from the
> code, add comments that explain the algorithm and mentions how
> ARCH_RET_ADDR_AFTER_LOCAL_VARS affects it.
>
> Link: http://lkml.kernel.org/r/20190806123455.487ac02b@gandalf.local.home
>
Acked-by: Joel Fernandes (Google) <joel@joelfernandes.org>
thanks!!
- Joel
> Suggested-by: Joel Fernandes <joel@joelfernandes.org>
> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> ---
> kernel/trace/trace_stack.c | 98 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 98 insertions(+)
>
> diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
> index 40e4a88eea8f..f94a2fc567de 100644
> --- a/kernel/trace/trace_stack.c
> +++ b/kernel/trace/trace_stack.c
> @@ -53,6 +53,104 @@ static void print_max_stack(void)
> }
> }
>
> +/*
> + * The stack tracer looks for a maximum stack at each call from a function. It
> + * registers a callback from ftrace, and in that callback it examines the stack
> + * size. It determines the stack size from the variable passed in, which is the
> + * address of a local variable in the stack_trace_call() callback function.
> + * The stack size is calculated by the address of the local variable to the top
> + * of the current stack. If that size is smaller than the currently saved max
> + * stack size, nothing more is done.
> + *
> + * If the size of the stack is greater than the maximum recorded size, then the
> + * following algorithm takes place.
> + *
> + * For architectures (like x86) that store the function's return address before
> + * saving the function's local variables, the stack will look something like
> + * this:
> + *
> + * [ top of stack ]
> + * 0: sys call entry frame
> + * 10: return addr to entry code
> + * 11: start of sys_foo frame
> + * 20: return addr to sys_foo
> + * 21: start of kernel_func_bar frame
> + * 30: return addr to kernel_func_bar
> + * 31: [ do trace stack here ]
> + *
> + * The save_stack_trace() is called returning all the functions it finds in the
> + * current stack. Which would be (from the bottom of the stack to the top):
> + *
> + * return addr to kernel_func_bar
> + * return addr to sys_foo
> + * return addr to entry code
> + *
> + * Now to figure out how much each of these functions' local variable size is,
> + * a search of the stack is made to find these values. When a match is made, it
> + * is added to the stack_dump_trace[] array. The offset into the stack is saved
> + * in the stack_trace_index[] array. The above example would show:
> + *
> + * stack_dump_trace[] | stack_trace_index[]
> + * ------------------ + -------------------
> + * return addr to kernel_func_bar | 30
> + * return addr to sys_foo | 20
> + * return addr to entry | 10
> + *
> + * The print_max_stack() function above, uses these values to print the size of
> + * each function's portion of the stack.
> + *
> + * for (i = 0; i < nr_entries; i++) {
> + * size = i == nr_entries - 1 ? stack_trace_index[i] :
> + * stack_trace_index[i] - stack_trace_index[i+1]
> + * print "%d %d %d %s\n", i, stack_trace_index[i], size, stack_dump_trace[i]);
> + * }
> + *
> + * The above shows
> + *
> + * depth size location
> + * ----- ---- --------
> + * 0 30 10 kernel_func_bar
> + * 1 20 10 sys_foo
> + * 2 10 10 entry code
> + *
> + * Now for architectures that might save the return address after the functions
> + * local variables (saving the link register before calling nested functions),
> + * this will cause the stack to look a little different:
> + *
> + * [ top of stack ]
> + * 0: sys call entry frame
> + * 10: start of sys_foo_frame
> + * 19: return addr to entry code << lr saved before calling kernel_func_bar
> + * 20: start of kernel_func_bar frame
> + * 29: return addr to sys_foo_frame << lr saved before calling next function
> + * 30: [ do trace stack here ]
> + *
> + * Although the functions returned by save_stack_trace() may be the same, the
> + * placement in the stack will be different. Using the same algorithm as above
> + * would yield:
> + *
> + * stack_dump_trace[] | stack_trace_index[]
> + * ------------------ + -------------------
> + * return addr to kernel_func_bar | 30
> + * return addr to sys_foo | 29
> + * return addr to entry | 19
> + *
> + * Where the mapping is off by one:
> + *
> + * kernel_func_bar stack frame size is 29 - 19 not 30 - 29!
> + *
> + * To fix this, if the architecture sets ARCH_RET_ADDR_AFTER_LOCAL_VARS the
> + * values in stack_trace_index[] are shifted by one to and the number of
> + * stack trace entries is decremented by one.
> + *
> + * stack_dump_trace[] | stack_trace_index[]
> + * ------------------ + -------------------
> + * return addr to kernel_func_bar | 29
> + * return addr to sys_foo | 19
> + *
> + * Although the entry function is not displayed, the first function (sys_foo)
> + * will still include the stack size of it.
> + */
> static void check_stack(unsigned long ip, unsigned long *stack)
> {
> unsigned long this_size, flags; unsigned long *p, *top, *start;
> --
> 2.20.1
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v4 1/2] ACPI/PPTT: Add support for ACPI 6.3 thread flag
From: Jeremy Linton @ 2019-08-08 20:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: lorenzo.pieralisi, rric, catalin.marinas, rjw, Jeremy Linton,
linux-acpi, sudeep.holla, will, lenb
In-Reply-To: <20190808204007.30110-1-jeremy.linton@arm.com>
ACPI 6.3 adds a flag to the CPU node to indicate whether
the given PE is a thread. Add a function to return that
information for a given linux logical CPU.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/acpi/pptt.c | 53 +++++++++++++++++++++++++++++++++++++++++++-
include/linux/acpi.h | 5 +++++
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index 1e7ac0bd0d3a..f31544d3656e 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -540,6 +540,44 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
return retval;
}
+/**
+ * check_acpi_cpu_flag() - Determine if CPU node has a flag set
+ * @cpu: Kernel logical CPU number
+ * @rev: The minimum PPTT revision defining the flag
+ * @flag: The flag itself
+ *
+ * Check the node representing a CPU for a given flag.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found or
+ * the table revision isn't new enough.
+ * 1, any passed flag set
+ * 0, flag unset
+ */
+static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
+{
+ struct acpi_table_header *table;
+ acpi_status status;
+ u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+ struct acpi_pptt_processor *cpu_node = NULL;
+ int ret = -ENOENT;
+
+ status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+ if (ACPI_FAILURE(status)) {
+ acpi_pptt_warn_missing();
+ return ret;
+ }
+
+ if (table->revision >= rev)
+ cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
+
+ if (cpu_node)
+ ret = (cpu_node->flags & flag) != 0;
+
+ acpi_put_table(table);
+
+ return ret;
+}
+
/**
* acpi_find_last_cache_level() - Determines the number of cache levels for a PE
* @cpu: Kernel logical CPU number
@@ -604,6 +642,20 @@ int cache_setup_acpi(unsigned int cpu)
return status;
}
+/**
+ * acpi_pptt_cpu_is_thread() - Determine if CPU is a thread
+ * @cpu: Kernel logical CPU number
+ *
+ * Return: 1, a thread
+ * 0, not a thread
+ * -ENOENT ,if the PPTT doesn't exist, the CPU cannot be found or
+ * the table revision isn't new enough.
+ */
+int acpi_pptt_cpu_is_thread(unsigned int cpu)
+{
+ return check_acpi_cpu_flag(cpu, 2, ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD);
+}
+
/**
* find_acpi_cpu_topology() - Determine a unique topology value for a given CPU
* @cpu: Kernel logical CPU number
@@ -664,7 +716,6 @@ int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
return ret;
}
-
/**
* find_acpi_cpu_topology_package() - Determine a unique CPU package value
* @cpu: Kernel logical CPU number
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9426b9aaed86..9d0e20a2ac83 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1302,11 +1302,16 @@ static inline int lpit_read_residency_count_address(u64 *address)
#endif
#ifdef CONFIG_ACPI_PPTT
+int acpi_pptt_cpu_is_thread(unsigned int cpu);
int find_acpi_cpu_topology(unsigned int cpu, int level);
int find_acpi_cpu_topology_package(unsigned int cpu);
int find_acpi_cpu_topology_hetero_id(unsigned int cpu);
int find_acpi_cpu_cache_topology(unsigned int cpu, int level);
#else
+static inline int acpi_pptt_cpu_is_thread(unsigned int cpu)
+{
+ return -EINVAL;
+}
static inline int find_acpi_cpu_topology(unsigned int cpu, int level)
{
return -EINVAL;
--
2.21.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v4 0/2] arm64/PPTT ACPI 6.3 thread flag support
From: Jeremy Linton @ 2019-08-08 20:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: lorenzo.pieralisi, rric, catalin.marinas, rjw, Jeremy Linton,
linux-acpi, sudeep.holla, will, lenb
ACPI 6.3 adds a flag to the CPU node to indicate whether
the given CPU is a thread. Add a function to return that
information for a given linux logical CPU and then utilize
it while building the arm64 topology.
v4->v5: Add Sudeep's Reviewed tag
Trivial comment tweaks
Move is_threaded logic from parse_acpi_topology()
to apci_cpu_is_threaded()
v3->v4: Remove table revision cache as this code path is only
called during boot and there aren't any
indications that it presents a perf issue.
Rebase to 5.3
v2->v3: Clarify and tweak the return from check_acpi_cpu_flag()
Cache the PPTT table revision to avoid repeat
acpi_table_get/put calls in the case of
missing or old PPTT tables.
v1->v2:
Return ENOENT instead on ENONET.
Jeremy Linton (2):
ACPI/PPTT: Add support for ACPI 6.3 thread flag
arm64: topology: Use PPTT to determine if PE is a thread
arch/arm64/kernel/topology.c | 19 ++++++++++---
drivers/acpi/pptt.c | 53 +++++++++++++++++++++++++++++++++++-
include/linux/acpi.h | 5 ++++
3 files changed, 72 insertions(+), 5 deletions(-)
--
2.21.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v4 2/2] arm64: topology: Use PPTT to determine if PE is a thread
From: Jeremy Linton @ 2019-08-08 20:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: lorenzo.pieralisi, rric, catalin.marinas, rjw, Jeremy Linton,
linux-acpi, sudeep.holla, will, lenb
In-Reply-To: <20190808204007.30110-1-jeremy.linton@arm.com>
ACPI 6.3 adds a thread flag to represent if a CPU/PE is
actually a thread. Given that the MPIDR_MT bit may not
represent this information consistently on homogeneous machines
we should prefer the PPTT flag if its available.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
---
arch/arm64/kernel/topology.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 0825c4a856e3..bad9c42ea825 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -340,17 +340,28 @@ void remove_cpu_topology(unsigned int cpu)
}
#ifdef CONFIG_ACPI
+static int __init acpi_cpu_is_threaded(int cpu)
+{
+ int is_threaded = acpi_pptt_cpu_is_thread(cpu);
+
+ /*
+ * if the PPTT doesn't have thread information, assume a homogeneous
+ * machine and return the current CPU's thread state.
+ */
+ if (is_threaded < 0)
+ is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
+
+ return is_threaded;
+}
+
/*
* Propagate the topology information of the processor_topology_node tree to the
* cpu_topology array.
*/
static int __init parse_acpi_topology(void)
{
- bool is_threaded;
int cpu, topology_id;
- is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
-
for_each_possible_cpu(cpu) {
int i, cache_id;
@@ -358,7 +369,7 @@ static int __init parse_acpi_topology(void)
if (topology_id < 0)
return topology_id;
- if (is_threaded) {
+ if (acpi_cpu_is_threaded(cpu)) {
cpu_topology[cpu].thread_id = topology_id;
topology_id = find_acpi_cpu_topology(cpu, 1);
cpu_topology[cpu].core_id = topology_id;
--
2.21.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] soc: fsl: dpio: Add support for QBMan ring bulk enqueue.
From: Youri Querry @ 2019-08-08 20:59 UTC (permalink / raw)
To: Roy Pledge, Leo Li, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org, Ioana Ciocoi Radulescu,
Ioana Ciornei
Cc: Youri Querry
The QBMan frame descriptor enqueuing is changed from array
mode (a single frame enqueue at a time) to bulk ring mode.
This new mode allows the enqueuing of multiple frames in one operation.
The original interface is kept but use the bulk enqueue of one frame
Signed-off-by: Youri Querry <youri.querry_1@nxp.com>
---
drivers/soc/fsl/dpio/dpio-service.c | 69 +++-
drivers/soc/fsl/dpio/qbman-portal.c | 772 ++++++++++++++++++++++++++++++++----
drivers/soc/fsl/dpio/qbman-portal.h | 175 +++++++-
3 files changed, 935 insertions(+), 81 deletions(-)
diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c
index b9539ef..4eb53ee 100644
--- a/drivers/soc/fsl/dpio/dpio-service.c
+++ b/drivers/soc/fsl/dpio/dpio-service.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* Copyright 2014-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
+ * Copyright 2016-2019 NXP
*
*/
#include <linux/types.h>
@@ -435,6 +435,69 @@ int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d,
EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq);
/**
+ * dpaa2_io_service_enqueue_multiple_fq() - Enqueue multiple frames
+ * to a frame queue using one fqid.
+ * @d: the given DPIO service.
+ * @fqid: the given frame queue id.
+ * @fd: the list of frame descriptors enqueued.
+ * @nb: number of frames to be enqueued
+ *
+ * Return the number of enqueued frames (0 if EQCR is busy)
+ * or -ENODEV if there is no dpio service.
+ */
+int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d,
+ u32 fqid,
+ const struct dpaa2_fd *fd,
+ int nb)
+{
+ struct qbman_eq_desc ed;
+
+ d = service_select(d);
+ if (!d)
+ return -ENODEV;
+
+ qbman_eq_desc_clear(&ed);
+ qbman_eq_desc_set_no_orp(&ed, 0);
+ qbman_eq_desc_set_fq(&ed, fqid);
+
+ return qbman_swp_enqueue_multiple(d->swp, &ed, fd, 0, nb);
+}
+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_fq);
+
+/**
+ * dpaa2_io_service_enqueue_multiple_desc_fq() - Enqueue multiple frames
+ * to different frame queue using a list of fqids.
+ * @d: the given DPIO service.
+ * @fqid: the given list of frame queue ids.
+ * @fd: the list of frame descriptors enqueued.
+ * @nb: number of frames to be enqueued
+ *
+ * Return the number of enqueued frames (0 if EQCR is busy)
+ * or -ENODEV if there is no dpio service.
+ */
+int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d,
+ u32 *fqid,
+ const struct dpaa2_fd *fd,
+ int nb)
+{
+ int i;
+ struct qbman_eq_desc_min ed[32];
+
+ d = service_select(d);
+ if (!d)
+ return -ENODEV;
+
+ for (i = 0; i < nb; i++) {
+ qbman_eq_desc_min_clear(&ed[i]);
+ qbman_eq_desc_set_no_orp_min(&ed[i], 0);
+ qbman_eq_desc_set_min_fq(&ed[i], fqid[i]);
+ }
+
+ return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb);
+}
+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq);
+
+/**
* dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
* @d: the given DPIO service.
* @qdid: the given queuing destination id.
@@ -528,7 +591,7 @@ EXPORT_SYMBOL_GPL(dpaa2_io_service_acquire);
/**
* dpaa2_io_store_create() - Create the dma memory storage for dequeue result.
- * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
+ * @max_frames: the maximum number of dequeued result for frames, must be <= 32.
* @dev: the device to allow mapping/unmapping the DMAable region.
*
* The size of the storage is "max_frames*sizeof(struct dpaa2_dq)".
@@ -543,7 +606,7 @@ struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
struct dpaa2_io_store *ret;
size_t size;
- if (!max_frames || (max_frames > 16))
+ if (!max_frames || (max_frames > 32))
return NULL;
ret = kmalloc(sizeof(*ret), GFP_KERNEL);
diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c
index c66f5b7..c892a86 100644
--- a/drivers/soc/fsl/dpio/qbman-portal.c
+++ b/drivers/soc/fsl/dpio/qbman-portal.c
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Copyright 2016 NXP
+ * Copyright 2016-2019 NXP
*
*/
#include <asm/cacheflush.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/spinlock.h>
#include <soc/fsl/dpaa2-global.h>
#include "qbman-portal.h"
@@ -28,6 +29,7 @@
/* CINH register offsets */
#define QBMAN_CINH_SWP_EQCR_PI 0x800
+#define QBMAN_CINH_SWP_EQCR_CI 0x840
#define QBMAN_CINH_SWP_EQAR 0x8c0
#define QBMAN_CINH_SWP_CR_RT 0x900
#define QBMAN_CINH_SWP_VDQCR_RT 0x940
@@ -51,6 +53,8 @@
#define QBMAN_CENA_SWP_CR 0x600
#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((u32)(vb) >> 1))
#define QBMAN_CENA_SWP_VDQCR 0x780
+#define QBMAN_CENA_SWP_EQCR_CI 0x840
+#define QBMAN_CENA_SWP_EQCR_CI_MEMBACK 0x1840
/* CENA register offsets in memory-backed mode */
#define QBMAN_CENA_SWP_DQRR_MEM(n) (0x800 + ((u32)(n) << 6))
@@ -78,6 +82,12 @@
/* opaque token for static dequeues */
#define QMAN_SDQCR_TOKEN 0xbb
+#define QBMAN_EQCR_DCA_IDXMASK 0x0f
+#define QBMAN_ENQUEUE_FLAG_DCA (1ULL << 31)
+
+#define EQ_DESC_SIZE_WITHOUT_FD 29
+#define EQ_DESC_SIZE_FD_START 32
+
enum qbman_sdqcr_dct {
qbman_sdqcr_dct_null = 0,
qbman_sdqcr_dct_prio_ics,
@@ -90,6 +100,82 @@ enum qbman_sdqcr_fc {
qbman_sdqcr_fc_up_to_3 = 1
};
+/* Internal Function declaration */
+static int qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd);
+static int qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd);
+static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd,
+ uint32_t *flags,
+ int num_frames);
+static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd,
+ uint32_t *flags,
+ int num_frames);
+static int
+qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
+ const struct qbman_eq_desc_min *d,
+ const struct dpaa2_fd *fd,
+ int num_frames);
+static
+int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
+ const struct qbman_eq_desc_min *d,
+ const struct dpaa2_fd *fd,
+ int num_frames);
+static int qbman_swp_pull_direct(struct qbman_swp *s,
+ struct qbman_pull_desc *d);
+static int qbman_swp_pull_mem_back(struct qbman_swp *s,
+ struct qbman_pull_desc *d);
+
+const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s);
+const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s);
+
+static int qbman_swp_release_direct(struct qbman_swp *s,
+ const struct qbman_release_desc *d,
+ const u64 *buffers,
+ unsigned int num_buffers);
+static int qbman_swp_release_mem_back(struct qbman_swp *s,
+ const struct qbman_release_desc *d,
+ const u64 *buffers,
+ unsigned int num_buffers);
+
+/* Function pointers */
+int (*qbman_swp_enqueue_ring_mode_ptr)(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd)
+ = qbman_swp_enqueue_ring_mode_direct;
+
+int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd,
+ uint32_t *flags,
+ int num_frames)
+ = qbman_swp_enqueue_multiple_direct;
+
+int
+(*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s,
+ const struct qbman_eq_desc_min *d,
+ const struct dpaa2_fd *fd,
+ int num_frames)
+ = qbman_swp_enqueue_multiple_desc_direct;
+
+int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d)
+ = qbman_swp_pull_direct;
+
+const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s)
+ = qbman_swp_dqrr_next_direct;
+
+int (*qbman_swp_release_ptr)(struct qbman_swp *s,
+ const struct qbman_release_desc *d,
+ const u64 *buffers,
+ unsigned int num_buffers)
+ = qbman_swp_release_direct;
+
/* Portal Access */
static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset)
@@ -146,6 +232,15 @@ static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm,
#define QMAN_RT_MODE 0x00000100
+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
+{
+ /* 'first' is included, 'last' is excluded */
+ if (first <= last)
+ return last - first;
+ else
+ return (2 * ringsize) - (first - last);
+}
+
/**
* qbman_swp_init() - Create a functional object representing the given
* QBMan portal descriptor.
@@ -156,8 +251,12 @@ static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm,
*/
struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
{
- struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+ struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL);
u32 reg;
+ u32 mask_size;
+ u32 eqcr_pi;
+
+ spin_lock_init(&p->access_spinlock);
if (!p)
return NULL;
@@ -189,22 +288,39 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)
memset(p->addr_cena, 0, 64 * 1024);
- reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
- 1, /* Writes Non-cacheable */
- 0, /* EQCR_CI stashing threshold */
- 3, /* RPM: Valid bit mode, RCR in array mode */
- 2, /* DCM: Discrete consumption ack mode */
- 3, /* EPM: Valid bit mode, EQCR in array mode */
- 1, /* mem stashing drop enable == TRUE */
- 1, /* mem stashing priority == TRUE */
- 1, /* mem stashing enable == TRUE */
- 1, /* dequeue stashing priority == TRUE */
- 0, /* dequeue stashing enable == FALSE */
- 0); /* EQCR_CI stashing priority == FALSE */
- if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)
+ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {
+
+ reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
+ 0, /* Writes Non-cacheable */
+ 1, /* EQCR_CI stashing threshold */
+ 3, /* RPM: RCR in array mode */
+ 2, /* DCM: Discrete consumption ack */
+ 0, /* EPM: EQCR in ring mode */
+ 1, /* mem stashing drop enable */
+ 1, /* mem stashing priority enable */
+ 1, /* mem stashing enable */
+ 1, /* dequeue stashing priority enable */
+ 0, /* dequeue stashing enable */
+ 0); /* EQCR_CI stashing priority enable */
+ } else {
+ reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
+ 1, /* Writes Non-cacheable */
+ 0, /* EQCR_CI stashing threshold */
+ 3, /* RPM: RCR in array mode */
+ 2, /* DCM: Discrete consumption ack */
+ 2, /* EPM: EQCR in ring mode */
+ 1, /* mem stashing drop enable enable */
+ 1, /* mem stashing priority enable */
+ 1, /* mem stashing enable */
+ 1, /* dequeue stashing priority Tenable */
+ 0, /* dequeue stashing enable enable */
+ 0); /* EQCR_CI stashing priority enable */
+ }
+ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {
reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */
1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */
1 << SWP_CFG_CPM_SHIFT; /* CR read triggered mode */
+ }
qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg);
reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG);
@@ -225,6 +341,30 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
* applied when dequeues from a specific channel are enabled.
*/
qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0);
+
+ p->eqcr.pi_ring_size = 8;
+ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {
+ p->eqcr.pi_ring_size = 32;
+ qbman_swp_enqueue_ring_mode_ptr =
+ qbman_swp_enqueue_ring_mode_mem_back;
+ qbman_swp_enqueue_multiple_ptr =
+ qbman_swp_enqueue_multiple_mem_back;
+ qbman_swp_enqueue_multiple_desc_ptr =
+ qbman_swp_enqueue_multiple_desc_mem_back;
+ qbman_swp_pull_ptr = qbman_swp_pull_mem_back;
+ qbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back;
+ qbman_swp_release_ptr = qbman_swp_release_mem_back;
+ }
+
+ for (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1)
+ p->eqcr.pi_ci_mask = (p->eqcr.pi_ci_mask << 1) + 1;
+ eqcr_pi = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_PI);
+ p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask;
+ p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;
+ p->eqcr.ci = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_CI)
+ & p->eqcr.pi_ci_mask;
+ p->eqcr.available = p->eqcr.pi_ring_size;
+
return p;
}
@@ -378,6 +518,7 @@ enum qb_enqueue_commands {
#define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2
#define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
#define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4
+#define QB_ENQUEUE_CMD_DCA_EN_SHIFT 7
/**
* qbman_eq_desc_clear() - Clear the contents of a descriptor to
@@ -389,6 +530,16 @@ void qbman_eq_desc_clear(struct qbman_eq_desc *d)
}
/**
+ * qbman_eq_desc_min_clear() - Clear the contents of a minimal
+ * enqueue descriptor to
+ * default/starting state.
+ */
+void qbman_eq_desc_min_clear(struct qbman_eq_desc_min *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+/**
* qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
* @d: the enqueue descriptor.
* @response_success: 1 = enqueue with response always; 0 = enqueue with
@@ -403,6 +554,22 @@ void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
d->verb |= enqueue_rejects_to_fq;
}
+/**
+ * qbman_eq_desc_set_no_orp_min() - Set minimal enqueue descriptor without orp
+ * @d: the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ * rejections returned on a FQ.
+ */
+void qbman_eq_desc_set_no_orp_min(struct qbman_eq_desc_min *d,
+ int respond_success)
+{
+ d->verb &= ~(1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT);
+ if (respond_success)
+ d->verb |= enqueue_response_always;
+ else
+ d->verb |= enqueue_rejects_to_fq;
+}
+
/*
* Exactly one of the following descriptor "targets" should be set. (Calling any
* one of these will replace the effect of any prior call to one of these.)
@@ -422,6 +589,17 @@ void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid)
}
/**
+ * qbman_eq_desc_set_min_fq() - set the FQ for the minimal enqueue command
+ * @d: the enqueue descriptor
+ * @fqid: the id of the frame queue to be enqueued
+ */
+void qbman_eq_desc_set_min_fq(struct qbman_eq_desc_min *d, u32 fqid)
+{
+ d->verb &= ~(1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT);
+ d->tgtid = cpu_to_le32(fqid);
+}
+
+/**
* qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command
* @d: the enqueue descriptor
* @qdid: the id of the queuing destination to be enqueued
@@ -453,41 +631,340 @@ static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p,
QMAN_RT_MODE);
}
+#define QB_RT_BIT ((u32)0x100)
/**
- * qbman_swp_enqueue() - Issue an enqueue command
+ * qbman_swp_enqueue_ring_mode_direct() - Issue an enqueue command
* @s: the software portal used for enqueue
* @d: the enqueue descriptor
* @fd: the frame descriptor to be enqueued
*
- * Please note that 'fd' should only be NULL if the "action" of the
- * descriptor is "orp_hole" or "orp_nesn".
+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
+ */
+static
+int qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd)
+{
+ int flags = 0;
+ int ret = qbman_swp_enqueue_multiple_direct(s, d, fd, &flags, 1);
+
+ if (ret >= 0)
+ ret = 0;
+ else
+ ret = -EBUSY;
+ return ret;
+}
+
+/**
+ * qbman_swp_enqueue_ring_mode_mem_back() - Issue an enqueue command
+ * @s: the software portal used for enqueue
+ * @d: the enqueue descriptor
+ * @fd: the frame descriptor to be enqueued
*
* Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
*/
-int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
- const struct dpaa2_fd *fd)
+static
+int qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd)
{
- struct qbman_eq_desc *p;
- u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR);
+ int flags = 0;
+ int ret = qbman_swp_enqueue_multiple_mem_back(s, d, fd, &flags, 1);
- if (!EQAR_SUCCESS(eqar))
- return -EBUSY;
+ if (ret >= 0)
+ ret = 0;
+ else
+ ret = -EBUSY;
+ return ret;
+}
- p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
- memcpy(&p->dca, &d->dca, 31);
- memcpy(&p->fd, fd, sizeof(*fd));
+/**
+ * qbman_swp_enqueue_multiple_direct() - Issue a multi enqueue command
+ * using one enqueue descriptor
+ * @s: the software portal used for enqueue
+ * @d: the enqueue descriptor
+ * @fd: table pointer of frame descriptor table to be enqueued
+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL
+ * @num_frames: number of fd to be enqueued
+ *
+ * Return the number of fd enqueued, or a negative error number.
+ */
+static
+int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd,
+ uint32_t *flags,
+ int num_frames)
+{
+ uint32_t *p = NULL;
+ const uint32_t *cl = (uint32_t *)d;
+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
+ int i, num_enqueued = 0;
+
+ half_mask = (s->eqcr.pi_ci_mask>>1);
+ full_mask = s->eqcr.pi_ci_mask;
+
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI;
+ s->eqcr.ci = __raw_readl(p) & full_mask;
+
+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
+ eqcr_ci, s->eqcr.ci);
+ if (!s->eqcr.available)
+ return 0;
+ }
- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
- /* Set the verb byte, have to substitute in the valid-bit */
- dma_wmb();
- p->verb = d->verb | EQAR_VB(eqar);
- } else {
- p->verb = d->verb | EQAR_VB(eqar);
- dma_wmb();
- qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));
+ eqcr_pi = s->eqcr.pi;
+ num_enqueued = (s->eqcr.available < num_frames) ?
+ s->eqcr.available : num_frames;
+ s->eqcr.available -= num_enqueued;
+ /* Fill in the EQCR ring */
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ /* Skip copying the verb */
+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
+ &fd[i], sizeof(*fd));
+ eqcr_pi++;
}
- return 0;
+ dma_wmb();
+
+ /* Set the verb byte, have to substitute in the valid-bit */
+ eqcr_pi = s->eqcr.pi;
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
+ struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
+
+ d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
+ ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
+ }
+ eqcr_pi++;
+ if (!(eqcr_pi & half_mask))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+
+ s->eqcr.pi = (s->eqcr.pi + num_enqueued) & full_mask;
+
+ return num_enqueued;
+}
+
+/**
+ * qbman_swp_enqueue_multiple_mem_back() - Issue a multi enqueue command
+ * using one enqueue descriptor
+ * @s: the software portal used for enqueue
+ * @d: the enqueue descriptor
+ * @fd: table pointer of frame descriptor table to be enqueued
+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL
+ * @num_frames: number of fd to be enqueued
+ *
+ * Return the number of fd enqueued, or a negative error number.
+ */
+static
+int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd,
+ uint32_t *flags,
+ int num_frames)
+{
+ uint32_t *p = NULL;
+ const uint32_t *cl = (uint32_t *)(d);
+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
+ int i, num_enqueued = 0;
+ unsigned long irq_flags;
+
+ spin_lock(&s->access_spinlock);
+ local_irq_save(irq_flags);
+
+ half_mask = (s->eqcr.pi_ci_mask>>1);
+ full_mask = s->eqcr.pi_ci_mask;
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK;
+ s->eqcr.ci = __raw_readl(p) & full_mask;
+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
+ eqcr_ci, s->eqcr.ci);
+ if (!s->eqcr.available) {
+ local_irq_restore(irq_flags);
+ spin_unlock(&s->access_spinlock);
+ return 0;
+ }
+ }
+
+ eqcr_pi = s->eqcr.pi;
+ num_enqueued = (s->eqcr.available < num_frames) ?
+ s->eqcr.available : num_frames;
+ s->eqcr.available -= num_enqueued;
+ /* Fill in the EQCR ring */
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ /* Skip copying the verb */
+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
+ &fd[i], sizeof(*fd));
+ eqcr_pi++;
+ }
+
+ /* Set the verb byte, have to substitute in the valid-bit */
+ eqcr_pi = s->eqcr.pi;
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {
+ struct qbman_eq_desc *d = (struct qbman_eq_desc *)p;
+
+ d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |
+ ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);
+ }
+ eqcr_pi++;
+ if (!(eqcr_pi & half_mask))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+ s->eqcr.pi = eqcr_pi & full_mask;
+
+ dma_wmb();
+ qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI,
+ (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
+ local_irq_restore(irq_flags);
+ spin_unlock(&s->access_spinlock);
+
+ return num_enqueued;
+}
+
+/**
+ * qbman_swp_enqueue_multiple_desc_direct() - Issue a multi enqueue command
+ * using multiple enqueue descriptor
+ * @s: the software portal used for enqueue
+ * @d: table of minimal enqueue descriptor
+ * @fd: table pointer of frame descriptor table to be enqueued
+ * @num_frames: number of fd to be enqueued
+ *
+ * Return the number of fd enqueued, or a negative error number.
+ */
+static
+int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
+ const struct qbman_eq_desc_min *d,
+ const struct dpaa2_fd *fd,
+ int num_frames)
+{
+ uint32_t *p;
+ const uint32_t *cl;
+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
+ int i, num_enqueued = 0;
+
+ half_mask = (s->eqcr.pi_ci_mask>>1);
+ full_mask = s->eqcr.pi_ci_mask;
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI;
+ s->eqcr.ci = __raw_readl(p) & full_mask;
+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
+ eqcr_ci, s->eqcr.ci);
+ if (!s->eqcr.available)
+ return 0;
+ }
+
+ eqcr_pi = s->eqcr.pi;
+ num_enqueued = (s->eqcr.available < num_frames) ?
+ s->eqcr.available : num_frames;
+ s->eqcr.available -= num_enqueued;
+ /* Fill in the EQCR ring */
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ cl = (uint32_t *)(&d[i]);
+ /* Skip copying the verb */
+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
+ &fd[i], sizeof(*fd));
+ eqcr_pi++;
+ }
+
+ dma_wmb();
+
+ /* Set the verb byte, have to substitute in the valid-bit */
+ eqcr_pi = s->eqcr.pi;
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ cl = (uint32_t *)(&d[i]);
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ eqcr_pi++;
+ if (!(eqcr_pi & half_mask))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+ s->eqcr.pi = (s->eqcr.pi + num_enqueued) & full_mask;
+
+ return num_enqueued;
+}
+
+/**
+ * qbman_swp_enqueue_multiple_desc_mem_back() - Issue a multi enqueue command
+ * using multiple enqueue descriptor
+ * @s: the software portal used for enqueue
+ * @d: table of minimal enqueue descriptor
+ * @fd: table pointer of frame descriptor table to be enqueued
+ * @num_frames: number of fd to be enqueued
+ *
+ * Return the number of fd enqueued, or a negative error number.
+ */
+static
+int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
+ const struct qbman_eq_desc_min *d,
+ const struct dpaa2_fd *fd,
+ int num_frames)
+{
+ uint32_t *p;
+ const uint32_t *cl;
+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
+ int i, num_enqueued = 0;
+
+ half_mask = (s->eqcr.pi_ci_mask>>1);
+ full_mask = s->eqcr.pi_ci_mask;
+ if (!s->eqcr.available) {
+ eqcr_ci = s->eqcr.ci;
+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK;
+ s->eqcr.ci = __raw_readl(p) & full_mask;
+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
+ eqcr_ci, s->eqcr.ci);
+ if (!s->eqcr.available)
+ return 0;
+ }
+
+ eqcr_pi = s->eqcr.pi;
+ num_enqueued = (s->eqcr.available < num_frames) ?
+ s->eqcr.available : num_frames;
+ s->eqcr.available -= num_enqueued;
+ /* Fill in the EQCR ring */
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ cl = (uint32_t *)(&d[i]);
+ /* Skip copying the verb */
+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1);
+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)],
+ &fd[i], sizeof(*fd));
+ eqcr_pi++;
+ }
+
+ /* Set the verb byte, have to substitute in the valid-bit */
+ eqcr_pi = s->eqcr.pi;
+ for (i = 0; i < num_enqueued; i++) {
+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));
+ cl = (uint32_t *)(&d[i]);
+ p[0] = cl[0] | s->eqcr.pi_vb;
+ eqcr_pi++;
+ if (!(eqcr_pi & half_mask))
+ s->eqcr.pi_vb ^= QB_VALID_BIT;
+ }
+
+ s->eqcr.pi = eqcr_pi & full_mask;
+
+ dma_wmb();
+ qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI,
+ (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
+
+ return num_enqueued;
}
/* Static (push) dequeue */
@@ -645,7 +1122,7 @@ void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
}
/**
- * qbman_swp_pull() - Issue the pull dequeue command
+ * qbman_swp_pull_direct() - Issue the pull dequeue command
* @s: the software portal object
* @d: the software portal descriptor which has been configured with
* the set of qbman_pull_desc_set_*() calls
@@ -653,7 +1130,7 @@ void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
* Return 0 for success, and -EBUSY if the software portal is not ready
* to do pull dequeue.
*/
-int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+static int qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d)
{
struct qbman_pull_desc *p;
@@ -671,18 +1148,48 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
p->dq_src = d->dq_src;
p->rsp_addr = d->rsp_addr;
p->rsp_addr_virt = d->rsp_addr_virt;
+ dma_wmb();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p->verb = d->verb | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
- dma_wmb();
- /* Set the verb byte, have to substitute in the valid-bit */
- p->verb = d->verb | s->vdq.valid_bit;
- s->vdq.valid_bit ^= QB_VALID_BIT;
- } else {
- p->verb = d->verb | s->vdq.valid_bit;
- s->vdq.valid_bit ^= QB_VALID_BIT;
- dma_wmb();
- qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);
+ return 0;
+}
+
+/**
+ * qbman_swp_pull_mem_back() - Issue the pull dequeue command
+ * @s: the software portal object
+ * @d: the software portal descriptor which has been configured with
+ * the set of qbman_pull_desc_set_*() calls
+ *
+ * Return 0 for success, and -EBUSY if the software portal is not ready
+ * to do pull dequeue.
+ */
+static int qbman_swp_pull_mem_back(struct qbman_swp *s,
+ struct qbman_pull_desc *d)
+{
+ struct qbman_pull_desc *p;
+
+ if (!atomic_dec_and_test(&s->vdq.available)) {
+ atomic_inc(&s->vdq.available);
+ return -EBUSY;
}
+ s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt;
+ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
+ else
+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR_MEM);
+ p->numf = d->numf;
+ p->tok = QMAN_DQ_TOKEN_VALID;
+ p->dq_src = d->dq_src;
+ p->rsp_addr = d->rsp_addr;
+ p->rsp_addr_virt = d->rsp_addr_virt;
+
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p->verb = d->verb | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
+ dma_wmb();
+ qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);
return 0;
}
@@ -690,14 +1197,14 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
#define QMAN_DQRR_PI_MASK 0xf
/**
- * qbman_swp_dqrr_next() - Get an valid DQRR entry
+ * qbman_swp_dqrr_next_direct() - Get an valid DQRR entry
* @s: the software portal object
*
* Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
* only once, so repeated calls can return a sequence of DQRR entries, without
* requiring they be consumed immediately or in any particular order.
*/
-const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
+const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s)
{
u32 verb;
u32 response_verb;
@@ -740,10 +1247,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
}
- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
- p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
- else
- p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));
+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
verb = p->dq.verb;
/*
@@ -785,6 +1289,98 @@ const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
}
/**
+ * qbman_swp_dqrr_next_mem_back() - Get an valid DQRR entry
+ * @s: the software portal object
+ *
+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s)
+{
+ u32 verb;
+ u32 response_verb;
+ u32 flags;
+ struct dpaa2_dq *p;
+
+ /* Before using valid-bit to detect if something is there, we have to
+ * handle the case of the DQRR reset bug...
+ */
+ if (unlikely(s->dqrr.reset_bug)) {
+ /*
+ * We pick up new entries by cache-inhibited producer index,
+ * which means that a non-coherent mapping would require us to
+ * invalidate and read *only* once that PI has indicated that
+ * there's an entry here. The first trip around the DQRR ring
+ * will be much less efficient than all subsequent trips around
+ * it...
+ */
+ u8 pi = qbman_read_register(s, QBMAN_CINH_SWP_DQPI) &
+ QMAN_DQRR_PI_MASK;
+
+ /* there are new entries if pi != next_idx */
+ if (pi == s->dqrr.next_idx)
+ return NULL;
+
+ /*
+ * if next_idx is/was the last ring index, and 'pi' is
+ * different, we can disable the workaround as all the ring
+ * entries have now been DMA'd to so valid-bit checking is
+ * repaired. Note: this logic needs to be based on next_idx
+ * (which increments one at a time), rather than on pi (which
+ * can burst and wrap-around between our snapshots of it).
+ */
+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) {
+ pr_debug("next_idx=%d, pi=%d, clear reset bug\n",
+ s->dqrr.next_idx, pi);
+ s->dqrr.reset_bug = 0;
+ }
+ prefetch(qbman_get_cmd(s,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
+ }
+
+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));
+ verb = p->dq.verb;
+
+ /*
+ * If the valid-bit isn't of the expected polarity, nothing there. Note,
+ * in the DQRR reset bug workaround, we shouldn't need to skip these
+ * check, because we've already determined that a new entry is available
+ * and we've invalidated the cacheline before reading it, so the
+ * valid-bit behaviour is repaired and should tell us what we already
+ * knew from reading PI.
+ */
+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
+ prefetch(qbman_get_cmd(s,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
+ return NULL;
+ }
+ /*
+ * There's something there. Move "next_idx" attention to the next ring
+ * entry (and prefetch it) before returning what we found.
+ */
+ s->dqrr.next_idx++;
+ s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */
+ if (!s->dqrr.next_idx)
+ s->dqrr.valid_bit ^= QB_VALID_BIT;
+
+ /*
+ * If this is the final response to a volatile dequeue command
+ * indicate that the vdq is available
+ */
+ flags = p->dq.stat;
+ response_verb = verb & QBMAN_RESULT_MASK;
+ if (response_verb == QBMAN_RESULT_DQ &&
+ (flags & DPAA2_DQ_STAT_VOLATILE) &&
+ (flags & DPAA2_DQ_STAT_EXPIRED))
+ atomic_inc(&s->vdq.available);
+
+ prefetch(qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
+
+ return p;
+}
+
+/**
* qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from
* qbman_swp_dqrr_next().
* @s: the software portal object
@@ -872,7 +1468,7 @@ void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
#define RAR_SUCCESS(rar) ((rar) & 0x100)
/**
- * qbman_swp_release() - Issue a buffer release command
+ * qbman_swp_release_direct() - Issue a buffer release command
* @s: the software portal object
* @d: the release descriptor
* @buffers: a pointer pointing to the buffer address to be released
@@ -880,8 +1476,53 @@ void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
*
* Return 0 for success, -EBUSY if the release command ring is not ready.
*/
-int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
- const u64 *buffers, unsigned int num_buffers)
+int qbman_swp_release_direct(struct qbman_swp *s,
+ const struct qbman_release_desc *d,
+ const u64 *buffers, unsigned int num_buffers)
+{
+ int i;
+ struct qbman_release_desc *p;
+ u32 rar;
+
+ if (!num_buffers || num_buffers > 7)
+ return -EINVAL;
+
+ rar = qbman_read_register(s, QBMAN_CINH_SWP_RAR);
+ if (!RAR_SUCCESS(rar))
+ return -EBUSY;
+
+ /* Start the release command */
+ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)
+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ else
+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ for (i = 0; i < num_buffers; i++)
+ p->buf[i] = cpu_to_le64(buffers[i]);
+ p->bpid = d->bpid;
+
+ /*
+ * Set the verb byte, have to substitute in the valid-bit
+ * and the number of buffers.
+ */
+ dma_wmb();
+ p->verb = d->verb | RAR_VB(rar) | num_buffers;
+
+ return 0;
+}
+
+/**
+ * qbman_swp_release_mem_back() - Issue a buffer release command
+ * @s: the software portal object
+ * @d: the release descriptor
+ * @buffers: a pointer pointing to the buffer address to be released
+ * @num_buffers: number of buffers to be released, must be less than 8
+ *
+ * Return 0 for success, -EBUSY if the release command ring is not ready.
+ */
+int qbman_swp_release_mem_back(struct qbman_swp *s,
+ const struct qbman_release_desc *d,
+ const u64 *buffers, unsigned int num_buffers)
{
int i;
struct qbman_release_desc *p;
@@ -904,19 +1545,10 @@ int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
p->buf[i] = cpu_to_le64(buffers[i]);
p->bpid = d->bpid;
- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {
- /*
- * Set the verb byte, have to substitute in the valid-bit
- * and the number of buffers.
- */
- dma_wmb();
- p->verb = d->verb | RAR_VB(rar) | num_buffers;
- } else {
- p->verb = d->verb | RAR_VB(rar) | num_buffers;
- dma_wmb();
- qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT +
- RAR_IDX(rar) * 4, QMAN_RT_MODE);
- }
+ p->verb = d->verb | RAR_VB(rar) | num_buffers;
+ dma_wmb();
+ qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT +
+ RAR_IDX(rar) * 4, QMAN_RT_MODE);
return 0;
}
diff --git a/drivers/soc/fsl/dpio/qbman-portal.h b/drivers/soc/fsl/dpio/qbman-portal.h
index f3ec5d2..f4b6e47 100644
--- a/drivers/soc/fsl/dpio/qbman-portal.h
+++ b/drivers/soc/fsl/dpio/qbman-portal.h
@@ -9,6 +9,13 @@
#include <soc/fsl/dpaa2-fd.h>
+#define QMAN_REV_4000 0x04000000
+#define QMAN_REV_4100 0x04010000
+#define QMAN_REV_4101 0x04010001
+#define QMAN_REV_5000 0x05000000
+
+#define QMAN_REV_MASK 0xffff0000
+
struct dpaa2_dq;
struct qbman_swp;
@@ -67,6 +74,22 @@ enum qbman_pull_type_e {
#define QBMAN_FQ_XOFF 0x4e
/* structure of enqueue descriptor */
+struct qbman_eq_desc_min {
+ u8 verb;
+ u8 dca;
+ __le16 seqnum;
+ __le16 orpid;
+ __le16 reserved1;
+ __le32 tgtid;
+ __le32 tag;
+ __le16 qdbin;
+ u8 qpri;
+ u8 reserved[3];
+ u8 wae;
+ u8 rspid;
+ __le64 rsp_addr;
+};
+
struct qbman_eq_desc {
u8 verb;
u8 dca;
@@ -132,8 +155,48 @@ struct qbman_swp {
u8 dqrr_size;
int reset_bug; /* indicates dqrr reset workaround is needed */
} dqrr;
+
+ struct {
+ u32 pi;
+ u32 pi_vb;
+ u32 pi_ring_size;
+ u32 pi_ci_mask;
+ u32 ci;
+ int available;
+ u32 pend;
+ u32 no_pfdr;
+ } eqcr;
+
+ spinlock_t access_spinlock;
};
+/* Function pointers */
+extern
+int (*qbman_swp_enqueue_ring_mode_ptr)(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd);
+extern
+int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd,
+ uint32_t *flags,
+ int num_frames);
+extern
+int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s,
+ const struct qbman_eq_desc_min *d,
+ const struct dpaa2_fd *fd,
+ int num_frames);
+extern
+int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d);
+extern
+const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s);
+extern
+int (*qbman_swp_release_ptr)(struct qbman_swp *s,
+ const struct qbman_release_desc *d,
+ const u64 *buffers,
+ unsigned int num_buffers);
+
+/* Functions */
struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
void qbman_swp_finish(struct qbman_swp *p);
u32 qbman_swp_interrupt_read_status(struct qbman_swp *p);
@@ -158,29 +221,25 @@ void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid,
void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
enum qbman_pull_type_e dct);
-int qbman_swp_pull(struct qbman_swp *p, struct qbman_pull_desc *d);
-
-const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s);
void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq);
int qbman_result_has_new_result(struct qbman_swp *p, const struct dpaa2_dq *dq);
void qbman_eq_desc_clear(struct qbman_eq_desc *d);
+void qbman_eq_desc_min_clear(struct qbman_eq_desc_min *d);
void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
+void qbman_eq_desc_set_no_orp_min(struct qbman_eq_desc_min *d,
+ int respond_success);
void qbman_eq_desc_set_token(struct qbman_eq_desc *d, u8 token);
void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid);
+void qbman_eq_desc_set_min_fq(struct qbman_eq_desc_min *d, u32 fqid);
void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
u32 qd_bin, u32 qd_prio);
-int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d,
- const struct dpaa2_fd *fd);
-
void qbman_release_desc_clear(struct qbman_release_desc *d);
void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid);
void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
-int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
- const u64 *buffers, unsigned int num_buffers);
int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
unsigned int num_buffers);
int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
@@ -194,6 +253,61 @@ void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb);
void *qbman_swp_mc_result(struct qbman_swp *p);
/**
+ * qbman_swp_enqueue() - Issue an enqueue command
+ * @s: the software portal used for enqueue
+ * @d: the enqueue descriptor
+ * @fd: the frame descriptor to be enqueued
+ *
+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
+ */
+static inline int
+qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd)
+{
+ return qbman_swp_enqueue_ring_mode_ptr(s, d, fd);
+}
+
+/**
+ * qbman_swp_enqueue_multiple() - Issue a multi enqueue command
+ * using one enqueue descriptor
+ * @s: the software portal used for enqueue
+ * @d: the enqueue descriptor
+ * @fd: table pointer of frame descriptor table to be enqueued
+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL
+ * @num_frames: number of fd to be enqueued
+ *
+ * Return the number of fd enqueued, or a negative error number.
+ */
+static inline int
+qbman_swp_enqueue_multiple(struct qbman_swp *s,
+ const struct qbman_eq_desc *d,
+ const struct dpaa2_fd *fd,
+ uint32_t *flags,
+ int num_frames)
+{
+ return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags, num_frames);
+}
+
+/**
+ * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command
+ * using multiple enqueue descriptor
+ * @s: the software portal used for enqueue
+ * @d: table of minimal enqueue descriptor
+ * @fd: table pointer of frame descriptor table to be enqueued
+ * @num_frames: number of fd to be enqueued
+ *
+ * Return the number of fd enqueued, or a negative error number.
+ */
+static inline int
+qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,
+ const struct qbman_eq_desc_min *d,
+ const struct dpaa2_fd *fd,
+ int num_frames)
+{
+ return qbman_swp_enqueue_multiple_desc_ptr(s, d, fd, num_frames);
+}
+
+/**
* qbman_result_is_DQ() - check if the dequeue result is a dequeue response
* @dq: the dequeue result to be checked
*
@@ -504,4 +618,49 @@ int qbman_bp_query(struct qbman_swp *s, u16 bpid,
u32 qbman_bp_info_num_free_bufs(struct qbman_bp_query_rslt *a);
+/**
+ * qbman_swp_release() - Issue a buffer release command
+ * @s: the software portal object
+ * @d: the release descriptor
+ * @buffers: a pointer pointing to the buffer address to be released
+ * @num_buffers: number of buffers to be released, must be less than 8
+ *
+ * Return 0 for success, -EBUSY if the release command ring is not ready.
+ */
+static inline int qbman_swp_release(struct qbman_swp *s,
+ const struct qbman_release_desc *d,
+ const u64 *buffers,
+ unsigned int num_buffers)
+{
+ return qbman_swp_release_ptr(s, d, buffers, num_buffers);
+}
+
+/**
+ * qbman_swp_pull() - Issue the pull dequeue command
+ * @s: the software portal object
+ * @d: the software portal descriptor which has been configured with
+ * the set of qbman_pull_desc_set_*() calls
+ *
+ * Return 0 for success, and -EBUSY if the software portal is not ready
+ * to do pull dequeue.
+ */
+static inline int qbman_swp_pull(struct qbman_swp *s,
+ struct qbman_pull_desc *d)
+{
+ return qbman_swp_pull_ptr(s, d);
+}
+
+/**
+ * qbman_swp_dqrr_next() - Get an valid DQRR entry
+ * @s: the software portal object
+ *
+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+static inline const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+ return qbman_swp_dqrr_next_ptr(s);
+}
+
#endif /* __FSL_QBMAN_PORTAL_H */
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v19 00/15] arm64: untag user pointers passed to the kernel
From: Kees Cook @ 2019-08-08 21:12 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Mark Rutland, kvm, Christian Koenig, Szabolcs Nagy,
Catalin Marinas, Will Deacon, dri-devel, Kostya Serebryany,
Khalid Aziz, Lee Smith, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Jacob Bramley, Leon Romanovsky,
linux-rdma, amd-gfx, Christoph Hellwig, Jason Gunthorpe,
Dmitry Vyukov, Dave Martin, Evgeniy Stepanov, linux-media,
Ruben Ayrapetyan, Kevin Brodsky, Alex Williamson,
Mauro Carvalho Chehab, Linux ARM, Linux Memory Management List,
Greg Kroah-Hartman, Felix Kuehling, LKML, Jens Wiklander,
Ramana Radhakrishnan, Alexander Deucher, Andrew Morton, enh,
Robin Murphy, Yishai Hadas, Luc Van Oostenryck
In-Reply-To: <CAAeHK+zF01mxU+PkEYLkoVu-ZZM6jNfL_OwMJKRwLr-sdU4Myg@mail.gmail.com>
On Wed, Aug 07, 2019 at 07:17:35PM +0200, Andrey Konovalov wrote:
> On Tue, Aug 6, 2019 at 7:13 PM Will Deacon <will@kernel.org> wrote:
> >
> > On Wed, Jul 24, 2019 at 03:20:59PM +0100, Will Deacon wrote:
> > > On Wed, Jul 24, 2019 at 04:16:49PM +0200, Andrey Konovalov wrote:
> > > > On Wed, Jul 24, 2019 at 4:02 PM Will Deacon <will@kernel.org> wrote:
> > > > > On Tue, Jul 23, 2019 at 08:03:29PM +0200, Andrey Konovalov wrote:
> > > > > > Should this go through the mm or the arm tree?
> > > > >
> > > > > I would certainly prefer to take at least the arm64 bits via the arm64 tree
> > > > > (i.e. patches 1, 2 and 15). We also need a Documentation patch describing
> > > > > the new ABI.
> > > >
> > > > Sounds good! Should I post those patches together with the
> > > > Documentation patches from Vincenzo as a separate patchset?
> > >
> > > Yes, please (although as you say below, we need a new version of those
> > > patches from Vincenzo to address the feedback on v5). The other thing I
> > > should say is that I'd be happy to queue the other patches in the series
> > > too, but some of them are missing acks from the relevant maintainers (e.g.
> > > the mm/ and fs/ changes).
> >
> > Ok, I've queued patches 1, 2, and 15 on a stable branch here:
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/tbi
> >
> > which should find its way into -next shortly via our for-next/core branch.
> > If you want to make changes, please send additional patches on top.
> >
> > This is targetting 5.4, but I will drop it before the merge window if
> > we don't have both of the following in place:
> >
> > * Updated ABI documentation with Acks from Catalin and Kevin
>
> Catalin has posted a new version today.
>
> > * The other patches in the series either Acked (so I can pick them up)
> > or queued via some other tree(s) for 5.4.
>
> So we have the following patches in this series:
>
> 1. arm64: untag user pointers in access_ok and __uaccess_mask_ptr
> 2. arm64: Introduce prctl() options to control the tagged user addresses ABI
> 3. lib: untag user pointers in strn*_user
> 4. mm: untag user pointers passed to memory syscalls
> 5. mm: untag user pointers in mm/gup.c
> 6. mm: untag user pointers in get_vaddr_frames
> 7. fs/namespace: untag user pointers in copy_mount_options
> 8. userfaultfd: untag user pointers
> 9. drm/amdgpu: untag user pointers
> 10. drm/radeon: untag user pointers in radeon_gem_userptr_ioctl
> 11. IB/mlx4: untag user pointers in mlx4_get_umem_mr
> 12. media/v4l2-core: untag user pointers in videobuf_dma_contig_user_get
> 13. tee/shm: untag user pointers in tee_shm_register
> 14. vfio/type1: untag user pointers in vaddr_get_pfn
> 15. selftests, arm64: add a selftest for passing tagged pointers to kernel
>
> 1, 2 and 15 have been picked by Will.
>
> 11 has been picked up by Jason.
>
> 9, 10, 12, 13 and 14 have acks from their subsystem maintainers.
>
> 3 touches generic lib code, I'm not sure if there's a dedicated
> maintainer for that.
Andrew tends to pick up lib/ patches.
> The ones that are left are the mm ones: 4, 5, 6, 7 and 8.
>
> Andrew, could you take a look and give your Acked-by or pick them up directly?
Given the subsystem Acks, it seems like 3-10 and 12 could all just go
via Andrew? I hope he agrees. :)
--
Kees Cook
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 0/4] clk: meson: g12a: add support for DVFS
From: Kevin Hilman @ 2019-08-08 21:18 UTC (permalink / raw)
To: Neil Armstrong, sboyd, jbrunet
Cc: linux-kernel, linux-amlogic, linux-clk, linux-arm-kernel,
Neil Armstrong
In-Reply-To: <20190731084019.8451-1-narmstrong@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> The G12A/G12B Socs embeds a specific clock tree for each CPU cluster :
> cpu_clk / cpub_clk
> | \- cpu_clk_dyn
> | | \- cpu_clk_premux0
> | | |- cpu_clk_postmux0
> | | | |- cpu_clk_dyn0_div
> | | | \- xtal/fclk_div2/fclk_div3
> | | \- xtal/fclk_div2/fclk_div3
> | \- cpu_clk_premux1
> | |- cpu_clk_postmux1
> | | |- cpu_clk_dyn1_div
> | | \- xtal/fclk_div2/fclk_div3
> | \- xtal/fclk_div2/fclk_div3
> \ sys_pll / sys1_pll
>
> This patchset adds notifiers on cpu_clk / cpub_clk, cpu_clk_dyn,
> cpu_clk_premux0 and sys_pll / sys1_pll to permit change frequency of
> the CPU clock in a safe way as recommended by the vendor Documentation
> and reference code.
>
> This patchset :
> - introduces needed core and meson clk changes
> - adds the clock notifiers
>
> Dependencies:
> - None
nit: this doesn't apply to v5.3-rc, but appears to apply on
clk-meson/v5.4/drivers, so it appears to be dependent on the cleanups
from Alex.
Kevin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 00/22] ARM: omap1 multiplatform support
From: Arnd Bergmann @ 2019-08-08 21:22 UTC (permalink / raw)
To: Tony Lindgren, Aaro Koskinen
Cc: Arnd Bergmann, Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
Linus Walleij, Tomi Valkeinen, linux-omap, linux-arm-kernel
I spent some time cleaning up omap1, which is one of the last
remaining ARM9 platforms that is not yet part of
CONFIG_ARCH_MULTIPLATFORM.
There are two main parts here:
1. Avoiding mach/*.h header file dependencies, in particular
mach/memory.h and mach/io.h. I managed to split out a
small set of headers that are moved to include/linux/soc/ti,
to avoid completely rewriting the platform interfaces,
while getting all drivers to be actually self-contained
aside from these headers.
2. Rewriting the clock driver to use common-clk
I've never written a clock driver before, and I tried to
stick to the original code without changing too much here,
so the result is not overly pretty, and likely contains
bugs, but I think I'm on the track here. I did not test
any of this on real hardware, so I need some help in
testing and fixing this.
I would hope to merge the entire series through the arm-soc
tree for the next merge window, along with other some of the
other platforms I worked on.
Arnd
Arnd Bergmann (22):
ARM: omap1: innovator: pass lcd control address as pdata
ARM: omap1: make omapfb standalone compilable
ARM: omap1: move omap15xx local bus handling to usb.c
ARM: omap1: move ohci phy power handling to board files
ARM: omap1: move mach/usb.h to include/linux/soc
ARM: omap1: move some headers to include/linux/soc
ARM: omap1: move perseus spi pinconf to board file
ARM: omap1: move CF chipselect setup to board file
fbdev: omap: avoid using mach/*.h files
usb: omap: avoid mach/*.h headers
clocksource: ti-dmtimer: avoid using mach/hardware.h
serial: 8250/omap1: include linux/soc/ti/omap1-soc.h
input: omap: void using mach/*.h headers
ARM: omap1: use pci_ioremap_io() for omap_cf
ARM: omap1: move mach/*.h into mach directory
ARM: omap1: move clk support into a single file
ARM: omap1: remove some dead clock code
ARM: omap1: clk: rework 'struct clk'
ARM: omap1: clk: use common_clk-like callbacks
ARM: omap1: clk: use clk_init_data
ARM: omap1: use common clk framework
ARM: omap1: enable multiplatform
arch/arm/Kconfig | 18 -
arch/arm/configs/omap1_defconfig | 3 +
arch/arm/mach-omap1/Kconfig | 20 +-
arch/arm/mach-omap1/Makefile | 10 +-
arch/arm/mach-omap1/ams-delta-fiq-handler.S | 3 +-
arch/arm/mach-omap1/ams-delta-fiq.c | 2 +
arch/arm/mach-omap1/ams-delta-fiq.h | 2 +-
arch/arm/mach-omap1/board-ams-delta.c | 7 +-
arch/arm/mach-omap1/board-fsample.c | 10 +-
arch/arm/mach-omap1/board-generic.c | 8 +-
arch/arm/mach-omap1/board-h2.c | 12 +-
arch/arm/mach-omap1/board-h3.c | 14 +-
arch/arm/mach-omap1/board-htcherald.c | 10 +-
arch/arm/mach-omap1/board-innovator.c | 34 +-
arch/arm/mach-omap1/board-nokia770.c | 9 +-
arch/arm/mach-omap1/board-osk.c | 68 +-
arch/arm/mach-omap1/board-palmte.c | 14 +-
arch/arm/mach-omap1/board-palmtt.c | 14 +-
arch/arm/mach-omap1/board-palmz71.c | 14 +-
arch/arm/mach-omap1/board-perseus2.c | 13 +-
arch/arm/mach-omap1/board-sx1-mmc.c | 3 +-
arch/arm/mach-omap1/board-sx1.c | 12 +-
arch/arm/mach-omap1/clock.c | 1515 ++++++++++++-----
arch/arm/mach-omap1/clock.h | 288 ----
arch/arm/mach-omap1/clock_data.c | 921 ----------
arch/arm/mach-omap1/common.h | 5 +-
arch/arm/mach-omap1/devices.c | 9 +-
arch/arm/mach-omap1/fb.c | 19 +-
arch/arm/mach-omap1/flash.c | 3 +-
arch/arm/mach-omap1/fpga.c | 3 +-
arch/arm/mach-omap1/gpio15xx.c | 3 +-
arch/arm/mach-omap1/gpio16xx.c | 5 +-
arch/arm/mach-omap1/gpio7xx.c | 3 +-
.../mach-omap1/{include/mach => }/hardware.h | 132 +-
arch/arm/mach-omap1/i2c.c | 3 +-
arch/arm/mach-omap1/id.c | 5 +-
arch/arm/mach-omap1/include/mach/io.h | 45 -
arch/arm/mach-omap1/include/mach/lcdc.h | 44 -
arch/arm/mach-omap1/include/mach/memory.h | 55 -
arch/arm/mach-omap1/include/mach/uncompress.h | 117 --
arch/arm/mach-omap1/io.c | 6 +-
arch/arm/mach-omap1/irq.c | 4 +-
arch/arm/mach-omap1/{include/mach => }/irqs.h | 2 -
arch/arm/mach-omap1/mcbsp.c | 9 +-
.../mach-omap1/{include/mach => }/mtd-xip.h | 3 +-
arch/arm/mach-omap1/mux.c | 6 +-
arch/arm/mach-omap1/mux.h | 144 ++
arch/arm/mach-omap1/ocpi.c | 4 +-
.../mach-omap1/{include/mach => }/omap1510.h | 1 -
.../mach-omap1/{include/mach => }/omap16xx.h | 0
.../mach-omap1/{include/mach => }/omap7xx.h | 0
arch/arm/mach-omap1/opp.h | 26 -
arch/arm/mach-omap1/opp_data.c | 51 -
arch/arm/mach-omap1/pm.c | 8 +-
arch/arm/mach-omap1/pm.h | 2 +
arch/arm/mach-omap1/reset.c | 3 +-
arch/arm/mach-omap1/serial.c | 4 +-
.../mach-omap1/{include/mach => }/serial.h | 0
arch/arm/mach-omap1/sleep.S | 2 +-
arch/arm/mach-omap1/soc.h | 6 +-
arch/arm/mach-omap1/sram.S | 4 +-
arch/arm/mach-omap1/time.c | 2 +-
arch/arm/mach-omap1/timer.c | 1 +
arch/arm/mach-omap1/timer32k.c | 3 +-
arch/arm/mach-omap1/usb.c | 87 +-
arch/arm/mach-omap1/usb.h | 25 +
arch/arm/plat-omap/Makefile | 1 +
arch/arm/plat-omap/dma.c | 4 +-
arch/arm/plat-omap/include/plat/cpu.h | 21 -
drivers/clocksource/timer-ti-dm.c | 2 +-
drivers/input/keyboard/Kconfig | 2 +-
drivers/input/keyboard/omap-keypad.c | 1 +
drivers/pcmcia/Kconfig | 3 +-
drivers/pcmcia/omap_cf.c | 47 +-
drivers/spi/Kconfig | 2 +-
drivers/spi/spi-omap-uwire.c | 15 +-
drivers/tty/serial/8250/8250.h | 1 +
drivers/usb/gadget/udc/Kconfig | 2 +-
drivers/usb/gadget/udc/omap_udc.c | 5 +-
drivers/usb/host/Kconfig | 2 +-
drivers/usb/host/ohci-omap.c | 111 +-
drivers/usb/phy/Kconfig | 3 +-
drivers/usb/phy/phy-isp1301-omap.c | 6 +-
drivers/video/backlight/Kconfig | 4 +-
drivers/video/backlight/omap1_bl.c | 4 +-
drivers/video/fbdev/Makefile | 2 +-
drivers/video/fbdev/omap/Kconfig | 4 +-
drivers/video/fbdev/omap/Makefile | 5 +
drivers/video/fbdev/omap/lcd_ams_delta.c | 2 +-
.../video/fbdev/omap}/lcd_dma.c | 7 +-
.../video/fbdev/omap}/lcd_dma.h | 2 -
drivers/video/fbdev/omap/lcd_inn1510.c | 9 +-
drivers/video/fbdev/omap/lcd_osk.c | 4 +-
drivers/video/fbdev/omap/lcdc.c | 10 +-
drivers/video/fbdev/omap/lcdc.h | 35 +
drivers/video/fbdev/omap/omapfb.h | 2 +
drivers/video/fbdev/omap/omapfb_main.c | 19 +-
drivers/video/fbdev/omap/sossi.c | 4 +-
include/linux/omap-dma.h | 7 +-
include/linux/platform_data/keypad-omap.h | 5 -
include/linux/platform_data/usb-omap1.h | 4 +
include/linux/soc/ti/omap1-io.h | 143 ++
.../mux.h => include/linux/soc/ti/omap1-mux.h | 142 +-
.../soc.h => include/linux/soc/ti/omap1-soc.h | 22 -
.../usb.h => include/linux/soc/ti/omap1-usb.h | 28 +-
105 files changed, 1856 insertions(+), 2714 deletions(-)
delete mode 100644 arch/arm/mach-omap1/clock.h
delete mode 100644 arch/arm/mach-omap1/clock_data.c
rename arch/arm/mach-omap1/{include/mach => }/hardware.h (59%)
delete mode 100644 arch/arm/mach-omap1/include/mach/io.h
delete mode 100644 arch/arm/mach-omap1/include/mach/lcdc.h
delete mode 100644 arch/arm/mach-omap1/include/mach/memory.h
delete mode 100644 arch/arm/mach-omap1/include/mach/uncompress.h
rename arch/arm/mach-omap1/{include/mach => }/irqs.h (99%)
rename arch/arm/mach-omap1/{include/mach => }/mtd-xip.h (97%)
create mode 100644 arch/arm/mach-omap1/mux.h
rename arch/arm/mach-omap1/{include/mach => }/omap1510.h (99%)
rename arch/arm/mach-omap1/{include/mach => }/omap16xx.h (100%)
rename arch/arm/mach-omap1/{include/mach => }/omap7xx.h (100%)
delete mode 100644 arch/arm/mach-omap1/opp.h
delete mode 100644 arch/arm/mach-omap1/opp_data.c
rename arch/arm/mach-omap1/{include/mach => }/serial.h (100%)
create mode 100644 arch/arm/mach-omap1/usb.h
delete mode 100644 arch/arm/plat-omap/include/plat/cpu.h
rename {arch/arm/mach-omap1 => drivers/video/fbdev/omap}/lcd_dma.c (98%)
rename {arch/arm/mach-omap1/include/mach => drivers/video/fbdev/omap}/lcd_dma.h (98%)
create mode 100644 include/linux/soc/ti/omap1-io.h
rename arch/arm/mach-omap1/include/mach/mux.h => include/linux/soc/ti/omap1-mux.h (53%)
rename arch/arm/mach-omap1/include/mach/soc.h => include/linux/soc/ti/omap1-soc.h (90%)
rename arch/arm/mach-omap1/include/mach/usb.h => include/linux/soc/ti/omap1-usb.h (86%)
--
2.20.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox