* Patch "drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut()" has been added to the 4.14-stable tree
From: gregkh @ 2018-12-06 9:29 UTC (permalink / raw)
To: 20181125012117.31915-1-lyude, carlo, dri-devel, gregkh, khilman,
linux-amlogic, linux-arm-kernel, lyude, maxime.ripard, narmstrong,
seanpaul
Cc: stable-commits
This is a note to let you know that I've just added the patch titled
drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut()
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-meson-fix-oob-memory-accesses-in-meson_viu_set_osd_lut.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
From 97b2a3180a559a33852ac0cd77904166069484fd Mon Sep 17 00:00:00 2001
From: Lyude Paul <lyude@redhat.com>
Date: Sat, 24 Nov 2018 20:21:17 -0500
Subject: drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut()
From: Lyude Paul <lyude@redhat.com>
commit 97b2a3180a559a33852ac0cd77904166069484fd upstream.
Currently on driver bringup with KASAN enabled, meson triggers an OOB
memory access as shown below:
[ 117.904528] ==================================================================
[ 117.904560] BUG: KASAN: global-out-of-bounds in meson_viu_set_osd_lut+0x7a0/0x890
[ 117.904588] Read of size 4 at addr ffff20000a63ce24 by task systemd-udevd/498
[ 117.904601]
[ 118.083372] CPU: 4 PID: 498 Comm: systemd-udevd Not tainted 4.20.0-rc3Lyude-Test+ #20
[ 118.091143] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018
[ 118.099768] Call trace:
[ 118.102181] dump_backtrace+0x0/0x3e8
[ 118.105796] show_stack+0x14/0x20
[ 118.109083] dump_stack+0x130/0x1c4
[ 118.112539] print_address_description+0x60/0x25c
[ 118.117214] kasan_report+0x1b4/0x368
[ 118.120851] __asan_report_load4_noabort+0x18/0x20
[ 118.125566] meson_viu_set_osd_lut+0x7a0/0x890
[ 118.129953] meson_viu_init+0x10c/0x290
[ 118.133741] meson_drv_bind_master+0x474/0x748
[ 118.138141] meson_drv_bind+0x10/0x18
[ 118.141760] try_to_bring_up_master+0x3d8/0x768
[ 118.146249] component_add+0x214/0x570
[ 118.149978] meson_dw_hdmi_probe+0x18/0x20 [meson_dw_hdmi]
[ 118.155404] platform_drv_probe+0x98/0x138
[ 118.159455] really_probe+0x2a0/0xa70
[ 118.163070] driver_probe_device+0x1b4/0x2d8
[ 118.167299] __driver_attach+0x200/0x280
[ 118.171189] bus_for_each_dev+0x10c/0x1a8
[ 118.175144] driver_attach+0x38/0x50
[ 118.178681] bus_add_driver+0x330/0x608
[ 118.182471] driver_register+0x140/0x388
[ 118.186361] __platform_driver_register+0xc8/0x108
[ 118.191117] meson_dw_hdmi_platform_driver_init+0x1c/0x1000 [meson_dw_hdmi]
[ 118.198022] do_one_initcall+0x12c/0x3bc
[ 118.201883] do_init_module+0x1fc/0x638
[ 118.205673] load_module+0x4b4c/0x6808
[ 118.209387] __se_sys_init_module+0x2e8/0x3c0
[ 118.213699] __arm64_sys_init_module+0x68/0x98
[ 118.218100] el0_svc_common+0x104/0x210
[ 118.221893] el0_svc_handler+0x48/0xb8
[ 118.225594] el0_svc+0x8/0xc
[ 118.228429]
[ 118.229887] The buggy address belongs to the variable:
[ 118.235007] eotf_33_linear_mapping+0x84/0xc0
[ 118.239301]
[ 118.240752] Memory state around the buggy address:
[ 118.245522] ffff20000a63cd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 118.252695] ffff20000a63cd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 118.259850] >ffff20000a63ce00: 00 00 00 00 04 fa fa fa fa fa fa fa 00 00 00 00
[ 118.267000] ^
[ 118.271222] ffff20000a63ce80: 00 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
[ 118.278393] ffff20000a63cf00: 00 00 00 00 00 00 00 00 00 00 00 00 04 fa fa fa
[ 118.285542] ==================================================================
[ 118.292699] Disabling lock debugging due to kernel taint
It seems that when looping through the OSD EOTF LUT maps, we use the
same max iterator for OETF: 20. This is wrong though, since 20*2 is 40,
which means that we'll stop out of bounds on the EOTF maps.
But, this whole thing is already confusing enough to read through as-is,
so let's just replace all of the hardcoded sizes with
OSD_(OETF/EOTF)_LUT_SIZE / 2.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller")
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Carlo Caione <carlo@caione.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: <stable@vger.kernel.org> # v4.10+
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181125012117.31915-1-lyude@redhat.com
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/meson/meson_viu.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -184,18 +184,18 @@ void meson_viu_set_osd_lut(struct meson_
if (lut_sel == VIU_LUT_OSD_OETF) {
writel(0, priv->io_base + _REG(addr_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
@@ -211,18 +211,18 @@ void meson_viu_set_osd_lut(struct meson_
} else if (lut_sel == VIU_LUT_OSD_EOTF) {
writel(0, priv->io_base + _REG(addr_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
Patches currently in stable-queue which might be from lyude@redhat.com are
queue-4.14/drm-meson-enable-fast_io-in-meson_dw_hdmi_regmap_config.patch
queue-4.14/drm-meson-fix-oob-memory-accesses-in-meson_viu_set_osd_lut.patch
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: dmapool regression in next
From: Krzysztof Kozlowski @ 2018-12-06 9:25 UTC (permalink / raw)
To: tony
Cc: Stephen Rothwell, linux-kernel, john.garry, linux, hch,
andy.shevchenko, akpm, linux-omap, tonyb, linux-arm-kernel,
Marek Szyprowski
In-Reply-To: <20181206013054.GI6707@atomide.com>
On Thu, 6 Dec 2018 at 02:31, Tony Lindgren <tony@atomide.com> wrote:
>
> Hi,
>
> Looks like with commit 26abe88e830d ("mm/dmapool.c: improve scalability
> of dma_pool_free()") I'm now getting spammed with lots of "(bad vaddr)"
> on at least omap4 pandaboard, see below.
>
> Any ideas what might be going wrong?
>
> Regards,
>
> Tony
>
> 8< ---------------------
> omap-dma-engine 4a056000.dma-controller: dma_pool_free 4a056000.dma-controller, (ptrval) (bad vaddr)/0xbe800000
> omap-dma-engine 4a056000.dma-controller: dma_pool_free 4a056000.dma-controller, (ptrval) (bad vaddr)/0xbe80001c
> omap-dma-engine 4a056000.dma-controller: dma_pool_free 4a056000.dma-controller, (ptrval) (bad vaddr)/0xbe800038
> ...
I see it as well on all my Exynos boards, since yesterday's next. In
my case it is the USB EHCI driver:
exynos-ehci 12110000.usb: dma_pool_free ehci_qtd, (ptrval) (bad
vaddr)/0xb8844180
Full log here:
https://krzk.eu/#/builders/1/builds/2937/steps/12/logs/serial0
Best regards,
Krzysztof
_______________________________________________
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 v9 2/2] ThunderX2, perf : Add Cavium ThunderX2 SoC UNCORE PMU driver
From: Suzuki K Poulose @ 2018-12-06 9:24 UTC (permalink / raw)
To: Kulkarni, Ganapatrao, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Cc: mark.rutland@arm.com, Nair, Jayachandran, Jan Glauber,
gklkml16@gmail.com, rdunlap@infradead.org, Will.Deacon@arm.com,
Lomovtsev, Vadim, Richter, Robert
In-Reply-To: <20181205105853.15154-3-ganapatrao.kulkarni@cavium.com>
Hi Ganpat,
On 05/12/2018 10:59, Kulkarni, Ganapatrao wrote:
> This patch adds a perf driver for the PMU UNCORE devices DDR4 Memory
> Controller(DMC) and Level 3 Cache(L3C). Each PMU supports up to 4
> counters. All counters lack overflow interrupt and are
> sampled periodically.
>
> Signed-off-by: Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com>
> ---
> drivers/perf/Kconfig | 9 +
> drivers/perf/Makefile | 1 +
> drivers/perf/thunderx2_pmu.c | 861 +++++++++++++++++++++++++++++++++++
> include/linux/cpuhotplug.h | 1 +
> 4 files changed, 872 insertions(+)
> create mode 100644 drivers/perf/thunderx2_pmu.c
> --- /dev/null
> +++ b/drivers/perf/thunderx2_pmu.c
> @@ -0,0 +1,861 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * CAVIUM THUNDERX2 SoC PMU UNCORE
> + * Copyright (C) 2018 Cavium Inc.
> + * Author: Ganapatrao Kulkarni <gkulkarni@cavium.com>
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/cpuhotplug.h>
> +#include <linux/perf_event.h>
> +#include <linux/platform_device.h>
> +
> +/* Each ThunderX2(TX2) Socket has a L3C and DMC UNCORE PMU device.
> + * Each UNCORE PMU device consists of 4 independent programmable counters.
> + * Counters are 32 bit and do not support overflow interrupt,
> + * they need to be sampled before overflow(i.e, at every 2 seconds).
> + */
> +
> +#define TX2_PMU_MAX_COUNTERS 4
> +#define TX2_PMU_DMC_CHANNELS 8
> +#define TX2_PMU_L3_TILES 16
> +
> +#define TX2_PMU_HRTIMER_INTERVAL (2 * NSEC_PER_SEC)
> +#define GET_EVENTID(ev) ((ev->hw.config) & 0x1f)
> +#define GET_COUNTERID(ev) ((ev->hw.idx) & 0x3)
> + /* 1 byte per counter(4 counters).
> + * Event id is encoded in bits [5:1] of a byte,
> + */
> +#define DMC_EVENT_CFG(idx, val) ((val) << (((idx) * 8) + 1))
> +
> +#define L3C_COUNTER_CTL 0xA8
> +#define L3C_COUNTER_DATA 0xAC
> +#define DMC_COUNTER_CTL 0x234
> +#define DMC_COUNTER_DATA 0x240
> +
> +/* L3C event IDs */
> +#define L3_EVENT_READ_REQ 0xD
> +#define L3_EVENT_WRITEBACK_REQ 0xE
> +#define L3_EVENT_INV_N_WRITE_REQ 0xF
> +#define L3_EVENT_INV_REQ 0x10
> +#define L3_EVENT_EVICT_REQ 0x13
> +#define L3_EVENT_INV_N_WRITE_HIT 0x14
> +#define L3_EVENT_INV_HIT 0x15
> +#define L3_EVENT_READ_HIT 0x17
> +#define L3_EVENT_MAX 0x18
> +
> +/* DMC event IDs */
> +#define DMC_EVENT_COUNT_CYCLES 0x1
> +#define DMC_EVENT_WRITE_TXNS 0xB
> +#define DMC_EVENT_DATA_TRANSFERS 0xD
> +#define DMC_EVENT_READ_TXNS 0xF
> +#define DMC_EVENT_MAX 0x10
> +
> +enum tx2_uncore_type {
> + PMU_TYPE_L3C,
> + PMU_TYPE_DMC,
> + PMU_TYPE_INVALID,
> +};
> +
> +/*
> + * pmu on each socket has 2 uncore devices(dmc and l3c),
> + * each device has 4 counters.
> + */
> +struct tx2_uncore_pmu {
> + struct hlist_node hpnode;
> + struct list_head entry;
> + struct pmu pmu;
> + char *name;
> + int node;
> + int cpu;
> + u32 max_counters;
> + u32 prorate_factor;
> + u32 max_events;
> + u64 hrtimer_interval;
minor nit:
The alignment of the fields are pretty inconsistent. e.g,
u32 is followed by tabs and the rest are not. Please keep it
consistent.
> + void __iomem *base;
> + DECLARE_BITMAP(active_counters, TX2_PMU_MAX_COUNTERS);
> + struct perf_event *events[TX2_PMU_MAX_COUNTERS];
> + struct device *dev;
> + struct hrtimer hrtimer;
> + const struct attribute_group **attr_groups;
> + enum tx2_uncore_type type;
> + void (*init_cntr_base)(struct perf_event *event,
> + struct tx2_uncore_pmu *tx2_pmu);
> + void (*stop_event)(struct perf_event *event);
> + void (*start_event)(struct perf_event *event, int flags);
> +};
> +
> +static LIST_HEAD(tx2_pmus);
> +
> +static inline struct tx2_uncore_pmu *pmu_to_tx2_pmu(struct pmu *pmu)
> +{
> + return container_of(pmu, struct tx2_uncore_pmu, pmu);
> +}
> +
> +PMU_FORMAT_ATTR(event, "config:0-4");
> +
> +static struct attribute *l3c_pmu_format_attrs[] = {
> + &format_attr_event.attr,
> + NULL,
> +};
> +
> +static struct attribute *dmc_pmu_format_attrs[] = {
> + &format_attr_event.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group l3c_pmu_format_attr_group = {
> + .name = "format",
> + .attrs = l3c_pmu_format_attrs,
> +};
> +
> +static const struct attribute_group dmc_pmu_format_attr_group = {
> + .name = "format",
> + .attrs = dmc_pmu_format_attrs,
> +};
> +
> +/*
> + * sysfs event attributes
> + */
> +static ssize_t tx2_pmu_event_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct dev_ext_attribute *eattr;
> +
> + eattr = container_of(attr, struct dev_ext_attribute, attr);
> + return sprintf(buf, "event=0x%lx\n", (unsigned long) eattr->var);
> +}
> +
> +#define TX2_EVENT_ATTR(name, config) \
> + PMU_EVENT_ATTR(name, tx2_pmu_event_attr_##name, \
> + config, tx2_pmu_event_show)
> +
> +TX2_EVENT_ATTR(read_request, L3_EVENT_READ_REQ);
> +TX2_EVENT_ATTR(writeback_request, L3_EVENT_WRITEBACK_REQ);
> +TX2_EVENT_ATTR(inv_nwrite_request, L3_EVENT_INV_N_WRITE_REQ);
> +TX2_EVENT_ATTR(inv_request, L3_EVENT_INV_REQ);
> +TX2_EVENT_ATTR(evict_request, L3_EVENT_EVICT_REQ);
> +TX2_EVENT_ATTR(inv_nwrite_hit, L3_EVENT_INV_N_WRITE_HIT);
> +TX2_EVENT_ATTR(inv_hit, L3_EVENT_INV_HIT);
> +TX2_EVENT_ATTR(read_hit, L3_EVENT_READ_HIT);
> +
> +static struct attribute *l3c_pmu_events_attrs[] = {
> + &tx2_pmu_event_attr_read_request.attr.attr,
> + &tx2_pmu_event_attr_writeback_request.attr.attr,
> + &tx2_pmu_event_attr_inv_nwrite_request.attr.attr,
> + &tx2_pmu_event_attr_inv_request.attr.attr,
> + &tx2_pmu_event_attr_evict_request.attr.attr,
> + &tx2_pmu_event_attr_inv_nwrite_hit.attr.attr,
> + &tx2_pmu_event_attr_inv_hit.attr.attr,
> + &tx2_pmu_event_attr_read_hit.attr.attr,
> + NULL,
> +};
> +
> +TX2_EVENT_ATTR(cnt_cycles, DMC_EVENT_COUNT_CYCLES);
> +TX2_EVENT_ATTR(write_txns, DMC_EVENT_WRITE_TXNS);
> +TX2_EVENT_ATTR(data_transfers, DMC_EVENT_DATA_TRANSFERS);
> +TX2_EVENT_ATTR(read_txns, DMC_EVENT_READ_TXNS);
> +
> +static struct attribute *dmc_pmu_events_attrs[] = {
> + &tx2_pmu_event_attr_cnt_cycles.attr.attr,
> + &tx2_pmu_event_attr_write_txns.attr.attr,
> + &tx2_pmu_event_attr_data_transfers.attr.attr,
> + &tx2_pmu_event_attr_read_txns.attr.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group l3c_pmu_events_attr_group = {
> + .name = "events",
> + .attrs = l3c_pmu_events_attrs,
> +};
> +
> +static const struct attribute_group dmc_pmu_events_attr_group = {
> + .name = "events",
> + .attrs = dmc_pmu_events_attrs,
> +};
> +
> +/*
> + * sysfs cpumask attributes
> + */
> +static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> + char *buf)
> +{
> + struct tx2_uncore_pmu *tx2_pmu;
> +
> + tx2_pmu = pmu_to_tx2_pmu(dev_get_drvdata(dev));
> + return cpumap_print_to_pagebuf(true, buf, cpumask_of(tx2_pmu->cpu));
> +}
> +static DEVICE_ATTR_RO(cpumask);
> +
> +static struct attribute *tx2_pmu_cpumask_attrs[] = {
> + &dev_attr_cpumask.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group pmu_cpumask_attr_group = {
> + .attrs = tx2_pmu_cpumask_attrs,
> +};
> +
> +/*
> + * Per PMU device attribute groups
> + */
> +static const struct attribute_group *l3c_pmu_attr_groups[] = {
> + &l3c_pmu_format_attr_group,
> + &pmu_cpumask_attr_group,
> + &l3c_pmu_events_attr_group,
> + NULL
> +};
> +
> +static const struct attribute_group *dmc_pmu_attr_groups[] = {
> + &dmc_pmu_format_attr_group,
> + &pmu_cpumask_attr_group,
> + &dmc_pmu_events_attr_group,
> + NULL
> +};
> +
> +static inline u32 reg_readl(unsigned long addr)
> +{
> + return readl((void __iomem *)addr);
> +}
> +
> +static inline void reg_writel(u32 val, unsigned long addr)
> +{
> + writel(val, (void __iomem *)addr);
> +}
> +
> +static int alloc_counter(struct tx2_uncore_pmu *tx2_pmu)
> +{
> + int counter;
> +
> + counter = find_first_zero_bit(tx2_pmu->active_counters,
> + tx2_pmu->max_counters);
> + if (counter == tx2_pmu->max_counters)
> + return -ENOSPC;
> +
> + set_bit(counter, tx2_pmu->active_counters);
> + return counter;
> +}
> +
> +static inline void free_counter(struct tx2_uncore_pmu *tx2_pmu, int counter)
> +{
> + clear_bit(counter, tx2_pmu->active_counters);
> +}
> +
> +static void init_cntr_base_l3c(struct perf_event *event,
> + struct tx2_uncore_pmu *tx2_pmu)
> +{
> + struct hw_perf_event *hwc = &event->hw;
> +
> + /* counter ctrl/data reg offset at 8 */
> + hwc->config_base = (unsigned long)tx2_pmu->base
> + + L3C_COUNTER_CTL + (8 * GET_COUNTERID(event));
> + hwc->event_base = (unsigned long)tx2_pmu->base
> + + L3C_COUNTER_DATA + (8 * GET_COUNTERID(event));
> +}
> +
> +static void init_cntr_base_dmc(struct perf_event *event,
> + struct tx2_uncore_pmu *tx2_pmu)
> +{
> + struct hw_perf_event *hwc = &event->hw;
> +
> + hwc->config_base = (unsigned long)tx2_pmu->base
> + + DMC_COUNTER_CTL;
> + /* counter data reg offset at 0xc */
> + hwc->event_base = (unsigned long)tx2_pmu->base
> + + DMC_COUNTER_DATA + (0xc * GET_COUNTERID(event));
> +}
> +
> +static void uncore_start_event_l3c(struct perf_event *event, int flags)
> +{
> + u32 val;
> + struct hw_perf_event *hwc = &event->hw;
> +
> + /* event id encoded in bits [07:03] */
> + val = GET_EVENTID(event) << 3;
> + reg_writel(val, hwc->config_base);
> + local64_set(&hwc->prev_count, 0);
> + reg_writel(0, hwc->event_base);
> +}
> +
> +static inline void uncore_stop_event_l3c(struct perf_event *event)
> +{
> + reg_writel(0, event->hw.config_base);
> +}
> +
> +static void uncore_start_event_dmc(struct perf_event *event, int flags)
> +{
> + u32 val;
> + struct hw_perf_event *hwc = &event->hw;
> + int idx = GET_COUNTERID(event);
> + int event_id = GET_EVENTID(event);
> +
> + /* enable and start counters.
> + * 8 bits for each counter, bits[05:01] of a counter to set event type.
> + */
> + val = reg_readl(hwc->config_base);
> + val &= ~DMC_EVENT_CFG(idx, 0x1f);
> + val |= DMC_EVENT_CFG(idx, event_id);
> + reg_writel(val, hwc->config_base);
> + local64_set(&hwc->prev_count, 0);
> + reg_writel(0, hwc->event_base);
> +}
> +
> +static void uncore_stop_event_dmc(struct perf_event *event)
> +{
> + u32 val;
> + struct hw_perf_event *hwc = &event->hw;
> + int idx = GET_COUNTERID(event);
> +
> + /* clear event type(bits[05:01]) to stop counter */
> + val = reg_readl(hwc->config_base);
> + val &= ~DMC_EVENT_CFG(idx, 0x1f);
> + reg_writel(val, hwc->config_base);
> +}
> +
> +static void tx2_uncore_event_update(struct perf_event *event)
> +{
> + s64 prev, delta, new = 0;
> + struct hw_perf_event *hwc = &event->hw;
> + struct tx2_uncore_pmu *tx2_pmu;
> + enum tx2_uncore_type type;
> + u32 prorate_factor;
> +
> + tx2_pmu = pmu_to_tx2_pmu(event->pmu);
> + type = tx2_pmu->type;
> + prorate_factor = tx2_pmu->prorate_factor;
> +
> + new = reg_readl(hwc->event_base);
> + prev = local64_xchg(&hwc->prev_count, new);
> +
> + /* handles rollover of 32 bit counter */
> + delta = (u32)(((1UL << 32) - prev) + new);
> +
> + /* DMC event data_transfers granularity is 16 Bytes, convert it to 64 */
> + if (type == PMU_TYPE_DMC &&
> + GET_EVENTID(event) == DMC_EVENT_DATA_TRANSFERS)
> + delta = delta/4;
> +
> + /* L3C and DMC has 16 and 8 interleave channels respectively.
> + * The sampled value is for channel 0 and multiplied with
> + * prorate_factor to get the count for a device.
> + */
> + local64_add(delta * prorate_factor, &event->count);
> +}
> +
> +enum tx2_uncore_type get_tx2_pmu_type(struct acpi_device *adev)
> +{
> + int i = 0;
> + struct acpi_tx2_pmu_device {
> + __u8 id[ACPI_ID_LEN];
> + enum tx2_uncore_type type;
> + } devices[] = {
> + {"CAV901D", PMU_TYPE_L3C},
> + {"CAV901F", PMU_TYPE_DMC},
> + {"", PMU_TYPE_INVALID}
> + };
> +
> + while (devices[i].type != PMU_TYPE_INVALID) {
> + if (!strcmp(acpi_device_hid(adev), devices[i].id))
> + break;
> + i++;
> + }
> +
> + return devices[i].type;
> +}
> +
> +static bool tx2_uncore_validate_event(struct pmu *pmu,
> + struct perf_event *event, int *counters)
> +{
> + if (is_software_event(event))
> + return true;
> + /* Reject groups spanning multiple HW PMUs. */
> + if (event->pmu != pmu)
> + return false;
> +
> + *counters = *counters + 1;
> + return true;
nit: alignment.
Otherwise looks good to me.
FWIW, with the above nits fixed:
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.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 v5 1/5] spi: spi-mem: Add driver for NXP FlexSPI controller
From: Schrempf Frieder @ 2018-12-06 9:22 UTC (permalink / raw)
To: Yogesh Narayan Gaur, linux-mtd@lists.infradead.org,
boris.brezillon@bootlin.com, marek.vasut@gmail.com,
broonie@kernel.org, linux-spi@vger.kernel.org,
devicetree@vger.kernel.org
Cc: mark.rutland@arm.com, robh@kernel.org,
linux-kernel@vger.kernel.org, computersforpeace@gmail.com,
shawnguo@kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <1542366701-16065-2-git-send-email-yogeshnarayan.gaur@nxp.com>
Hi Yogesh,
I've had a closer look at your v5. See my comments below.
On 16.11.18 12:13, Yogesh Narayan Gaur wrote:
> - Add driver for NXP FlexSPI host controller
>
> (0) What is the FlexSPI controller?
> FlexSPI is a flexsible SPI host controller which supports two SPI
> channels and up to 4 external devices. Each channel supports
> Single/Dual/Quad/Octal mode data transfer (1/2/4/8 bidirectional
> data lines) i.e. FlexSPI acts as an interface to external devices,
> maximum 4, each with up to 8 bidirectional data lines.
>
> It uses new SPI memory interface of the SPI framework to issue
> flash memory operations to up to four connected flash
> devices (2 buses with 2 CS each).
>
> (1) Tested this driver with the mtd_debug and JFFS2 filesystem utility
> on NXP LX2160ARDB and LX2160AQDS targets.
> LX2160ARDB is having two NOR slave device connected on single bus A
> i.e. A0 and A1 (CS0 and CS1).
> LX2160AQDS is having two NOR slave device connected on separate buses
> one flash on A0 and second on B1 i.e. (CS0 and CS3).
> Verified this driver on following SPI NOR flashes:
> Micron, mt35xu512ab, [Read - 1 bit mode]
> Cypress, s25fl512s, [Read - 1/2/4 bit mode]
>
> Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur@nxp.com>
> ---
> Changes for v5:
> - Rebase on top of v4.20-rc2
> - Modified fspi_readl_poll_tout() as per review comments
> - Arrange header file in alphabetical order
> - Removed usage of read()/write() function callback pointer
> - Add support for 1 and 2 byte address length
> - Change Frieder e-mail to new e-mail address
> Changes for v4:
> - Incorporate Boris review comments
> * Use readl_poll_timeout() instead of busy looping.
> * Re-define register masking as per comment.
> * Drop fspi_devtype enum.
> Changes for v3:
> - Added endianness flag in platform specific structure instead of DTS.
> - Modified nxp_fspi_read_ahb(), removed remapping code.
> - Added Boris and Frieder as Author and provided reference of spi-fsl-qspi.c
> Changes for v2:
> - Incorporated Boris review comments.
> - Remove dependency of driver over connected flash device size.
> - Modified the logic to select requested CS.
> - Remove SPI-Octal Macros.
>
> drivers/spi/Kconfig | 10 +
> drivers/spi/Makefile | 1 +
> drivers/spi/spi-nxp-fspi.c | 1145 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 1156 insertions(+)
> create mode 100644 drivers/spi/spi-nxp-fspi.c
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 7d3a5c9..36630a1 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -259,6 +259,16 @@ config SPI_FSL_LPSPI
> help
> This enables Freescale i.MX LPSPI controllers in master mode.
>
> +config SPI_NXP_FLEXSPI
> + tristate "NXP Flex SPI controller"
> + depends on ARCH_LAYERSCAPE || HAS_IOMEM
> + help
> + This enables support for the Flex SPI controller in master mode.
> + Up to four slave devices can be connected on two buses with two
> + chipselects each.
> + This controller does not support generic SPI messages and only
> + supports the high-level SPI memory interface.
> +
> config SPI_GPIO
> tristate "GPIO-based bitbanging SPI Master"
> depends on GPIOLIB || COMPILE_TEST
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 3575205..55fec5c 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -60,6 +60,7 @@ obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
> obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
> obj-$(CONFIG_SPI_MXS) += spi-mxs.o
> obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
> +obj-$(CONFIG_SPI_NXP_FLEXSPI) += spi-nxp-fspi.o
> obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
> spi-octeon-objs := spi-cavium.o spi-cavium-octeon.o
> obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
> diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> new file mode 100644
> index 0000000..a35013b
> --- /dev/null
> +++ b/drivers/spi/spi-nxp-fspi.c
> @@ -0,0 +1,1145 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * NXP FlexSPI(FSPI) controller driver.
> + *
> + * Copyright 2018 NXP.
> + *
> + * FlexSPI is a flexsible SPI host controller which supports two SPI
> + * channels and up to 4 external devices. Each channel supports
> + * Single/Dual/Quad/Octal mode data transfer (1/2/4/8 bidirectional
> + * data lines).
> + *
> + * FlexSPI controller is driven by the LUT(Look-up Table) registers
> + * LUT registers are a look-up-table for sequences of instructions.
> + * A valid sequence consists of four LUT registers.
> + * Maximum 32 LUT sequences can be programmed simultaneously.
> + *
> + * LUTs are being created at run-time based on the commands passed
> + * from the spi-mem framework, thus using single LUT index.
> + *
> + * Software triggered Flash read/write access by IP Bus.
> + *
> + * Memory mapped read access by AHB Bus.
> + *
> + * Based on SPI MEM interface and spi-fsl-qspi.c driver.
> + *
> + * Author:
> + * Yogesh Gaur <yogeshnarayan.gaur@nxp.com>
> + * Boris Brezillion <boris.brezillon@bootlin.com>
> + * Frieder Schrempf <frieder.schrempf@kontron.de>
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/completion.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/jiffies.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_qos.h>
> +#include <linux/sizes.h>
> +
> +#include <linux/spi/spi.h>
> +#include <linux/spi/spi-mem.h>
> +
> +/*
> + * The driver only uses one single LUT entry, that is updated on
> + * each call of exec_op(). Index 0 is preset at boot with a basic
> + * read operation, so let's use the last entry (31).
> + */
> +#define SEQID_LUT 31
> +
> +/* Registers used by the driver */
> +#define FSPI_MCR0 0x00
> +#define FSPI_MCR0_AHB_TIMEOUT(x) ((x) << 24)
> +#define FSPI_MCR0_IP_TIMEOUT(x) ((x) << 16)
> +#define FSPI_MCR0_LEARN_EN BIT(15)
> +#define FSPI_MCR0_SCRFRUN_EN BIT(14)
> +#define FSPI_MCR0_OCTCOMB_EN BIT(13)
> +#define FSPI_MCR0_DOZE_EN BIT(12)
> +#define FSPI_MCR0_HSEN BIT(11)
> +#define FSPI_MCR0_SERCLKDIV BIT(8)
> +#define FSPI_MCR0_ATDF_EN BIT(7)
> +#define FSPI_MCR0_ARDF_EN BIT(6)
> +#define FSPI_MCR0_RXCLKSRC(x) ((x) << 4)
> +#define FSPI_MCR0_END_CFG(x) ((x) << 2)
> +#define FSPI_MCR0_MDIS BIT(1)
> +#define FSPI_MCR0_SWRST BIT(0)
> +
> +#define FSPI_MCR1 0x04
> +#define FSPI_MCR1_SEQ_TIMEOUT(x) ((x) << 16)
> +#define FSPI_MCR1_AHB_TIMEOUT(x) (x)
> +
> +#define FSPI_MCR2 0x08
> +#define FSPI_MCR2_IDLE_WAIT(x) ((x) << 24)
> +#define FSPI_MCR2_SAMEDEVICEEN BIT(15)
> +#define FSPI_MCR2_CLRLRPHS BIT(14)
> +#define FSPI_MCR2_ABRDATSZ BIT(8)
> +#define FSPI_MCR2_ABRLEARN BIT(7)
> +#define FSPI_MCR2_ABR_READ BIT(6)
> +#define FSPI_MCR2_ABRWRITE BIT(5)
> +#define FSPI_MCR2_ABRDUMMY BIT(4)
> +#define FSPI_MCR2_ABR_MODE BIT(3)
> +#define FSPI_MCR2_ABRCADDR BIT(2)
> +#define FSPI_MCR2_ABRRADDR BIT(1)
> +#define FSPI_MCR2_ABR_CMD BIT(0)
> +
> +#define FSPI_AHBCR 0x0c
> +#define FSPI_AHBCR_RDADDROPT BIT(6)
> +#define FSPI_AHBCR_PREF_EN BIT(5)
> +#define FSPI_AHBCR_BUFF_EN BIT(4)
> +#define FSPI_AHBCR_CACH_EN BIT(3)
> +#define FSPI_AHBCR_CLRTXBUF BIT(2)
> +#define FSPI_AHBCR_CLRRXBUF BIT(1)
> +#define FSPI_AHBCR_PAR_EN BIT(0)
> +
> +#define FSPI_INTEN 0x10
> +#define FSPI_INTEN_SCLKSBWR BIT(9)
> +#define FSPI_INTEN_SCLKSBRD BIT(8)
> +#define FSPI_INTEN_DATALRNFL BIT(7)
> +#define FSPI_INTEN_IPTXWE BIT(6)
> +#define FSPI_INTEN_IPRXWA BIT(5)
> +#define FSPI_INTEN_AHBCMDERR BIT(4)
> +#define FSPI_INTEN_IPCMDERR BIT(3)
> +#define FSPI_INTEN_AHBCMDGE BIT(2)
> +#define FSPI_INTEN_IPCMDGE BIT(1)
> +#define FSPI_INTEN_IPCMDDONE BIT(0)
> +
> +#define FSPI_INTR 0x14
> +#define FSPI_INTR_SCLKSBWR BIT(9)
> +#define FSPI_INTR_SCLKSBRD BIT(8)
> +#define FSPI_INTR_DATALRNFL BIT(7)
> +#define FSPI_INTR_IPTXWE BIT(6)
> +#define FSPI_INTR_IPRXWA BIT(5)
> +#define FSPI_INTR_AHBCMDERR BIT(4)
> +#define FSPI_INTR_IPCMDERR BIT(3)
> +#define FSPI_INTR_AHBCMDGE BIT(2)
> +#define FSPI_INTR_IPCMDGE BIT(1)
> +#define FSPI_INTR_IPCMDDONE BIT(0)
> +
> +#define FSPI_LUTKEY 0x18
> +#define FSPI_LUTKEY_VALUE 0x5AF05AF0
> +
> +#define FSPI_LCKCR 0x1C
> +
> +#define FSPI_LCKER_LOCK 0x1
> +#define FSPI_LCKER_UNLOCK 0x2
> +
> +#define FSPI_BUFXCR_INVALID_MSTRID 0xE
> +#define FSPI_AHBRX_BUF0CR0 0x20
> +#define FSPI_AHBRX_BUF1CR0 0x24
> +#define FSPI_AHBRX_BUF2CR0 0x28
> +#define FSPI_AHBRX_BUF3CR0 0x2C
> +#define FSPI_AHBRX_BUF4CR0 0x30
> +#define FSPI_AHBRX_BUF5CR0 0x34
> +#define FSPI_AHBRX_BUF6CR0 0x38
> +#define FSPI_AHBRX_BUF7CR0 0x3C
> +#define FSPI_AHBRXBUF0CR7_PREF BIT(31)
> +
> +#define FSPI_AHBRX_BUF0CR1 0x40
> +#define FSPI_AHBRX_BUF1CR1 0x44
> +#define FSPI_AHBRX_BUF2CR1 0x48
> +#define FSPI_AHBRX_BUF3CR1 0x4C
> +#define FSPI_AHBRX_BUF4CR1 0x50
> +#define FSPI_AHBRX_BUF5CR1 0x54
> +#define FSPI_AHBRX_BUF6CR1 0x58
> +#define FSPI_AHBRX_BUF7CR1 0x5C
> +
> +#define FSPI_FLSHA1CR0 0x60
> +#define FSPI_FLSHA2CR0 0x64
> +#define FSPI_FLSHB1CR0 0x68
> +#define FSPI_FLSHB2CR0 0x6C
> +#define FSPI_FLSHXCR0_SZ_KB 10
> +#define FSPI_FLSHXCR0_SZ(x) ((x) >> FSPI_FLSHXCR0_SZ_KB)
> +
> +#define FSPI_FLSHA1CR1 0x70
> +#define FSPI_FLSHA2CR1 0x74
> +#define FSPI_FLSHB1CR1 0x78
> +#define FSPI_FLSHB2CR1 0x7C
> +#define FSPI_FLSHXCR1_CSINTR(x) ((x) << 16)
> +#define FSPI_FLSHXCR1_CAS(x) ((x) << 11)
> +#define FSPI_FLSHXCR1_WA BIT(10)
> +#define FSPI_FLSHXCR1_TCSH(x) ((x) << 5)
> +#define FSPI_FLSHXCR1_TCSS(x) (x)
> +
> +#define FSPI_FLSHA1CR2 0x80
> +#define FSPI_FLSHA2CR2 0x84
> +#define FSPI_FLSHB1CR2 0x88
> +#define FSPI_FLSHB2CR2 0x8C
> +#define FSPI_FLSHXCR2_CLRINSP BIT(24)
> +#define FSPI_FLSHXCR2_AWRWAIT BIT(16)
> +#define FSPI_FLSHXCR2_AWRSEQN_SHIFT 13
> +#define FSPI_FLSHXCR2_AWRSEQI_SHIFT 8
> +#define FSPI_FLSHXCR2_ARDSEQN_SHIFT 5
> +#define FSPI_FLSHXCR2_ARDSEQI_SHIFT 0
> +
> +#define FSPI_IPCR0 0xA0
> +
> +#define FSPI_IPCR1 0xA4
> +#define FSPI_IPCR1_IPAREN BIT(31)
> +#define FSPI_IPCR1_SEQNUM_SHIFT 24
> +#define FSPI_IPCR1_SEQID_SHIFT 16
> +#define FSPI_IPCR1_IDATSZ(x) (x)
> +
> +#define FSPI_IPCMD 0xB0
> +#define FSPI_IPCMD_TRG BIT(0)
> +
> +#define FSPI_DLPR 0xB4
> +
> +#define FSPI_IPRXFCR 0xB8
> +#define FSPI_IPRXFCR_CLR BIT(0)
> +#define FSPI_IPRXFCR_DMA_EN BIT(1)
> +#define FSPI_IPRXFCR_WMRK(x) ((x) << 2)
> +
> +#define FSPI_IPTXFCR 0xBC
> +#define FSPI_IPTXFCR_CLR BIT(0)
> +#define FSPI_IPTXFCR_DMA_EN BIT(1)
> +#define FSPI_IPTXFCR_WMRK(x) ((x) << 2)
> +
> +#define FSPI_DLLACR 0xC0
> +#define FSPI_DLLACR_OVRDEN BIT(8)
> +
> +#define FSPI_DLLBCR 0xC4
> +#define FSPI_DLLBCR_OVRDEN BIT(8)
> +
> +#define FSPI_STS0 0xE0
> +#define FSPI_STS0_DLPHB(x) ((x) << 8)
> +#define FSPI_STS0_DLPHA(x) ((x) << 4)
> +#define FSPI_STS0_CMD_SRC(x) ((x) << 2)
> +#define FSPI_STS0_ARB_IDLE BIT(1)
> +#define FSPI_STS0_SEQ_IDLE BIT(0)
> +
> +#define FSPI_STS1 0xE4
> +#define FSPI_STS1_IP_ERRCD(x) ((x) << 24)
> +#define FSPI_STS1_IP_ERRID(x) ((x) << 16)
> +#define FSPI_STS1_AHB_ERRCD(x) ((x) << 8)
> +#define FSPI_STS1_AHB_ERRID(x) (x)
> +
> +#define FSPI_AHBSPNST 0xEC
> +#define FSPI_AHBSPNST_DATLFT(x) ((x) << 16)
> +#define FSPI_AHBSPNST_BUFID(x) ((x) << 1)
> +#define FSPI_AHBSPNST_ACTIVE BIT(0)
> +
> +#define FSPI_IPRXFSTS 0xF0
> +#define FSPI_IPRXFSTS_RDCNTR(x) ((x) << 16)
> +#define FSPI_IPRXFSTS_FILL(x) (x)
> +
> +#define FSPI_IPTXFSTS 0xF4
> +#define FSPI_IPTXFSTS_WRCNTR(x) ((x) << 16)
> +#define FSPI_IPTXFSTS_FILL(x) (x)
> +
> +#define FSPI_RFDR 0x100
> +#define FSPI_TFDR 0x180
> +
> +#define FSPI_LUT_BASE 0x200
> +#define FSPI_LUT_OFFSET (SEQID_LUT * 4 * 4)
> +#define FSPI_LUT_REG(idx) \
> + (FSPI_LUT_BASE + FSPI_LUT_OFFSET + (idx) * 4)
> +
> +/* register map end */
> +
> +/* Instruction set for the LUT register. */
> +#define LUT_STOP 0x00
> +#define LUT_CMD 0x01
> +#define LUT_ADDR 0x02
> +#define LUT_CADDR_SDR 0x03
> +#define LUT_MODE 0x04
> +#define LUT_MODE2 0x05
> +#define LUT_MODE4 0x06
> +#define LUT_MODE8 0x07
> +#define LUT_NXP_WRITE 0x08
> +#define LUT_NXP_READ 0x09
> +#define LUT_LEARN_SDR 0x0A
> +#define LUT_DATSZ_SDR 0x0B
> +#define LUT_DUMMY 0x0C
> +#define LUT_DUMMY_RWDS_SDR 0x0D
> +#define LUT_JMP_ON_CS 0x1F
> +#define LUT_CMD_DDR 0x21
> +#define LUT_ADDR_DDR 0x22
> +#define LUT_CADDR_DDR 0x23
> +#define LUT_MODE_DDR 0x24
> +#define LUT_MODE2_DDR 0x25
> +#define LUT_MODE4_DDR 0x26
> +#define LUT_MODE8_DDR 0x27
> +#define LUT_WRITE_DDR 0x28
> +#define LUT_READ_DDR 0x29
> +#define LUT_LEARN_DDR 0x2A
> +#define LUT_DATSZ_DDR 0x2B
> +#define LUT_DUMMY_DDR 0x2C
> +#define LUT_DUMMY_RWDS_DDR 0x2D
> +
> +/*
> + * Calculate number of required PAD bits for LUT register.
> + *
> + * The pad stands for the number of IO lines [0:7].
> + * For example, the octal read needs eight IO lines,
> + * so you should use LUT_PAD(8). This macro
> + * returns 3 i.e. use eight (2^3) IP lines for read.
> + */
> +#define LUT_PAD(x) (fls(x) - 1)
> +
> +/*
> + * Macro for constructing the LUT entries with the following
> + * register layout:
> + *
> + * ---------------------------------------------------
> + * | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 |
> + * ---------------------------------------------------
> + */
> +#define PAD_SHIFT 8
> +#define INSTR_SHIFT 10
> +#define OPRND_SHIFT 16
> +
> +/* Macros for constructing the LUT register. */
> +#define LUT_DEF(idx, ins, pad, opr) \
> + ((((ins) << INSTR_SHIFT) | ((pad) << PAD_SHIFT) | \
> + (opr)) << (((idx) % 2) * OPRND_SHIFT))
> +
> +/* Operands for the LUT register. */
> +#define ADDR8BIT 0x08
> +#define ADDR16BIT 0x10
> +#define ADDR24BIT 0x18
> +#define ADDR32BIT 0x20
You can drop these ADDRXBIT definitions, see below...
> +
> +#define POLL_TOUT 5000
> +#define NXP_FSPI_MAX_CHIPSELECT 4
> +
> +struct nxp_fspi_devtype_data {
> + unsigned int rxfifo;
> + unsigned int txfifo;
> + unsigned int ahb_buf_size;
> + unsigned int quirks;
> + bool little_endian;
> +};
> +
> +static const struct nxp_fspi_devtype_data lx2160a_data = {
> + .rxfifo = SZ_512, /* (64 * 64 bits) */
> + .txfifo = SZ_1K, /* (128 * 64 bits) */
> + .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */
> + .quirks = 0,
> + .little_endian = true, /* little-endian */
> +};
> +
> +struct nxp_fspi {
> + void __iomem *iobase;
> + void __iomem *ahb_addr;
> + u32 memmap_phy;
> + u32 memmap_phy_size;
> + struct clk *clk, *clk_en;
> + struct device *dev;
> + struct completion c;
> + const struct nxp_fspi_devtype_data *devtype_data;
> + struct mutex lock;
> + struct pm_qos_request pm_qos_req;
> + int selected;
> +};
> +
> +/*
> + * R/W functions for big- or little-endian registers:
> + * The FSPI controller's endianness is independent of
> + * the CPU core's endianness. So far, although the CPU
> + * core is little-endian the FSPI controller can use
> + * big-endian or little-endian.
> + */
> +static void fspi_writel(struct nxp_fspi *f, u32 val, void __iomem *addr)
> +{
> + if (f->devtype_data->little_endian)
> + iowrite32(val, addr);
> + else
> + iowrite32be(val, addr);
> +}
> +
> +static u32 fspi_readl(struct nxp_fspi *f, void __iomem *addr)
> +{
> + if (f->devtype_data->little_endian)
> + return ioread32(addr);
> + else
> + return ioread32be(addr);
> +}
> +
> +static irqreturn_t nxp_fspi_irq_handler(int irq, void *dev_id)
> +{
> + struct nxp_fspi *f = dev_id;
> + u32 reg;
> +
> + /* clear interrupt */
> + reg = fspi_readl(f, f->iobase + FSPI_INTR);
> + fspi_writel(f, FSPI_INTR_IPCMDDONE, f->iobase + FSPI_INTR);
> +
> + if (reg & FSPI_INTR_IPCMDDONE)
> + complete(&f->c);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int nxp_fspi_check_buswidth(struct nxp_fspi *f, u8 width)
> +{
> + switch (width) {
> + case 1:
> + case 2:
> + case 4:
> + case 8:
> + return 0;
> + }
> +
> + return -ENOTSUPP;
> +}
> +
> +static bool nxp_fspi_supports_op(struct spi_mem *mem,
> + const struct spi_mem_op *op)
> +{
> + struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master);
> + int ret;
> +
> + ret = nxp_fspi_check_buswidth(f, op->cmd.buswidth);
> +
> + if (op->addr.nbytes)
> + ret |= nxp_fspi_check_buswidth(f, op->addr.buswidth);
> +
> + if (op->dummy.nbytes)
> + ret |= nxp_fspi_check_buswidth(f, op->dummy.buswidth);
> +
> + if (op->data.nbytes)
> + ret |= nxp_fspi_check_buswidth(f, op->data.buswidth);
> +
> + if (ret)
> + return false;
> +
> + /*
> + * The number of instructions needed for the op, needs
> + * to fit into a single LUT entry.
> + */
> + if (op->addr.nbytes +
> + (op->dummy.nbytes ? 1:0) +
> + (op->data.nbytes ? 1:0) > 6)
> + return false;
> +
> + /* Max 64 dummy clock cycles supported */
> + if (op->dummy.buswidth &&
> + (op->dummy.nbytes * 8 / op->dummy.buswidth > 64))
> + return false;
> +
> + /* Max data length, check controller limits and alignment */
> + if (op->data.dir == SPI_MEM_DATA_IN &&
> + (op->data.nbytes > f->devtype_data->ahb_buf_size ||
> + (op->data.nbytes > f->devtype_data->rxfifo - 4 &&
> + !IS_ALIGNED(op->data.nbytes, 8))))
> + return false;
> +
> + if (op->data.dir == SPI_MEM_DATA_OUT &&
> + op->data.nbytes > f->devtype_data->txfifo)
> + return false;
> +
> + return true;
> +}
> +
> +/* Instead of busy looping invoke readl_poll_timeout functionality. */
> +static int fspi_readl_poll_tout(struct nxp_fspi *f, void __iomem *base,
> + u32 mask, u32 delay_us,
> + u32 timeout_us, bool condition)
> +{
> + u32 reg;
> +
> + if (!f->devtype_data->little_endian)
> + mask = (u32)cpu_to_be32(mask);
> +
> + if (condition)
> + return readl_poll_timeout(base, reg, (reg & mask),
> + delay_us, timeout_us);
> + else
> + return readl_poll_timeout(base, reg, !(reg & mask),
> + delay_us, timeout_us);
I would rather use a local variable to store the condition:
bool c = condition ? (reg & mask):!(reg & mask);
return readl_poll_timeout(base, reg, c, delay_us, timeout_us);
> +}
> +
> +/*
> + * If the slave device content being changed by Write/Erase, need to
> + * invalidate the AHB buffer. This can be achieved by doing the reset
> + * of controller after setting MCR0[SWRESET] bit.
> + */
> +static inline void nxp_fspi_invalid(struct nxp_fspi *f)
> +{
> + u32 reg;
> + int ret;
> +
> + reg = fspi_readl(f, f->iobase + FSPI_MCR0);
> + fspi_writel(f, reg | FSPI_MCR0_SWRST, f->iobase + FSPI_MCR0);
> +
> + /* w1c register, wait unit clear */
> + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0,
> + FSPI_MCR0_SWRST, 0, POLL_TOUT, false);
> + WARN_ON(ret);
> +}
> +
> +static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
> + const struct spi_mem_op *op)
> +{
> + void __iomem *base = f->iobase;
> + u32 lutval[4] = {};
> + int lutidx = 1, i;
> +
> + /* cmd */
> + lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth),
> + op->cmd.opcode);
> +
> + /* addr bus width */
> + if (op->addr.nbytes) {
> + u32 addrlen = 0;
> +
> + switch (op->addr.nbytes) {
> + case 1:
> + addrlen = ADDR8BIT;
> + break;
> + case 2:
> + addrlen = ADDR16BIT;
> + break;
> + case 3:
> + addrlen = ADDR24BIT;
> + break;
> + case 4:
> + addrlen = ADDR32BIT;
> + break;
> + default:
> + dev_err(f->dev, "In-correct address length\n");
> + return;
> + }
You don't need to validate op->addr.nbytes here, this is already done in
nxp_fspi_supports_op().
> +
> + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR,
> + LUT_PAD(op->addr.buswidth),
> + addrlen);
You can also just remove the whole switch statement above and use this:
lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR,
LUT_PAD(op->addr.buswidth),
op->addr.nbytes * 8);
> + lutidx++;
> + }
> +
> + /* dummy bytes, if needed */
> + if (op->dummy.nbytes) {
> + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_DUMMY,
> + /*
> + * Due to FlexSPI controller limitation number of PAD for dummy
> + * buswidth needs to be programmed as equal to data buswidth.
> + */
> + LUT_PAD(op->data.buswidth),
> + op->dummy.nbytes * 8 /
> + op->dummy.buswidth);
> + lutidx++;
> + }
> +
> + /* read/write data bytes */
> + if (op->data.nbytes) {
> + lutval[lutidx / 2] |= LUT_DEF(lutidx,
> + op->data.dir == SPI_MEM_DATA_IN ?
> + LUT_NXP_READ : LUT_NXP_WRITE,
> + LUT_PAD(op->data.buswidth),
> + 0);
> + lutidx++;
> + }
> +
> + /* stop condition. */
> + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_STOP, 0, 0);
> +
> + /* unlock LUT */
> + fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY);
> + fspi_writel(f, FSPI_LCKER_UNLOCK, f->iobase + FSPI_LCKCR);
> +
> + /* fill LUT */
> + for (i = 0; i < ARRAY_SIZE(lutval); i++)
> + fspi_writel(f, lutval[i], base + FSPI_LUT_REG(i));
> +
> + dev_dbg(f->dev, "CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x]\n",
> + op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3]);
> +
> + /* lock LUT */
> + fspi_writel(f, FSPI_LUTKEY_VALUE, f->iobase + FSPI_LUTKEY);
> + fspi_writel(f, FSPI_LCKER_LOCK, f->iobase + FSPI_LCKCR);
> +}
> +
> +static int nxp_fspi_clk_prep_enable(struct nxp_fspi *f)
> +{
> + int ret;
> +
> + ret = clk_prepare_enable(f->clk_en);
> + if (ret)
> + return ret;
> +
> + ret = clk_prepare_enable(f->clk);
> + if (ret) {
> + clk_disable_unprepare(f->clk_en);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void nxp_fspi_clk_disable_unprep(struct nxp_fspi *f)
> +{
> + clk_disable_unprepare(f->clk);
> + clk_disable_unprepare(f->clk_en);
> +}
> +
> +/*
> + * In FlexSPI controller, flash access is based on value of FSPI_FLSHXXCR0
> + * register and start base address of the slave device.
> + *
> + * (Higher address)
> + * -------- <-- FLSHB2CR0
> + * | B2 |
> + * | |
> + * B2 start address --> -------- <-- FLSHB1CR0
> + * | B1 |
> + * | |
> + * B1 start address --> -------- <-- FLSHA2CR0
> + * | A2 |
> + * | |
> + * A2 start address --> -------- <-- FLSHA1CR0
> + * | A1 |
> + * | |
> + * A1 start address --> -------- (Lower address)
> + *
> + *
> + * Start base address defines the starting address range for given CS and
> + * FSPI_FLSHXXCR0 defines the size of the slave device connected at given CS.
> + *
> + * But, different targets are having different combinations of number of CS,
> + * some targets only have single CS or two CS covering controller's full
> + * memory mapped space area.
> + * Thus, implementation is being done as independent of the size and number
> + * of the connected slave device.
> + * Assign controller memory mapped space size as the size to the connected
> + * slave device.
> + * Mark FLSHxxCR0 as zero initially and then assign value only to the selected
> + * chip-select Flash configuration register.
> + *
> + * For e.g. to access CS2 (B1), FLSHB1CR0 register would be equal to the
> + * memory mapped size of the controller.
> + * Value for rest of the CS FLSHxxCR0 register would be zero.
> + *
> + */
> +static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
> +{
> + unsigned long rate = spi->max_speed_hz;
> + int ret;
> + uint64_t size_kb;
> +
> + /*
> + * Return, if previously selected slave device is same as current
> + * requested slave device.
> + */
> + if (f->selected == spi->chip_select)
> + return;
> +
> + /* Reset FLSHxxCR0 registers */
> + fspi_writel(f, 0, f->iobase + FSPI_FLSHA1CR0);
> + fspi_writel(f, 0, f->iobase + FSPI_FLSHA2CR0);
> + fspi_writel(f, 0, f->iobase + FSPI_FLSHB1CR0);
> + fspi_writel(f, 0, f->iobase + FSPI_FLSHB2CR0);
> +
> + /* Assign controller memory mapped space as size, KBytes, of flash. */
> + size_kb = FSPI_FLSHXCR0_SZ(f->memmap_phy_size);
You are still using memory of arbitrary size (memmap_phy_size) for
mapping the flash. Why not use the same approach as in the QSPI driver
and just map ahb_buf_size until we implement the dirmap API?
You are already aligning the AHB reads for this in
nxp_fspi_adjust_op_size().
> +
> + switch (spi->chip_select) {
> + case 0:
> + fspi_writel(f, size_kb, f->iobase + FSPI_FLSHA1CR0);
> + break;
> + case 1:
> + fspi_writel(f, size_kb, f->iobase + FSPI_FLSHA2CR0);
> + break;
> + case 2:
> + fspi_writel(f, size_kb, f->iobase + FSPI_FLSHB1CR0);
> + break;
> + case 3:
> + fspi_writel(f, size_kb, f->iobase + FSPI_FLSHB2CR0);
> + break;
> + default:
> + dev_err(f->dev, "In-correct CS provided\n");
> + return;
You don't need to validate spi->chip_select here. This should never be
invalid and if it is, something is really wrong and your check won't help.
> + }
> +
> + dev_dbg(f->dev, "Slave device [CS:%x] selected\n", spi->chip_select);
> +
> + nxp_fspi_clk_disable_unprep(f);
> +
> + ret = clk_set_rate(f->clk, rate);
> + if (ret)
> + return;
> +
> + ret = nxp_fspi_clk_prep_enable(f);
> + if (ret)
> + return;
Missing newline line here.
> + f->selected = spi->chip_select;
> +}
> +
> +static void nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op)
> +{
> + u32 len = op->data.nbytes;
> +
> + /* Read out the data directly from the AHB buffer. */
> + memcpy_fromio(op->data.buf.in, (f->ahb_addr + op->addr.val), len);
> +}
> +
> +static void nxp_fspi_fill_txfifo(struct nxp_fspi *f,
> + const struct spi_mem_op *op)
> +{
> + void __iomem *base = f->iobase;
> + int i, j, ret;
> + int size, tmp_size, wm_size;
> + u32 data = 0;
> + u32 *txbuf = (u32 *) op->data.buf.out;
> +
> + /* clear the TX FIFO. */
> + fspi_writel(f, FSPI_IPTXFCR_CLR, base + FSPI_IPTXFCR);
> +
> + /* Default value of water mark level is 8 bytes. */
> + wm_size = 8;
> + size = op->data.nbytes / wm_size;
> + for (i = 0; i < size; i++) {
> + /* Wait for TXFIFO empty */
> + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR,
> + FSPI_INTR_IPTXWE, 0,
> + POLL_TOUT, true);
> + WARN_ON(ret);
> +
> + j = 0;
> + tmp_size = wm_size;
> + while (tmp_size > 0) {
> + data = 0;
> + memcpy(&data, txbuf, 4);
> + fspi_writel(f, data, base + FSPI_TFDR + j * 4);
> + tmp_size -= 4;
> + j++;
> + txbuf += 1;
> + }
> + fspi_writel(f, FSPI_INTR_IPTXWE, base + FSPI_INTR);
> + }
> +
> + size = op->data.nbytes % wm_size;
> + if (size) {
> + /* Wait for TXFIFO empty */
> + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR,
> + FSPI_INTR_IPTXWE, 0,
> + POLL_TOUT, true);
> + WARN_ON(ret);
> +
> + j = 0;
> + tmp_size = 0;
> + while (size > 0) {
> + data = 0;
> + tmp_size = (size < 4) ? size : 4;
> + memcpy(&data, txbuf, tmp_size);
> + fspi_writel(f, data, base + FSPI_TFDR + j * 4);
> + size -= tmp_size;
> + j++;
> + txbuf += 1;
> + }
> + fspi_writel(f, FSPI_INTR_IPTXWE, base + FSPI_INTR);
> + }
All these nested loops to fill the TX buffer and also the ones below to
read the RX buffer look much more complicated than they should really
be. Can you try to make this more readable?
Maybe something like this would work:
for (i = 0; i < ALIGN_DOWN(op->data.nbytes, 8); i += 8) {
/* Wait for TXFIFO empty */
ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR,
FSPI_INTR_IPTXWE, 0,
POLL_TOUT, true);
fspi_writel(f, op->data.buf.out + i, base + FSPI_TFDR);
fspi_writel(f, op->data.buf.out + i + 4, base + FSPI_TFDR + 4);
fspi_writel(f, FSPI_INTR_IPTXWE, base + FSPI_INTR);
}
if (i < op->data.nbytes) {
u32 data = 0;
int j;
/* Wait for TXFIFO empty */
ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR,
FSPI_INTR_IPTXWE, 0,
POLL_TOUT, true);
for (j = 0; j < ALIGN(op->data.nbytes - i, 4); j += 4) {
memcpy(&data, op->data.buf.out + i + j, 4);
fspi_writel(f, data, base + FSPI_TFDR + j);
}
fspi_writel(f, FSPI_INTR_IPTXWE, base + FSPI_INTR);
}
> +}
> +
> +static void nxp_fspi_read_rxfifo(struct nxp_fspi *f,
> + const struct spi_mem_op *op)
> +{
> + void __iomem *base = f->iobase;
> + int i, j;
> + int size, tmp_size, wm_size, ret;
> + u32 tmp = 0;
> + u8 *buf = op->data.buf.in;
> + u32 len = op->data.nbytes;
> +
> + /* Default value of water mark level is 8 bytes. */
> + wm_size = 8;
> +
> + while (len > 0) {
> + size = len / wm_size;
> +
> + for (i = 0; i < size; i++) {
> + /* Wait for RXFIFO available */
> + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR,
> + FSPI_INTR_IPRXWA, 0,
> + POLL_TOUT, true);
> + WARN_ON(ret);
> +
> + j = 0;
> + tmp_size = wm_size;
> + while (tmp_size > 0) {
> + tmp = 0;
> + tmp = fspi_readl(f, base + FSPI_RFDR + j * 4);
> + memcpy(buf, &tmp, 4);
> + tmp_size -= 4;
> + j++;
> + buf += 4;
> + }
> + /* move the FIFO pointer */
> + fspi_writel(f, FSPI_INTR_IPRXWA, base + FSPI_INTR);
> + len -= wm_size;
> + }
> +
> + size = len % wm_size;
> +
> + j = 0;
> + if (size) {
> + /* Wait for RXFIFO available */
> + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR,
> + FSPI_INTR_IPRXWA, 0,
> + POLL_TOUT, true);
> + WARN_ON(ret);
> +
> + while (len > 0) {
> + tmp = 0;
> + size = (len < 4) ? len : 4;
> + tmp = fspi_readl(f, base + FSPI_RFDR + j * 4);
> + memcpy(buf, &tmp, size);
> + len -= size;
> + j++;
> + buf += size;
> + }
> + }
> +
> + /* invalid the RXFIFO */
> + fspi_writel(f, FSPI_IPRXFCR_CLR, base + FSPI_IPRXFCR);
> + /* move the FIFO pointer */
> + fspi_writel(f, FSPI_INTR_IPRXWA, base + FSPI_INTR);
> + }
Same here. I think this is overly complicated.
> +}
> +
> +static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op)
> +{
> + void __iomem *base = f->iobase;
> + int seqnum = 0;
> + int err = 0;
> + u32 reg;
> +
> + reg = fspi_readl(f, base + FSPI_IPRXFCR);
> + /* invalid RXFIFO first */
> + reg &= ~FSPI_IPRXFCR_DMA_EN;
> + reg = reg | FSPI_IPRXFCR_CLR;
> + fspi_writel(f, reg, base + FSPI_IPRXFCR);
> +
> + init_completion(&f->c);
> +
> + fspi_writel(f, op->addr.val, base + FSPI_IPCR0);
> + /*
> + * Always start the sequence at the same index since we update
> + * the LUT at each exec_op() call. And also specify the DATA
> + * length, since it's has not been specified in the LUT.
> + */
> + fspi_writel(f, op->data.nbytes |
> + (SEQID_LUT << FSPI_IPCR1_SEQID_SHIFT) |
> + (seqnum << FSPI_IPCR1_SEQNUM_SHIFT),
> + base + FSPI_IPCR1);
> +
> + /* Trigger the LUT now. */
> + fspi_writel(f, FSPI_IPCMD_TRG, base + FSPI_IPCMD);
> +
> + /* Wait for the interrupt. */
> + if (!wait_for_completion_timeout(&f->c, msecs_to_jiffies(1000)))
> + err = -ETIMEDOUT;
> +
> + /* Invoke IP data read, if request is of data read. */
> + if (!err && op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN)
> + nxp_fspi_read_rxfifo(f, op);
> +
> + return err;
> +}
> +
> +static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
> +{
> + struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master);
> + int err = 0;
> +
> + mutex_lock(&f->lock);
> +
> + /* Wait for controller being ready. */
> + err = fspi_readl_poll_tout(f, f->iobase + FSPI_STS0,
> + FSPI_STS0_ARB_IDLE, 1, POLL_TOUT, true);
> + WARN_ON(err);
> +
> + nxp_fspi_select_mem(f, mem->spi);
> +
> + nxp_fspi_prepare_lut(f, op);
> + /*
> + * If we have large chunks of data, we read them through the AHB bus
> + * by accessing the mapped memory. In all other cases we use
> + * IP commands to access the flash.
> + */
> + if (op->data.nbytes > (f->devtype_data->rxfifo - 4) &&
> + op->data.dir == SPI_MEM_DATA_IN) {
> + nxp_fspi_read_ahb(f, op);
> + } else {
> + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
> + nxp_fspi_fill_txfifo(f, op);
> +
> + err = nxp_fspi_do_op(f, op);
> +
> + /* Invalidate the data in the AHB buffer. */
> + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
> + nxp_fspi_invalid(f);
E.g. in case of an erase operation or a NAND load page operation, the
invalidation is not triggered, but flash/buffer contents have changed.
So I'm not sure if this is enough...
> + }
> +
> + mutex_unlock(&f->lock);
> +
> + return err;
> +}
> +
> +static int nxp_fspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
> +{
> + struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master);
> +
> + if (op->data.dir == SPI_MEM_DATA_OUT) {
> + if (op->data.nbytes > f->devtype_data->txfifo)
> + op->data.nbytes = f->devtype_data->txfifo;
> + } else {
> + if (op->data.nbytes > f->devtype_data->ahb_buf_size)
> + op->data.nbytes = f->devtype_data->ahb_buf_size;
> + else if (op->data.nbytes > (f->devtype_data->rxfifo - 4))
> + op->data.nbytes = ALIGN_DOWN(op->data.nbytes, 8);
You are using the same alignments as in the QSPI driver. So AHB reads
will happen in portions of ahb_buf_size, but you dont' stick to this
when you map the memory. See above.
Regards,
Frieder
> + }
> +
> + return 0;
> +}
> +
> +static int nxp_fspi_default_setup(struct nxp_fspi *f)
> +{
> + void __iomem *base = f->iobase;
> + int ret, i;
> + u32 reg;
> +
> + /* disable and unprepare clock to avoid glitch pass to controller */
> + nxp_fspi_clk_disable_unprep(f);
> +
> + /* the default frequency, we will change it later if necessary. */
> + ret = clk_set_rate(f->clk, 20000000);
> + if (ret)
> + return ret;
> +
> + ret = nxp_fspi_clk_prep_enable(f);
> + if (ret)
> + return ret;
> +
> + /* Reset the module */
> + /* w1c register, wait unit clear */
> + ret = fspi_readl_poll_tout(f, f->iobase + FSPI_MCR0,
> + FSPI_MCR0_SWRST, 0, POLL_TOUT, false);
> + WARN_ON(ret);
> +
> + /* Disable the module */
> + fspi_writel(f, FSPI_MCR0_MDIS, base + FSPI_MCR0);
> +
> + /* Reset the DLL register to default value */
> + fspi_writel(f, FSPI_DLLACR_OVRDEN, base + FSPI_DLLACR);
> + fspi_writel(f, FSPI_DLLBCR_OVRDEN, base + FSPI_DLLBCR);
> +
> + /* enable module */
> + fspi_writel(f, FSPI_MCR0_AHB_TIMEOUT(0xFF) | FSPI_MCR0_IP_TIMEOUT(0xFF),
> + base + FSPI_MCR0);
> +
> + /*
> + * Disable same device enable bit and configure all slave devices
> + * independently.
> + */
> + reg = fspi_readl(f, f->iobase + FSPI_MCR2);
> + reg = reg & ~(FSPI_MCR2_SAMEDEVICEEN);
> + fspi_writel(f, reg, base + FSPI_MCR2);
> +
> + /* AHB configuration for access buffer 0~7. */
> + for (i = 0; i < 7; i++)
> + fspi_writel(f, 0, base + FSPI_AHBRX_BUF0CR0 + 4 * i);
> +
> + /*
> + * Set ADATSZ with the maximum AHB buffer size to improve the read
> + * performance.
> + */
> + fspi_writel(f, (f->devtype_data->ahb_buf_size / 8 |
> + FSPI_AHBRXBUF0CR7_PREF), base + FSPI_AHBRX_BUF7CR0);
> +
> + /* prefetch and no start address alignment limitation */
> + fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT,
> + base + FSPI_AHBCR);
> +
> + /* AHB Read - Set lut sequence ID for all CS. */
> + fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2);
> + fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2);
> + fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB1CR2);
> + fspi_writel(f, SEQID_LUT, base + FSPI_FLSHB2CR2);
> +
> + f->selected = -1;
> +
> + /* enable the interrupt */
> + fspi_writel(f, FSPI_INTEN_IPCMDDONE, base + FSPI_INTEN);
> +
> + return 0;
> +}
> +
> +static const struct spi_controller_mem_ops nxp_fspi_mem_ops = {
> + .adjust_op_size = nxp_fspi_adjust_op_size,
> + .supports_op = nxp_fspi_supports_op,
> + .exec_op = nxp_fspi_exec_op,
> +};
> +
> +static int nxp_fspi_probe(struct platform_device *pdev)
> +{
> + struct spi_controller *ctlr;
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct resource *res;
> + struct nxp_fspi *f;
> + int ret;
> +
> + ctlr = spi_alloc_master(&pdev->dev, sizeof(*f));
> + if (!ctlr)
> + return -ENOMEM;
> +
> + ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD |
> + SPI_TX_DUAL | SPI_TX_QUAD;
> +
> + f = spi_controller_get_devdata(ctlr);
> + f->dev = dev;
> + f->devtype_data = of_device_get_match_data(dev);
> + if (!f->devtype_data) {
> + ret = -ENODEV;
> + goto err_put_ctrl;
> + }
> +
> + platform_set_drvdata(pdev, f);
> +
> + /* find the resources - configuration register address space */
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_base");
> + f->iobase = devm_ioremap_resource(dev, res);
> + if (IS_ERR(f->iobase)) {
> + ret = PTR_ERR(f->iobase);
> + goto err_put_ctrl;
> + }
> +
> + /* find the resources - controller memory mapped space */
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_mmap");
> + f->ahb_addr = devm_ioremap_resource(dev, res);
> + if (IS_ERR(f->ahb_addr)) {
> + ret = PTR_ERR(f->ahb_addr);
> + goto err_put_ctrl;
> + }
> +
> + /* assign memory mapped starting address and mapped size. */
> + f->memmap_phy = res->start;
> + f->memmap_phy_size = resource_size(res);
> +
> + /* find the clocks */
> + f->clk_en = devm_clk_get(dev, "fspi_en");
> + if (IS_ERR(f->clk_en)) {
> + ret = PTR_ERR(f->clk_en);
> + goto err_put_ctrl;
> + }
> +
> + f->clk = devm_clk_get(dev, "fspi");
> + if (IS_ERR(f->clk)) {
> + ret = PTR_ERR(f->clk);
> + goto err_put_ctrl;
> + }
> +
> + ret = nxp_fspi_clk_prep_enable(f);
> + if (ret) {
> + dev_err(dev, "can not enable the clock\n");
> + goto err_put_ctrl;
> + }
> +
> + /* find the irq */
> + ret = platform_get_irq(pdev, 0);
> + if (ret < 0) {
> + dev_err(dev, "failed to get the irq: %d\n", ret);
> + goto err_disable_clk;
> + }
> +
> + ret = devm_request_irq(dev, ret,
> + nxp_fspi_irq_handler, 0, pdev->name, f);
> + if (ret) {
> + dev_err(dev, "failed to request irq: %d\n", ret);
> + goto err_disable_clk;
> + }
> +
> + mutex_init(&f->lock);
> +
> + ctlr->bus_num = -1;
> + ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;
> + ctlr->mem_ops = &nxp_fspi_mem_ops;
> +
> + nxp_fspi_default_setup(f);
> +
> + ctlr->dev.of_node = np;
> +
> + ret = spi_register_controller(ctlr);
> + if (ret)
> + goto err_destroy_mutex;
> +
> + return 0;
> +
> +err_destroy_mutex:
> + mutex_destroy(&f->lock);
> +
> +err_disable_clk:
> + nxp_fspi_clk_disable_unprep(f);
> +
> +err_put_ctrl:
> + spi_controller_put(ctlr);
> +
> + dev_err(dev, "NXP FSPI probe failed\n");
> + return ret;
> +}
> +
> +static int nxp_fspi_remove(struct platform_device *pdev)
> +{
> + struct nxp_fspi *f = platform_get_drvdata(pdev);
> +
> + /* disable the hardware */
> + fspi_writel(f, FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0);
> +
> + nxp_fspi_clk_disable_unprep(f);
> +
> + mutex_destroy(&f->lock);
> +
> + return 0;
> +}
> +
> +static int nxp_fspi_suspend(struct device *dev)
> +{
> + return 0;
> +}
> +
> +static int nxp_fspi_resume(struct device *dev)
> +{
> + struct nxp_fspi *f = dev_get_drvdata(dev);
> +
> + nxp_fspi_default_setup(f);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id nxp_fspi_dt_ids[] = {
> + { .compatible = "nxp,lx2160a-fspi", .data = (void *)&lx2160a_data, },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids);
> +
> +static const struct dev_pm_ops nxp_fspi_pm_ops = {
> + .suspend = nxp_fspi_suspend,
> + .resume = nxp_fspi_resume,
> +};
> +
> +static struct platform_driver nxp_fspi_driver = {
> + .driver = {
> + .name = "nxp-fspi",
> + .of_match_table = nxp_fspi_dt_ids,
> + .pm = &nxp_fspi_pm_ops,
> + },
> + .probe = nxp_fspi_probe,
> + .remove = nxp_fspi_remove,
> +};
> +module_platform_driver(nxp_fspi_driver);
> +
> +MODULE_DESCRIPTION("NXP FSPI Controller Driver");
> +MODULE_AUTHOR("NXP Semiconductor");
> +MODULE_LICENSE("GPL v2");
>
_______________________________________________
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] ARM: dts: exynos: Add proper regulator states for suspend-to-mem for odroid-u3
From: Marek Szyprowski @ 2018-12-06 9:18 UTC (permalink / raw)
To: Anand Moon, Krzysztof Kozlowski
Cc: Mark Rutland, devicetree, linux-samsung-soc,
Bartlomiej Zolnierkiewicz, Linux Kernel, Rob Herring, Kukjin Kim,
linux-arm-kernel
In-Reply-To: <ee0d71cd-a3e0-fbb0-3af8-0ecca1d53ec0@samsung.com>
Hi All,
On 2018-12-06 09:25, Marek Szyprowski wrote:
> On 2018-12-05 17:11, Anand Moon wrote:
>> On Wed, 5 Dec 2018 at 19:36, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>> On Tue, 4 Dec 2018 at 20:40, Anand Moon <linux.amoon@gmail.com> wrote:
>>>> Add suspend-to-mem node to regulator core to be enabled or disabled
>>>> during system suspend and also support changing the regulator operating
>>>> mode during runtime and when the system enter sleep mode.
>>>>
>>>> Signed-off-by: Anand Moon <linux.amoon@gmail.com>
>>>> ---
>>>> Tested on Odroid U3+
>>>>
>>>> ...
>> Well I have tested this patch as following
>> with only one issue, before enable suspend number of On-line cpu is 4
>> after resume number of On-line cpu is 1.
> This seems to be a regression in v4.20-rc1, not related to dts changes
> at all. I'm investigating this now...
Okay, I mixed kernel versions a bit. To be precise, this regression is
between v4.20-rc2 and v4.20-rc3. Bisecting pointed commit 383fb3ee8024
("ARM: spectre-v2: per-CPU vtables to work around big.Little systems").
I will post a bug report about the regression.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
_______________________________________________
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 v10 21/27] drivers: firmware: psci: Add a helper to attach a CPU to its PM domain
From: Ulf Hansson @ 2018-12-06 9:15 UTC (permalink / raw)
To: Lina Iyer
Cc: Mark Rutland, Lorenzo Pieralisi, Vincent Guittot,
Geert Uytterhoeven, Linux PM, Stephen Boyd, Viresh Kumar,
linux-arm-msm, Daniel Lezcano, Rafael J. Wysocki, Kevin Hilman,
Linux Kernel Mailing List, Tony Lindgren, Sudeep Holla,
Raju P.L.S.S.S.N, Linux ARM
In-Reply-To: <20181204184553.GO18262@codeaurora.org>
On Tue, 4 Dec 2018 at 19:45, Lina Iyer <ilina@codeaurora.org> wrote:
>
> On Thu, Nov 29 2018 at 10:50 -0700, Ulf Hansson wrote:
> >Introduce a new PSCI DT helper function, psci_dt_attach_cpu(), which takes
> >a CPU number as an in-parameter and attaches the CPU's struct device to its
> >corresponding PM domain. Additionally, the helper prepares the CPU to be
> >power managed via runtime PM, which is the last step needed to enable the
> >interaction with the PM domain through the runtime PM callbacks.
> >
> >Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> >---
> >
> >Changes in v10:
> > - New patch: Replaces "PM / Domains: Add helper functions to
> > attach/detach CPUs to/from genpd".
> >
> >---
> > drivers/firmware/psci/psci.h | 1 +
> > drivers/firmware/psci/psci_pm_domain.c | 19 +++++++++++++++++++
> > 2 files changed, 20 insertions(+)
> >
> >diff --git a/drivers/firmware/psci/psci.h b/drivers/firmware/psci/psci.h
> >index 05af462cc96e..fbc9980dee69 100644
> >--- a/drivers/firmware/psci/psci.h
> >+++ b/drivers/firmware/psci/psci.h
> >@@ -15,6 +15,7 @@ int psci_dt_parse_state_node(struct device_node *np, u32 *state);
> > int psci_dt_init_pm_domains(struct device_node *np);
> > int psci_dt_pm_domains_parse_states(struct cpuidle_driver *drv,
> > struct device_node *cpu_node, u32 *psci_states);
> >+int psci_dt_attach_cpu(int cpu);
> > #else
> > static inline int psci_dt_init_pm_domains(struct device_node *np) { return 0; }
> > #endif
> >diff --git a/drivers/firmware/psci/psci_pm_domain.c b/drivers/firmware/psci/psci_pm_domain.c
> >index 6c9d6a644c7f..b0fa7da8a0ce 100644
> >--- a/drivers/firmware/psci/psci_pm_domain.c
> >+++ b/drivers/firmware/psci/psci_pm_domain.c
> >@@ -12,8 +12,10 @@
> > #include <linux/device.h>
> > #include <linux/kernel.h>
> > #include <linux/pm_domain.h>
> >+#include <linux/pm_runtime.h>
> > #include <linux/slab.h>
> > #include <linux/string.h>
> >+#include <linux/cpu.h>
> > #include <linux/cpuidle.h>
> > #include <linux/cpu_pm.h>
> >
> >@@ -367,4 +369,21 @@ int psci_dt_pm_domains_parse_states(struct cpuidle_driver *drv,
> >
> > return 0;
> > }
> >+
> >+int psci_dt_attach_cpu(int cpu)
> >+{
> >+ struct device *dev = get_cpu_device(cpu);
> >+ int ret;
> >+
> >+ ret = dev_pm_domain_attach(dev, true);
> >+ if (ret)
> >+ return ret;
> >+
> >+ pm_runtime_irq_safe(dev);
> >+ pm_runtime_get_noresume(dev);
> >+ pm_runtime_set_active(dev);
> You would want to set this only if the CPU is online. Otherwise we will
> not power down the domain, if the CPU was never brought online.
Nice catch!
The platforms I tested this series on brings all their CPUs online
during boot, hence I haven't observed the problem.
I will post a new version soon to address the problem. Again, thanks
for your review!
[...]
Kind regards
Uffe
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] thermal: stm32: read factory settings properly
From: David HERNANDEZ SANCHEZ @ 2018-12-06 9:12 UTC (permalink / raw)
To: Zhang Rui, Eduardo Valentin, Daniel Lezcano, Rob Herring,
Mark Rutland, Maxime Coquelin, Alexandre TORGUE
Cc: devicetree@vger.kernel.org,
linux-stm32@st-md-mailman.stormreply.com,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org
Call stm_thermal_read_factory_settings once
internal peripheral is properly clocked.
To avoid wrong initialization of fmt0
(stm_thermal_sensor struct) member add
brackets properly.
Change-Id: I150d00fd50e382df04bfad12f0653b1ed6a1db1b
Signed-off-by: David Hernandez Sanchez <david.hernandezsanchez@st.com>
diff --git a/drivers/thermal/st/stm_thermal.c b/drivers/thermal/st/stm_thermal.c
index 47623da..bbd73c5 100644
--- a/drivers/thermal/st/stm_thermal.c
+++ b/drivers/thermal/st/stm_thermal.c
@@ -241,8 +241,8 @@ static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor)
sensor->t0 = TS1_T0_VAL1;
/* Retrieve fmt0 and put it on Hz */
- sensor->fmt0 = ADJUST * readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET)
- & TS1_FMT0_MASK;
+ sensor->fmt0 = ADJUST * (readl_relaxed(sensor->base +
+ DTS_T0VALR1_OFFSET) & TS1_FMT0_MASK);
/* Retrieve ramp coefficient */
sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) &
@@ -532,6 +532,10 @@ static int stm_thermal_prepare(struct stm_thermal_sensor *sensor)
if (ret)
return ret;
+ ret = stm_thermal_read_factory_settings(sensor);
+ if (ret)
+ goto thermal_unprepare;
+
ret = stm_thermal_calibration(sensor);
if (ret)
goto thermal_unprepare;
@@ -636,10 +640,6 @@ static int stm_thermal_probe(struct platform_device *pdev)
/* Populate sensor */
sensor->base = base;
- ret = stm_thermal_read_factory_settings(sensor);
- if (ret)
- return ret;
-
sensor->clk = devm_clk_get(&pdev->dev, "pclk");
if (IS_ERR(sensor->clk)) {
dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
--
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 v4 0/4] Add support of STM32 hwspinlock
From: Benjamin Gaignard @ 2018-12-06 9:10 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Ohad Ben Cohen, Mark Rutland, Alexandre Torgue, devicetree,
linux-remoteproc, Linux Kernel Mailing List, Rob Herring,
linux-stm32, Linux ARM
In-Reply-To: <20181206011045.GA23336@builder>
Le jeu. 6 déc. 2018 à 02:12, Bjorn Andersson
<bjorn.andersson@linaro.org> a écrit :
>
> On Fri 30 Nov 06:45 PST 2018, Benjamin Gaignard wrote:
>
> > Le mer. 14 nov. 2018 ą 10:00, Benjamin Gaignard
> > <benjamin.gaignard@linaro.org> a écrit :
> > >
> > > This serie adds the support of the hardware semaphore block for stm32mp1 SoC.
> > >
> > > version 4:
> > > - add Linaro SoB
> >
> > Gentle ping on this series
> >
>
> Sorry about that Benjamin, I was convinced that I picked your patches
> already. Applied first two patches to hwspinlock tree.
Thanks.
>
> I expect the dts update to go through the ST tree, and I guess the
> complaint from 0day tells us they already are?
Yes I will send fixed dts patches for stm32 tree
>
> Regards,
> Bjorn
_______________________________________________
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] media: Use of_node_name_eq for node name comparisons
From: Laurent Pinchart @ 2018-12-06 9:06 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree, linux-samsung-soc, Hyun Kwon, linux-kernel,
Krzysztof Kozlowski, Michal Simek, Benoit Parrot, Kyungmin Park,
Kukjin Kim, Sylwester Nawrocki, Mauro Carvalho Chehab,
linux-arm-kernel, linux-media
In-Reply-To: <20181205195050.4759-13-robh@kernel.org>
Hi Rob,
Thank you for the patch.
On Wednesday, 5 December 2018 21:50:29 EET Rob Herring wrote:
> Convert string compares of DT node names to use of_node_name_eq helper
> instead. This removes direct access to the node name pointer.
>
> Cc: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: Kukjin Kim <kgene@kernel.org>
> Cc: Krzysztof Kozlowski <krzk@kernel.org>
> Cc: Benoit Parrot <bparrot@ti.com>
> Cc: Hyun Kwon <hyun.kwon@xilinx.com>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Michal Simek <michal.simek@xilinx.com>
> Cc: linux-media@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-samsung-soc@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> drivers/media/platform/exynos4-is/media-dev.c | 12 ++++++------
> drivers/media/platform/ti-vpe/cal.c | 4 ++--
> drivers/media/platform/xilinx/xilinx-tpg.c | 2 +-
> drivers/media/v4l2-core/v4l2-fwnode.c | 6 ++----
> 4 files changed, 11 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/media/platform/exynos4-is/media-dev.c
> b/drivers/media/platform/exynos4-is/media-dev.c index
> 870501b0f351..ced14af56606 100644
> --- a/drivers/media/platform/exynos4-is/media-dev.c
> +++ b/drivers/media/platform/exynos4-is/media-dev.c
> @@ -445,7 +445,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
> */
> np = of_get_parent(rem);
>
> - if (np && !of_node_cmp(np->name, "i2c-isp"))
> + if (of_node_name_eq(np, "i2c-isp"))
> pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
> else
> pd->fimc_bus_type = pd->sensor_bus_type;
> @@ -495,7 +495,7 @@ static int fimc_md_register_sensor_entities(struct
> fimc_md *fmd) for_each_available_child_of_node(parent, node) {
> struct device_node *port;
>
> - if (of_node_cmp(node->name, "csis"))
> + if (!of_node_name_eq(node, "csis"))
> continue;
> /* The csis node can have only port subnode. */
> port = of_get_next_child(node, NULL);
> @@ -720,13 +720,13 @@ static int fimc_md_register_platform_entities(struct
> fimc_md *fmd, continue;
>
> /* If driver of any entity isn't ready try all again later. */
> - if (!strcmp(node->name, CSIS_OF_NODE_NAME))
> + if (of_node_name_eq(node, CSIS_OF_NODE_NAME))
> plat_entity = IDX_CSIS;
> - else if (!strcmp(node->name, FIMC_IS_OF_NODE_NAME))
> + else if (of_node_name_eq(node, FIMC_IS_OF_NODE_NAME))
You might want to s/if\t/if / while at it.
> plat_entity = IDX_IS_ISP;
> - else if (!strcmp(node->name, FIMC_LITE_OF_NODE_NAME))
> + else if (of_node_name_eq(node, FIMC_LITE_OF_NODE_NAME))
> plat_entity = IDX_FLITE;
> - else if (!strcmp(node->name, FIMC_OF_NODE_NAME) &&
> + else if (of_node_name_eq(node, FIMC_OF_NODE_NAME) &&
And here too.
Apart from that,
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> !of_property_read_bool(node, "samsung,lcd-wb"))
> plat_entity = IDX_FIMC;
>
> diff --git a/drivers/media/platform/ti-vpe/cal.c
> b/drivers/media/platform/ti-vpe/cal.c index 95a093f41905..fc3c212b96e1
> 100644
> --- a/drivers/media/platform/ti-vpe/cal.c
> +++ b/drivers/media/platform/ti-vpe/cal.c
> @@ -1615,7 +1615,7 @@ of_get_next_port(const struct device_node *parent,
> return NULL;
> }
> prev = port;
> - } while (of_node_cmp(port->name, "port") != 0);
> + } while (!of_node_name_eq(port, "port"));
> }
>
> return port;
> @@ -1635,7 +1635,7 @@ of_get_next_endpoint(const struct device_node *parent,
> if (!ep)
> return NULL;
> prev = ep;
> - } while (of_node_cmp(ep->name, "endpoint") != 0);
> + } while (!of_node_name_eq(ep, "endpoint"));
>
> return ep;
> }
> diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c
> b/drivers/media/platform/xilinx/xilinx-tpg.c index
> 851d20dcd550..ce686b8d6cff 100644
> --- a/drivers/media/platform/xilinx/xilinx-tpg.c
> +++ b/drivers/media/platform/xilinx/xilinx-tpg.c
> @@ -725,7 +725,7 @@ static int xtpg_parse_of(struct xtpg_device *xtpg)
> const struct xvip_video_format *format;
> struct device_node *endpoint;
>
> - if (!port->name || of_node_cmp(port->name, "port"))
> + if (!of_node_name_eq(port, "port"))
> continue;
>
> format = xvip_of_get_format(port);
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c
> b/drivers/media/v4l2-core/v4l2-fwnode.c index 218f0da0ce76..849326241b17
> 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -564,8 +564,7 @@ int v4l2_fwnode_parse_link(struct fwnode_handle
> *__fwnode, fwnode = fwnode_get_parent(__fwnode);
> fwnode_property_read_u32(fwnode, port_prop, &link->local_port);
> fwnode = fwnode_get_next_parent(fwnode);
> - if (is_of_node(fwnode) &&
> - of_node_cmp(to_of_node(fwnode)->name, "ports") == 0)
> + if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports"))
> fwnode = fwnode_get_next_parent(fwnode);
> link->local_node = fwnode;
>
> @@ -578,8 +577,7 @@ int v4l2_fwnode_parse_link(struct fwnode_handle
> *__fwnode, fwnode = fwnode_get_parent(fwnode);
> fwnode_property_read_u32(fwnode, port_prop, &link->remote_port);
> fwnode = fwnode_get_next_parent(fwnode);
> - if (is_of_node(fwnode) &&
> - of_node_cmp(to_of_node(fwnode)->name, "ports") == 0)
> + if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports"))
> fwnode = fwnode_get_next_parent(fwnode);
> link->remote_node = fwnode;
--
Regards,
Laurent Pinchart
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3 3/4] ARM: shmobile: Enable NXP pcf85363 rtc in shmobile_defconfig
From: Biju Das @ 2018-12-06 8:55 UTC (permalink / raw)
To: Simon Horman
Cc: linux-rtc, Fabrizio Castro, Alexandre Belloni, Geert Uytterhoeven,
Magnus Damm, Russell King, Biju Das, linux-renesas-soc,
Chris Paterson, linux-arm-kernel
In-Reply-To: <1544086559-47141-1-git-send-email-biju.das@bp.renesas.com>
The iWave RZ/G1C SBC supports RTC (NXP pcf85263). To increase hardware
support enable the driver in the shmobile_defconfig multiplatform
configuration.
Signed-off-by: Biju Das <biju.das@bp.renesas.com>
---
V1-->V2
* No change.
V2-->V3
* No change.
---
arch/arm/configs/shmobile_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 9e5a5ad..fdac4e4 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -177,6 +177,7 @@ CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_RS5C372=y
+CONFIG_RTC_DRV_PCF85363=y
CONFIG_RTC_DRV_BQ32K=y
CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_RX8581=y
--
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 "drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut()" has been added to the 4.19-stable tree
From: gregkh @ 2018-12-06 8:57 UTC (permalink / raw)
To: 20181125012117.31915-1-lyude, carlo, dri-devel, gregkh, khilman,
linux-amlogic, linux-arm-kernel, lyude, maxime.ripard, narmstrong,
seanpaul
Cc: stable-commits
This is a note to let you know that I've just added the patch titled
drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut()
to the 4.19-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-meson-fix-oob-memory-accesses-in-meson_viu_set_osd_lut.patch
and it can be found in the queue-4.19 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
From 97b2a3180a559a33852ac0cd77904166069484fd Mon Sep 17 00:00:00 2001
From: Lyude Paul <lyude@redhat.com>
Date: Sat, 24 Nov 2018 20:21:17 -0500
Subject: drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut()
From: Lyude Paul <lyude@redhat.com>
commit 97b2a3180a559a33852ac0cd77904166069484fd upstream.
Currently on driver bringup with KASAN enabled, meson triggers an OOB
memory access as shown below:
[ 117.904528] ==================================================================
[ 117.904560] BUG: KASAN: global-out-of-bounds in meson_viu_set_osd_lut+0x7a0/0x890
[ 117.904588] Read of size 4 at addr ffff20000a63ce24 by task systemd-udevd/498
[ 117.904601]
[ 118.083372] CPU: 4 PID: 498 Comm: systemd-udevd Not tainted 4.20.0-rc3Lyude-Test+ #20
[ 118.091143] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018
[ 118.099768] Call trace:
[ 118.102181] dump_backtrace+0x0/0x3e8
[ 118.105796] show_stack+0x14/0x20
[ 118.109083] dump_stack+0x130/0x1c4
[ 118.112539] print_address_description+0x60/0x25c
[ 118.117214] kasan_report+0x1b4/0x368
[ 118.120851] __asan_report_load4_noabort+0x18/0x20
[ 118.125566] meson_viu_set_osd_lut+0x7a0/0x890
[ 118.129953] meson_viu_init+0x10c/0x290
[ 118.133741] meson_drv_bind_master+0x474/0x748
[ 118.138141] meson_drv_bind+0x10/0x18
[ 118.141760] try_to_bring_up_master+0x3d8/0x768
[ 118.146249] component_add+0x214/0x570
[ 118.149978] meson_dw_hdmi_probe+0x18/0x20 [meson_dw_hdmi]
[ 118.155404] platform_drv_probe+0x98/0x138
[ 118.159455] really_probe+0x2a0/0xa70
[ 118.163070] driver_probe_device+0x1b4/0x2d8
[ 118.167299] __driver_attach+0x200/0x280
[ 118.171189] bus_for_each_dev+0x10c/0x1a8
[ 118.175144] driver_attach+0x38/0x50
[ 118.178681] bus_add_driver+0x330/0x608
[ 118.182471] driver_register+0x140/0x388
[ 118.186361] __platform_driver_register+0xc8/0x108
[ 118.191117] meson_dw_hdmi_platform_driver_init+0x1c/0x1000 [meson_dw_hdmi]
[ 118.198022] do_one_initcall+0x12c/0x3bc
[ 118.201883] do_init_module+0x1fc/0x638
[ 118.205673] load_module+0x4b4c/0x6808
[ 118.209387] __se_sys_init_module+0x2e8/0x3c0
[ 118.213699] __arm64_sys_init_module+0x68/0x98
[ 118.218100] el0_svc_common+0x104/0x210
[ 118.221893] el0_svc_handler+0x48/0xb8
[ 118.225594] el0_svc+0x8/0xc
[ 118.228429]
[ 118.229887] The buggy address belongs to the variable:
[ 118.235007] eotf_33_linear_mapping+0x84/0xc0
[ 118.239301]
[ 118.240752] Memory state around the buggy address:
[ 118.245522] ffff20000a63cd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 118.252695] ffff20000a63cd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 118.259850] >ffff20000a63ce00: 00 00 00 00 04 fa fa fa fa fa fa fa 00 00 00 00
[ 118.267000] ^
[ 118.271222] ffff20000a63ce80: 00 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
[ 118.278393] ffff20000a63cf00: 00 00 00 00 00 00 00 00 00 00 00 00 04 fa fa fa
[ 118.285542] ==================================================================
[ 118.292699] Disabling lock debugging due to kernel taint
It seems that when looping through the OSD EOTF LUT maps, we use the
same max iterator for OETF: 20. This is wrong though, since 20*2 is 40,
which means that we'll stop out of bounds on the EOTF maps.
But, this whole thing is already confusing enough to read through as-is,
so let's just replace all of the hardcoded sizes with
OSD_(OETF/EOTF)_LUT_SIZE / 2.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller")
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Carlo Caione <carlo@caione.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: <stable@vger.kernel.org> # v4.10+
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181125012117.31915-1-lyude@redhat.com
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/meson/meson_viu.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -184,18 +184,18 @@ void meson_viu_set_osd_lut(struct meson_
if (lut_sel == VIU_LUT_OSD_OETF) {
writel(0, priv->io_base + _REG(addr_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
@@ -211,18 +211,18 @@ void meson_viu_set_osd_lut(struct meson_
} else if (lut_sel == VIU_LUT_OSD_EOTF) {
writel(0, priv->io_base + _REG(addr_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
priv->io_base + _REG(data_port));
- for (i = 0; i < 20; i++)
+ for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
priv->io_base + _REG(data_port));
Patches currently in stable-queue which might be from lyude@redhat.com are
queue-4.19/drm-meson-enable-fast_io-in-meson_dw_hdmi_regmap_config.patch
queue-4.19/drm-amd-dm-understand-why-attaching-path-tile-properties-are-needed.patch
queue-4.19/drm-amd-dm-don-t-forget-to-attach-mst-encoders.patch
queue-4.19/drm-meson-fixes-for-drm_crtc_vblank_on-off-support.patch
queue-4.19/drm-meson-fix-oob-memory-accesses-in-meson_viu_set_osd_lut.patch
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Patch "drm/meson: Enable fast_io in meson_dw_hdmi_regmap_config" has been added to the 4.19-stable tree
From: gregkh @ 2018-12-06 8:57 UTC (permalink / raw)
To: 20181124191238.28276-1-lyude, carlo, daniel.vetter, dri-devel,
gregkh, khilman, linux-amlogic, linux-arm-kernel, lyude,
narmstrong, seanpaul
Cc: stable-commits
This is a note to let you know that I've just added the patch titled
drm/meson: Enable fast_io in meson_dw_hdmi_regmap_config
to the 4.19-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-meson-enable-fast_io-in-meson_dw_hdmi_regmap_config.patch
and it can be found in the queue-4.19 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
From 995b278e4723b26f8ebf0e7c119286d16c712747 Mon Sep 17 00:00:00 2001
From: Lyude Paul <lyude@redhat.com>
Date: Sat, 24 Nov 2018 14:12:38 -0500
Subject: drm/meson: Enable fast_io in meson_dw_hdmi_regmap_config
From: Lyude Paul <lyude@redhat.com>
commit 995b278e4723b26f8ebf0e7c119286d16c712747 upstream.
Seeing as we use this registermap in the context of our IRQ handlers, we
need to be using spinlocks for reading/writing registers so that we can
still read them from IRQ handlers without having to grab any mutexes and
accidentally sleep. We don't currently do this, as pointed out by
lockdep:
[ 18.403770] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:908
[ 18.406744] in_atomic(): 1, irqs_disabled(): 128, pid: 68, name: kworker/u17:0
[ 18.413864] INFO: lockdep is turned off.
[ 18.417675] irq event stamp: 12
[ 18.420778] hardirqs last enabled at (11): [<ffff000008a4f57c>] _raw_spin_unlock_irq+0x2c/0x60
[ 18.429510] hardirqs last disabled at (12): [<ffff000008a48914>] __schedule+0xc4/0xa60
[ 18.437345] softirqs last enabled at (0): [<ffff0000080b55e0>] copy_process.isra.4.part.5+0x4d8/0x1c50
[ 18.446684] softirqs last disabled at (0): [<0000000000000000>] (null)
[ 18.453979] CPU: 0 PID: 68 Comm: kworker/u17:0 Tainted: G W O 4.20.0-rc3Lyude-Test+ #9
[ 18.469839] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018
[ 18.480037] Workqueue: hci0 hci_power_on [bluetooth]
[ 18.487138] Call trace:
[ 18.494192] dump_backtrace+0x0/0x1b8
[ 18.501280] show_stack+0x14/0x20
[ 18.508361] dump_stack+0xbc/0xf4
[ 18.515427] ___might_sleep+0x140/0x1d8
[ 18.522515] __might_sleep+0x50/0x88
[ 18.529582] __mutex_lock+0x60/0x870
[ 18.536621] mutex_lock_nested+0x1c/0x28
[ 18.543660] regmap_lock_mutex+0x10/0x18
[ 18.550696] regmap_read+0x38/0x70
[ 18.557727] dw_hdmi_hardirq+0x58/0x138 [dw_hdmi]
[ 18.564804] __handle_irq_event_percpu+0xac/0x410
[ 18.571891] handle_irq_event_percpu+0x34/0x88
[ 18.578982] handle_irq_event+0x48/0x78
[ 18.586051] handle_fasteoi_irq+0xac/0x160
[ 18.593061] generic_handle_irq+0x24/0x38
[ 18.599989] __handle_domain_irq+0x60/0xb8
[ 18.606857] gic_handle_irq+0x50/0xa0
[ 18.613659] el1_irq+0xb4/0x130
[ 18.620394] debug_lockdep_rcu_enabled+0x2c/0x30
[ 18.627111] schedule+0x38/0xa0
[ 18.633781] schedule_timeout+0x3a8/0x510
[ 18.640389] wait_for_common+0x15c/0x180
[ 18.646905] wait_for_completion+0x14/0x20
[ 18.653319] mmc_wait_for_req_done+0x28/0x168
[ 18.659693] mmc_wait_for_req+0xa8/0xe8
[ 18.665978] mmc_wait_for_cmd+0x64/0x98
[ 18.672180] mmc_io_rw_direct_host+0x94/0x130
[ 18.678385] mmc_io_rw_direct+0x10/0x18
[ 18.684516] sdio_enable_func+0xe8/0x1d0
[ 18.690627] btsdio_open+0x24/0xc0 [btsdio]
[ 18.696821] hci_dev_do_open+0x64/0x598 [bluetooth]
[ 18.703025] hci_power_on+0x50/0x270 [bluetooth]
[ 18.709163] process_one_work+0x2a0/0x6e0
[ 18.715252] worker_thread+0x40/0x448
[ 18.721310] kthread+0x12c/0x130
[ 18.727326] ret_from_fork+0x10/0x1c
[ 18.735555] ------------[ cut here ]------------
[ 18.741430] do not call blocking ops when !TASK_RUNNING; state=2 set at [<000000006265ec59>] wait_for_common+0x140/0x180
[ 18.752417] WARNING: CPU: 0 PID: 68 at kernel/sched/core.c:6096 __might_sleep+0x7c/0x88
[ 18.760553] Modules linked in: dm_mirror dm_region_hash dm_log dm_mod
btsdio bluetooth snd_soc_hdmi_codec dw_hdmi_i2s_audio ecdh_generic
brcmfmac brcmutil cfg80211 rfkill ir_nec_decoder meson_dw_hdmi(O)
dw_hdmi rc_geekbox meson_rng meson_ir ao_cec rng_core rc_core cec
leds_pwm efivars nfsd ip_tables x_tables crc32_generic f2fs uas
meson_gxbb_wdt pwm_meson efivarfs ipv6
[ 18.799469] CPU: 0 PID: 68 Comm: kworker/u17:0 Tainted: G W O 4.20.0-rc3Lyude-Test+ #9
[ 18.808858] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018
[ 18.818045] Workqueue: hci0 hci_power_on [bluetooth]
[ 18.824088] pstate: 80000085 (Nzcv daIf -PAN -UAO)
[ 18.829891] pc : __might_sleep+0x7c/0x88
[ 18.835722] lr : __might_sleep+0x7c/0x88
[ 18.841256] sp : ffff000008003cb0
[ 18.846751] x29: ffff000008003cb0 x28: 0000000000000000
[ 18.852269] x27: ffff00000938e000 x26: ffff800010283000
[ 18.857726] x25: ffff800010353280 x24: ffff00000868ef50
[ 18.863166] x23: 0000000000000000 x22: 0000000000000000
[ 18.868551] x21: 0000000000000000 x20: 000000000000038c
[ 18.873850] x19: ffff000008cd08c0 x18: 0000000000000010
[ 18.879081] x17: ffff000008a68cb0 x16: 0000000000000000
[ 18.884197] x15: 0000000000aaaaaa x14: 0e200e200e200e20
[ 18.889239] x13: 0000000000000001 x12: 00000000ffffffff
[ 18.894261] x11: ffff000008adfa48 x10: 0000000000000001
[ 18.899517] x9 : ffff0000092a0158 x8 : 0000000000000000
[ 18.904674] x7 : ffff00000812136c x6 : 0000000000000000
[ 18.909895] x5 : 0000000000000000 x4 : 0000000000000001
[ 18.915080] x3 : 0000000000000007 x2 : 0000000000000007
[ 18.920269] x1 : 99ab8e9ebb6c8500 x0 : 0000000000000000
[ 18.925443] Call trace:
[ 18.929904] __might_sleep+0x7c/0x88
[ 18.934311] __mutex_lock+0x60/0x870
[ 18.938687] mutex_lock_nested+0x1c/0x28
[ 18.943076] regmap_lock_mutex+0x10/0x18
[ 18.947453] regmap_read+0x38/0x70
[ 18.951842] dw_hdmi_hardirq+0x58/0x138 [dw_hdmi]
[ 18.956269] __handle_irq_event_percpu+0xac/0x410
[ 18.960712] handle_irq_event_percpu+0x34/0x88
[ 18.965176] handle_irq_event+0x48/0x78
[ 18.969612] handle_fasteoi_irq+0xac/0x160
[ 18.974058] generic_handle_irq+0x24/0x38
[ 18.978501] __handle_domain_irq+0x60/0xb8
[ 18.982938] gic_handle_irq+0x50/0xa0
[ 18.987351] el1_irq+0xb4/0x130
[ 18.991734] debug_lockdep_rcu_enabled+0x2c/0x30
[ 18.996180] schedule+0x38/0xa0
[ 19.000609] schedule_timeout+0x3a8/0x510
[ 19.005064] wait_for_common+0x15c/0x180
[ 19.009513] wait_for_completion+0x14/0x20
[ 19.013951] mmc_wait_for_req_done+0x28/0x168
[ 19.018402] mmc_wait_for_req+0xa8/0xe8
[ 19.022809] mmc_wait_for_cmd+0x64/0x98
[ 19.027177] mmc_io_rw_direct_host+0x94/0x130
[ 19.031563] mmc_io_rw_direct+0x10/0x18
[ 19.035922] sdio_enable_func+0xe8/0x1d0
[ 19.040294] btsdio_open+0x24/0xc0 [btsdio]
[ 19.044742] hci_dev_do_open+0x64/0x598 [bluetooth]
[ 19.049228] hci_power_on+0x50/0x270 [bluetooth]
[ 19.053687] process_one_work+0x2a0/0x6e0
[ 19.058143] worker_thread+0x40/0x448
[ 19.062608] kthread+0x12c/0x130
[ 19.067064] ret_from_fork+0x10/0x1c
[ 19.071513] irq event stamp: 12
[ 19.075937] hardirqs last enabled at (11): [<ffff000008a4f57c>] _raw_spin_unlock_irq+0x2c/0x60
[ 19.083560] hardirqs last disabled at (12): [<ffff000008a48914>] __schedule+0xc4/0xa60
[ 19.091401] softirqs last enabled at (0): [<ffff0000080b55e0>] copy_process.isra.4.part.5+0x4d8/0x1c50
[ 19.100801] softirqs last disabled at (0): [<0000000000000000>] (null)
[ 19.108135] ---[ end trace 38c4920787b88c75 ]---
So, fix this by enabling the fast_io option in our regmap config so that
regmap uses spinlocks for locking instead of mutexes.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Fixes: 3f68be7d8e96 ("drm/meson: Add support for HDMI encoder and DW-HDMI bridge + PHY")
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Carlo Caione <carlo@caione.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: <stable@vger.kernel.org> # v4.12+
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181124191238.28276-1-lyude@redhat.com
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/meson/meson_dw_hdmi.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -706,6 +706,7 @@ static const struct regmap_config meson_
.reg_read = meson_dw_hdmi_reg_read,
.reg_write = meson_dw_hdmi_reg_write,
.max_register = 0x10000,
+ .fast_io = true,
};
static bool meson_hdmi_connector_is_available(struct device *dev)
Patches currently in stable-queue which might be from lyude@redhat.com are
queue-4.19/drm-meson-enable-fast_io-in-meson_dw_hdmi_regmap_config.patch
queue-4.19/drm-amd-dm-understand-why-attaching-path-tile-properties-are-needed.patch
queue-4.19/drm-amd-dm-don-t-forget-to-attach-mst-encoders.patch
queue-4.19/drm-meson-fixes-for-drm_crtc_vblank_on-off-support.patch
queue-4.19/drm-meson-fix-oob-memory-accesses-in-meson_viu_set_osd_lut.patch
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3] ARM: smp: add support for per-task stack canaries
From: Ard Biesheuvel @ 2018-12-06 8:32 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, linux
Cc: Kees Cook, Arnd Bergmann, kernel-hardening, Ard Biesheuvel,
Emese Revfy, Laura Abbott
On ARM, we currently only change the value of the stack canary when
switching tasks if the kernel was built for UP. On SMP kernels, this
is impossible since the stack canary value is obtained via a global
symbol reference, which means
a) all running tasks on all CPUs must use the same value
b) we can only modify the value when no kernel stack frames are live
on any CPU, which is effectively never.
So instead, use a GCC plugin to add a RTL pass that replaces each
reference to the address of the __stack_chk_guard symbol with an
expression that produces the address of the 'stack_canary' field
that is added to struct thread_info. This way, each task will use
its own randomized value.
Cc: Russell King <linux@armlinux.org.uk>
Cc: Kees Cook <keescook@chromium.org>
Cc: Emese Revfy <re.emese@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Laura Abbott <labbott@redhat.com>
Cc: kernel-hardening@lists.openwall.com
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
v3:
- enable the feature automatically if CONFIG_STACKPROTECTOR and
CONFIG_GCC_PLUGINS are both enabled
- move the stack canary to the front of struct thread_info so it shares
a cacheline with the flags, preempt_count and task pointer members
- fix incorrect reference to task_struct::stack_canary in previous
version
arch/arm/Kconfig | 15 +++
arch/arm/Makefile | 12 +++
arch/arm/boot/compressed/Makefile | 1 +
arch/arm/include/asm/stackprotector.h | 12 ++-
arch/arm/include/asm/thread_info.h | 3 +
arch/arm/kernel/asm-offsets.c | 4 +
arch/arm/kernel/process.c | 6 +-
scripts/Makefile.gcc-plugins | 6 ++
scripts/gcc-plugins/Kconfig | 4 +
scripts/gcc-plugins/arm_ssp_per_task_plugin.c | 103 ++++++++++++++++++++
10 files changed, 163 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 91be74d8df65..5c0305585a0a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1810,6 +1810,21 @@ config XEN
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
+config STACKPROTECTOR_PER_TASK
+ bool "Use a unique stack canary value for each task"
+ depends on GCC_PLUGINS && STACKPROTECTOR && SMP && !XIP_DEFLATED_DATA
+ select GCC_PLUGIN_ARM_SSP_PER_TASK
+ default y
+ help
+ Due to the fact that GCC uses an ordinary symbol reference from
+ which to load the value of the stack canary, this value can only
+ change at reboot time on SMP systems, and all tasks running in the
+ kernel's address space are forced to use the same canary value for
+ the entire duration that the system is up.
+
+ Enable this option to switch to a different method that uses a
+ different canary value for each task.
+
endmenu
menu "Boot options"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 05a91d8b89f3..0436002d5091 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -303,6 +303,18 @@ else
KBUILD_IMAGE := $(boot)/zImage
endif
+ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y)
+prepare: stack_protector_prepare
+stack_protector_prepare: prepare0
+ $(eval KBUILD_CFLAGS += \
+ -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \
+ awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\
+ include/generated/asm-offsets.h) \
+ -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \
+ awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\
+ include/generated/asm-offsets.h))
+endif
+
all: $(notdir $(KBUILD_IMAGE))
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 1f5a5ffe7fcf..01bf2585a0fa 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -101,6 +101,7 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \
$(libfdt) $(libfdt_hdrs) hyp-stub.S
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
+KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN)
ifeq ($(CONFIG_FUNCTION_TRACER),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
index ef5f7b69443e..72a20c3a0a90 100644
--- a/arch/arm/include/asm/stackprotector.h
+++ b/arch/arm/include/asm/stackprotector.h
@@ -6,8 +6,10 @@
* the stack frame and verifying that it hasn't been overwritten when
* returning from the function. The pattern is called stack canary
* and gcc expects it to be defined by a global variable called
- * "__stack_chk_guard" on ARM. This unfortunately means that on SMP
- * we cannot have a different canary value per task.
+ * "__stack_chk_guard" on ARM. This prevents SMP systems from using a
+ * different value for each task unless we enable a GCC plugin that
+ * replaces these symbol references with references to each task's own
+ * value.
*/
#ifndef _ASM_STACKPROTECTOR_H
@@ -16,6 +18,8 @@
#include <linux/random.h>
#include <linux/version.h>
+#include <asm/thread_info.h>
+
extern unsigned long __stack_chk_guard;
/*
@@ -33,7 +37,11 @@ static __always_inline void boot_init_stack_canary(void)
canary ^= LINUX_VERSION_CODE;
current->stack_canary = canary;
+#ifndef CONFIG_STACKPROTECTOR_PER_TASK
__stack_chk_guard = current->stack_canary;
+#else
+ current_thread_info()->stack_canary = current->stack_canary;
+#endif
}
#endif /* _ASM_STACKPROTECTOR_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 8f55dc520a3e..286eb61c632b 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -53,6 +53,9 @@ struct thread_info {
struct task_struct *task; /* main task structure */
__u32 cpu; /* cpu */
__u32 cpu_domain; /* cpu domain */
+#ifdef CONFIG_STACKPROTECTOR_PER_TASK
+ unsigned long stack_canary;
+#endif
struct cpu_context_save cpu_context; /* cpu context */
__u32 syscall; /* syscall number */
__u8 used_cp[16]; /* thread used copro */
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 3968d6c22455..28b27104ac0c 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -79,6 +79,10 @@ int main(void)
#ifdef CONFIG_CRUNCH
DEFINE(TI_CRUNCH_STATE, offsetof(struct thread_info, crunchstate));
#endif
+#ifdef CONFIG_STACKPROTECTOR_PER_TASK
+ DEFINE(TI_STACK_CANARY, offsetof(struct thread_info, stack_canary));
+#endif
+ DEFINE(THREAD_SZ_ORDER, THREAD_SIZE_ORDER);
BLANK();
DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 82ab015bf42b..16601d1442d1 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -39,7 +39,7 @@
#include <asm/tls.h>
#include <asm/vdso.h>
-#ifdef CONFIG_STACKPROTECTOR
+#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
@@ -267,6 +267,10 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
thread_notify(THREAD_NOTIFY_COPY, thread);
+#ifdef CONFIG_STACKPROTECTOR_PER_TASK
+ thread->stack_canary = p->stack_canary;
+#endif
+
return 0;
}
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 46c5c6809806..048179d8c07f 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -36,6 +36,12 @@ ifdef CONFIG_GCC_PLUGIN_STACKLEAK
endif
export DISABLE_STACKLEAK_PLUGIN
+gcc-plugin-$(CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK) += arm_ssp_per_task_plugin.so
+ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK
+ DISABLE_ARM_SSP_PER_TASK_PLUGIN += -fplugin-arg-arm_ssp_per_task_plugin-disable
+endif
+export DISABLE_ARM_SSP_PER_TASK_PLUGIN
+
# All the plugin CFLAGS are collected here in case a build target needs to
# filter them out of the KBUILD_CFLAGS.
GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
index 0d5c799688f0..d45f7f36b859 100644
--- a/scripts/gcc-plugins/Kconfig
+++ b/scripts/gcc-plugins/Kconfig
@@ -190,4 +190,8 @@ config STACKLEAK_RUNTIME_DISABLE
runtime to control kernel stack erasing for kernels built with
CONFIG_GCC_PLUGIN_STACKLEAK.
+config GCC_PLUGIN_ARM_SSP_PER_TASK
+ bool
+ depends on GCC_PLUGINS && ARM
+
endif
diff --git a/scripts/gcc-plugins/arm_ssp_per_task_plugin.c b/scripts/gcc-plugins/arm_ssp_per_task_plugin.c
new file mode 100644
index 000000000000..de70b8470971
--- /dev/null
+++ b/scripts/gcc-plugins/arm_ssp_per_task_plugin.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "gcc-common.h"
+
+__visible int plugin_is_GPL_compatible;
+
+static unsigned int sp_mask, canary_offset;
+
+static unsigned int arm_pertask_ssp_rtl_execute(void)
+{
+ rtx_insn *insn;
+
+ for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) {
+ const char *sym;
+ rtx body;
+ rtx masked_sp;
+
+ /*
+ * Find a SET insn involving a SYMBOL_REF to __stack_chk_guard
+ */
+ if (!INSN_P(insn))
+ continue;
+ body = PATTERN(insn);
+ if (GET_CODE(body) != SET ||
+ GET_CODE(SET_SRC(body)) != SYMBOL_REF)
+ continue;
+ sym = XSTR(SET_SRC(body), 0);
+ if (strcmp(sym, "__stack_chk_guard"))
+ continue;
+
+ /*
+ * Replace the source of the SET insn with an expression that
+ * produces the address of the copy of the stack canary value
+ * stored in struct thread_info
+ */
+ masked_sp = gen_reg_rtx(Pmode);
+
+ emit_insn_before(gen_rtx_SET(masked_sp,
+ gen_rtx_AND(Pmode,
+ stack_pointer_rtx,
+ GEN_INT(sp_mask))),
+ insn);
+
+ SET_SRC(body) = gen_rtx_PLUS(Pmode, masked_sp,
+ GEN_INT(canary_offset));
+ }
+ return 0;
+}
+
+#define PASS_NAME arm_pertask_ssp_rtl
+
+#define NO_GATE
+#include "gcc-generate-rtl-pass.h"
+
+__visible int plugin_init(struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ const char * const plugin_name = plugin_info->base_name;
+ const int argc = plugin_info->argc;
+ const struct plugin_argument *argv = plugin_info->argv;
+ int tso = 0;
+ int i;
+
+ if (!plugin_default_version_check(version, &gcc_version)) {
+ error(G_("incompatible gcc/plugin versions"));
+ return 1;
+ }
+
+ for (i = 0; i < argc; ++i) {
+ if (!strcmp(argv[i].key, "disable"))
+ return 0;
+
+ /* all remaining options require a value */
+ if (!argv[i].value) {
+ error(G_("no value supplied for option '-fplugin-arg-%s-%s'"),
+ plugin_name, argv[i].key);
+ return 1;
+ }
+
+ if (!strcmp(argv[i].key, "tso")) {
+ tso = atoi(argv[i].value);
+ continue;
+ }
+
+ if (!strcmp(argv[i].key, "offset")) {
+ canary_offset = atoi(argv[i].value);
+ continue;
+ }
+ error(G_("unknown option '-fplugin-arg-%s-%s'"),
+ plugin_name, argv[i].key);
+ return 1;
+ }
+
+ /* create the mask that produces the base of the stack */
+ sp_mask = ~((1U << (12 + tso)) - 1);
+
+ PASS_INFO(arm_pertask_ssp_rtl, "expand", 1, PASS_POS_INSERT_AFTER);
+
+ register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP,
+ NULL, &arm_pertask_ssp_rtl_pass_info);
+
+ return 0;
+}
--
2.19.2
_______________________________________________
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 10/14] dt-bindings: pinctrl: milbeaut: Add Milbeaut M10V pinctrl description
From: Sugaya, Taichi @ 2018-12-06 8:29 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, devicetree, Masami Hiramatsu, Stephen Boyd,
Greg Kroah-Hartman, Michael Turquette, Daniel Lezcano,
linux-kernel, Russell King, Jassi Brar, linux-serial, Jiri Slaby,
Thomas Gleixner, linux-clk, linux-arm-kernel
In-Reply-To: <20181204231131.GA7366@bogus>
Hi,
Thank you for your comments.
On 2018/12/05 8:11, Rob Herring wrote:
> On Mon, Nov 19, 2018 at 10:02:12AM +0900, Sugaya Taichi wrote:
>> Add DT bindings document for Milbeaut M10V pinctrl.
>>
>> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com>
>> ---
>> .../pinctrl/socionext,milbeaut-pinctrl.txt | 33 ++++++++++++++++++++++
>> 1 file changed, 33 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/pinctrl/socionext,milbeaut-pinctrl.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pinctrl/socionext,milbeaut-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/socionext,milbeaut-pinctrl.txt
>> new file mode 100644
>> index 0000000..7469189
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/socionext,milbeaut-pinctrl.txt
>> @@ -0,0 +1,33 @@
>> +Milbeaut SoCs pin controller
>> +
>> +Required properties:
>> +- compatible: should be one of the following:
>> + "socionext,milbeaut-m10v-pinctrl" - for m10v SoC
>> +- reg: offset and length of the register set.
>> +- reg-names: should be "pinctrl", "exiu".
>> +- gpio-cells; should be 2.
>
> #gpio-cells
>
> gpio-controller?
Ah yes. I forgot to add it.
Add it.
>
>> +- interrupt-cells: should be 2.
>
> #interrupt-cells
>
> interrupt-controller?
Add it also.
Thanks,
Sugaya Taichi
>
>> +- clocks: phandle to the input clock.
>> +- interrupts: three interrupts specifer.
>> +- interrupt-names: corresponds "interrupts" factor.
>> +
>> +Example:
>> + pinctrl: pinctrl@1d022000 {
>> + compatible = "socionext,milbeaut-m10v-pinctrl";
>> + reg = <0x1d022000 0x1000>,
>> + <0x1c26f000 0x1000>;
>> + reg-names = "pinctrl", "exiu";
>> + gpio-controller;
>> + #gpio-cells = <2>;
>> + interrupt-controller;
>> + #interrupt-cells = <2>;
>> + clocks = <&dummy_clk>;
>> + interrupts = <0 54 4>, <0 55 4>, <0 56 4>, <0 57 4>,
>> + <0 58 4>, <0 59 4>, <0 60 4>, <0 61 4>,
>> + <0 62 4>, <0 63 4>, <0 64 4>, <0 65 4>,
>> + <0 66 4>, <0 67 4>, <0 68 4>, <0 69 4>;
>> + interrupt-names = "pin-48", "pin-49", "pin-50", "pin-51",
>> + "pin-52", "pin-53", "pin-54", "pin-55",
>> + "pin-56", "pin-57", "pin-58", "pin-59",
>> + "pin-60", "pin-61", "pin-62", "pin-63";
>> + }
>> --
>> 1.9.1
>>
_______________________________________________
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] ARM: dts: exynos: Add proper regulator states for suspend-to-mem for odroid-u3
From: Marek Szyprowski @ 2018-12-06 8:25 UTC (permalink / raw)
To: Anand Moon, Krzysztof Kozlowski
Cc: Mark Rutland, devicetree, linux-samsung-soc,
Bartlomiej Zolnierkiewicz, Linux Kernel, Rob Herring, Kukjin Kim,
linux-arm-kernel
In-Reply-To: <CANAwSgSSOmTbqS4WUYZHXdB8XL5fjoiGbrh3unxufQ0gZXBPkQ@mail.gmail.com>
Hi All,
On 2018-12-05 17:11, Anand Moon wrote:
> Hi Krzysztof,
>
> Thanks for your review.
> .
> On Wed, 5 Dec 2018 at 19:36, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>> On Tue, 4 Dec 2018 at 20:40, Anand Moon <linux.amoon@gmail.com> wrote:
>>> Add suspend-to-mem node to regulator core to be enabled or disabled
>>> during system suspend and also support changing the regulator operating
>>> mode during runtime and when the system enter sleep mode.
>>>
>>> Signed-off-by: Anand Moon <linux.amoon@gmail.com>
>>> ---
>>> Tested on Odroid U3+
>>> ...
> Well I have tested this patch as following
> with only one issue, before enable suspend number of On-line cpu is 4
> after resume number of On-line cpu is 1.
This seems to be a regression in v4.20-rc1, not related to dts changes
at all. I'm investigating this now...
> ...
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
_______________________________________________
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] ARM: dts: Add support for Liebherr's BK4 device (vf610 based)
From: Lukasz Majewski @ 2018-12-06 8:22 UTC (permalink / raw)
To: Fabio Estevam
Cc: Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Sascha Hauer, linux-kernel, Stefan Agner, Rob Herring,
Sascha Hauer, Fabio Estevam, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CAOMZO5BN5KJ+s6F9CJXQPX=Ta0Ow0PaV_AmFHYSDNr78jLjziQ@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 2015 bytes --]
On Wed, 5 Dec 2018 21:12:46 -0200
Fabio Estevam <festevam@gmail.com> wrote:
> Hi Lukasz/Rob,
>
> On Tue, Oct 9, 2018 at 7:50 AM Lukasz Majewski <lukma@denx.de> wrote:
>
> > +&dspi3 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_dspi3>;
> > + bus-num = <3>;
> > + status = "okay";
> > + spi-slave;
> > +
> > + slave@0 {
> > + compatible = "lwn,bk4";
> > + spi-max-frequency = <30000000>;
> > + reg = <0>;
> > + };
> > +};
>
> This is causing the following dtc warning in linux-next:
>
> DTC arch/arm/boot/dts/vf610-bk4.dtb
> arch/arm/boot/dts/vfxxx.dtsi:550.24-563.6: Warning (spi_bus_bridge):
> /soc/aips-bus@40080000/spi@400ad000: incorrect #address-cells for SPI
> bus
> also defined at arch/arm/boot/dts/vf610-bk4.dts:106.8-118.3
> arch/arm/boot/dts/vf610-bk4.dtb: Warning (spi_bus_reg): Failed
> prerequisite 'spi_bus_bridge'
>
> If spi-slave property is removed the warning is gone.
The spi-slave has been added according to review suggestion:
https://lkml.org/lkml/2018/9/26/836
That is the way to handle "slave" SPI operation mode across the kernel.
At the time of development - I've checked my NXP related patches with
W=1 passed to make. No warnings observed then.
>
> Looking at drivers/spi/spi-fsl-dspi.c I don't see the "spi-slave"
> property being handled there.
>
> Any ideas on how to fix this?
The *.dts file for Vybrid was sent and work on in parallel with the SPI
slave code implementation for Vybrid:
https://patchwork.kernel.org/patch/10680431/
Unfortunately, for the above patch I did not received any feedback
since mid September.
>
> Thanks
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 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] PCI: controller: dwc: Make PCI_IMX6 depend on PCIEPORTBUS
From: Baruch Siach @ 2018-12-06 8:10 UTC (permalink / raw)
To: Andrey Smirnov, Robert Hancock
Cc: A.s. Dong, Trent Piepho, Richard Zhu, linux-pci, linux-kernel,
linux-imx, bhelgaas, Leonard Crestez, cphealy, linux-arm-kernel,
l.stach
In-Reply-To: <20181206074555.19579-1-andrew.smirnov@gmail.com>
Hi Andrey,
Adding Robert Hancock who reported[1] on a PCIe MSI issue with i.MX6.
Andrey Smirnov writes:
> Building a kernel with CONFIG_PCI_IMX6=y, but CONFIG_PCIEPORTBUS=n
> produces a system where built-in PCIE bridge (16c3:abcd) isn't bound
> to pcieport driver. This, in turn, results in a PCIE bus that is
> capable of enumerating attached PCIE device, but lacks functional
> interrupt support.
Robert, does that fix your issue?
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
>
> Assuming this is a reasonable dependency, shold this be done to more
> than just i.MX6 driver?
>
> drivers/pci/controller/dwc/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index 2b139acccf32..44ededbeab85 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -92,6 +92,7 @@ config PCI_IMX6
> bool "Freescale i.MX6 PCIe controller"
> depends on SOC_IMX8MQ || SOC_IMX6Q || (ARM && COMPILE_TEST)
> depends on PCI_MSI_IRQ_DOMAIN
> + depends on PCIEPORTBUS
This effectively disables PCIe in imx_v6_v7_defconfig, since
CONFIG_PCIEPORTBUS is not enabled there. Maybe do 'select' instead?
> Select PCIE_DW_HOST
>
> config PCIE_SPEAR13XX
baruch
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-November/614800.html
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch@tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -
_______________________________________________
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] ARM: dts: exynos: Add proper regulator states for suspend-to-mem for odroid-u3
From: Anand Moon @ 2018-12-06 7:52 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Mark Rutland, devicetree, linux-samsung-soc,
Bartlomiej Zolnierkiewicz, Linux Kernel, Rob Herring, Kukjin Kim,
linux-arm-kernel, Marek Szyprowski
In-Reply-To: <CAJKOXPdvk0Kip-RrFF3cwTpuXnFFL2PEi1U57=vMzNY7HVjTGw@mail.gmail.com>
Hi Krzysztof,
On Wed, 5 Dec 2018 at 21:49, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Wed, 5 Dec 2018 at 17:11, Anand Moon <linux.amoon@gmail.com> wrote:
> >
> > Hi Krzysztof,
> >
> > Thanks for your review.
> > .
> > On Wed, 5 Dec 2018 at 19:36, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> > >
> > > On Tue, 4 Dec 2018 at 20:40, Anand Moon <linux.amoon@gmail.com> wrote:
> > > >
> > > > Add suspend-to-mem node to regulator core to be enabled or disabled
> > > > during system suspend and also support changing the regulator operating
> > > > mode during runtime and when the system enter sleep mode.
> > > >
> > > > Signed-off-by: Anand Moon <linux.amoon@gmail.com>
> > > > ---
> > > > Tested on Odroid U3+
> > > > ---
> > > > .../boot/dts/exynos4412-odroid-common.dtsi | 72 +++++++++++++++++++
> > > > 1 file changed, 72 insertions(+)
> > > >
> > > > diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
> > > > index 2caa3132f34e..837713a2ec3b 100644
> > > > --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
> > > > +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
> > > > @@ -285,6 +285,9 @@
> > > > regulator-min-microvolt = <1800000>;
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > > > + };
> > >
> > > Driver does not support suspend_enable so this will be noop. We could
> > > add this for DT-correctness (and full description of HW) but then I
> > > need explanation why this regulator has to stay on during suspend.
> > >
> >
> > Well I tried to study the suspend/resume feature from
> > *arch/arm/boot/dts/exynos4412-midas.dtsi*
> > and them I tried to apply the same with this on Odroid-U3 boards and
> > test these changes.
>
> Midas DTSI clearly has bugs then.
>
> >
> > > > };
> > > >
> > > > ldo3_reg: LDO3 {
> > > > @@ -292,6 +295,9 @@
> > > > regulator-min-microvolt = <1800000>;
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > >
> > > The same but with suspend_disable.
> > >
> > > I am not saying that these are wrong but I would be happy to see
> > > explanations why you chosen these particular properties.
> > >
> >
> > Well I was not aware on the regulator-always-on cannot be set to off
> > in suspend mode.
> > Will drop this in the future patch where regulator-always-on; is set.
> >
> > > > };
> > > >
> > > > ldo4_reg: LDO4 {
> > > > @@ -299,6 +305,9 @@
> > > > regulator-min-microvolt = <2800000>;
> > > > regulator-max-microvolt = <2800000>;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo5_reg: LDO5 {
> > > > @@ -307,6 +316,9 @@
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo6_reg: LDO6 {
> > > > @@ -314,6 +326,9 @@
> > > > regulator-min-microvolt = <1000000>;
> > > > regulator-max-microvolt = <1000000>;
> > > > regulator-always-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo7_reg: LDO7 {
> > > > @@ -321,18 +336,27 @@
> > > > regulator-min-microvolt = <1000000>;
> > > > regulator-max-microvolt = <1000000>;
> > > > regulator-always-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo8_reg: LDO8 {
> > > > regulator-name = "VDD10_HDMI_1.0V";
> > > > regulator-min-microvolt = <1000000>;
> > > > regulator-max-microvolt = <1000000>;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo10_reg: LDO10 {
> > > > regulator-name = "VDDQ_MIPIHSI_1.8V";
> > > > regulator-min-microvolt = <1800000>;
> > > > regulator-max-microvolt = <1800000>;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo11_reg: LDO11 {
> > > > @@ -340,6 +364,9 @@
> > > > regulator-min-microvolt = <1800000>;
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo12_reg: LDO12 {
> > > > @@ -348,6 +375,9 @@
> > > > regulator-max-microvolt = <3300000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo13_reg: LDO13 {
> > > > @@ -356,6 +386,9 @@
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo14_reg: LDO14 {
> > > > @@ -364,6 +397,9 @@
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo15_reg: LDO15 {
> > > > @@ -372,6 +408,9 @@
> > > > regulator-max-microvolt = <1000000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo16_reg: LDO16 {
> > > > @@ -380,6 +419,9 @@
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo20_reg: LDO20 {
> > > > @@ -387,6 +429,9 @@
> > > > regulator-min-microvolt = <1800000>;
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > ldo21_reg: LDO21 {
> > > > @@ -394,6 +439,9 @@
> > > > regulator-min-microvolt = <2800000>;
> > > > regulator-max-microvolt = <2800000>;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > >
> > > That's unusual setting... enabled in suspend but not necessarily
> > > during work (no always-on).
> > >
> >
> > I kept the regulator required for emmc/sd card in
> > regulator-on-in-suspend in suspend mode.
> >
> > > > + };
> > > > };
> > > >
> > > > ldo22_reg: LDO22 {
> > > > @@ -411,6 +459,9 @@
> > > > regulator-max-microvolt = <1800000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > buck1_reg: BUCK1 {
> > > > @@ -419,6 +470,9 @@
> > > > regulator-max-microvolt = <1100000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > > > + };
> > >
> > > This is seriously wrong so I have doubts whether you tested the
> > > changes or you know what is happening with them. If you turn off
> > > memory bus regulator off, how the memory will work in
> > > Suspend-to-Memory mode?
> > >
> >
> > Well I did not find any issue in my testing but I might be wrong.
> > Ok I will drop this changes in the next version of the patch where
> > regulator-always-on is set.
>
> It worked fine because regulator-off-in-suspend is noop for buck1 but
> it is clearly wrong from logical point of view. Do you think that
> memory should be off in Suspend to RAM?
>
> > > > };
> > > >
> > > > buck2_reg: BUCK2 {
> > > > @@ -427,6 +481,9 @@
> > > > regulator-max-microvolt = <1350000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-on-in-suspend;
> > > > + };
> > > > };
> > > >
> > > > buck3_reg: BUCK3 {
> > > > @@ -435,6 +492,9 @@
> > > > regulator-max-microvolt = <1050000>;
> > > > regulator-always-on;
> > > > regulator-boot-on;
> > > > + regulator-state-mem {
> > > > + regulator-off-in-suspend;
> > >
> > > Looks suspicious as well.
> >
> > Ok I will drop this changes in the next version of the patch where
> > regulator-always-on is set.
> >
> > >
> > > Best regards,
> > > Krzysztof
> > >
> >
> > Well I have tested this patch as following
> > with only one issue, before enable suspend number of On-line cpu is 4
> > after resume number of On-line cpu is 1.
>
> If before your change number of resumed CPUs was 4, then you
> apparently break some things.
>
No bring of secondary cpu's is broken. I have check this without my dts changes.
[root@archlinux-u3 alarm]# echo 1 > /sys/power/pm_debug_messages
[root@archlinux-u3 alarm]# echo +30 > /sys/class/rtc/rtc0/wakealarm
[root@archlinux-u3 alarm]# echo -n mem > /sys/power/state
[ 86.594308] PM: suspend entry (deep)
[ 86.594762] PM: Syncing filesystems ... done.
[ 86.899480] Freezing user space processes ... (elapsed 0.009 seconds) done.
[ 86.911830] OOM killer disabled.
[ 86.914121] Freezing remaining freezable tasks ... (elapsed 0.002
seconds) done.
[ 86.921412] printk: Suspending console(s) (use no_console_suspend to debug)
[ 86.971761] smsc95xx 1-2:1.0 eth0: entering SUSPEND2 mode
[ 87.003552] dwc2 12480000.hsotg: suspending usb gadget g_ether
[ 87.004504] dwc2 12480000.hsotg: dwc2_hsotg_ep_disable: called for ep0
[ 87.004521] dwc2 12480000.hsotg: dwc2_hsotg_ep_disable: called for ep0
[ 87.004594] dwc2 12480000.hsotg: new device is full-speed
[ 87.006402] wake enabled for irq 119
[ 87.006503] BUCK9: No configuration
[ 87.006592] BUCK8_P3V3: No configuration
[ 87.006631] BUCK7_2.0V: No configuration
[ 87.006667] BUCK6_1.35V: No configuration
[ 87.006703] VDDQ_CKEM1_2_1.2V: No configuration
[ 87.006830] LDO26: No configuration
[ 87.006868] VDDQ_LCD_1.8V: No configuration
[ 87.006905] LDO24: No configuration
[ 87.006939] LDO23: No configuration
[ 87.006977] LDO22_VDDQ_MMC4_2.8V: No configuration
[ 87.007013] TFLASH_2.8V: No configuration
[ 87.007048] LDO20_1.8V: No configuration
[ 87.007083] LDO19: No configuration
[ 87.007119] LDO18: No configuration
[ 87.007154] LDO17: No configuration
[ 87.007190] VDD18_HSIC_1.8V: No configuration
[ 87.007226] VDD10_HSIC_1.0V: No configuration
[ 87.007262] VDD18_ABB0_2_1.8V: No configuration
[ 87.007298] VDDQ_C2C_W_1.8V: No configuration
[ 87.007333] VDD33_USB_3.3V: No configuration
[ 87.007369] VDD18_ABB1_1.8V: No configuration
[ 87.007405] VDDQ_MIPIHSI_1.8V: No configuration
[ 87.007441] LDO9: No configuration
[ 87.007477] VDD10_HDMI_1.0V: No configuration
[ 87.007512] VDD10_XPLL_1.0V: No configuration
[ 87.007548] VDD10_MPLL_1.0V: No configuration
[ 87.007583] VDDQ_MMC1_3_1.8V: No configuration
[ 87.007619] VDDQ_MMC2_2.8V: No configuration
[ 87.007655] VDDQ_EXT_1.8V: No configuration
[ 87.007691] VDDQ_M1_2_1.8V: No configuration
[ 87.007727] VDD_ALIVE_1.0V: No configuration
[ 87.014494] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[ 87.024071] usb3503 0-0008: switched to STANDBY mode
[ 87.024739] wake enabled for irq 123
[ 87.066437] samsung-pinctrl 11000000.pinctrl: Setting external
wakeup interrupt mask: 0xfbfff7ff
[ 87.086663] Disabling non-boot CPUs ...
[ 87.230744] Enabling non-boot CPUs ...
[ 88.229226] CPU1: failed to boot: -110
[ 88.231113] Error taking CPU1 up: -110
[ 88.234223] ------------[ cut here ]------------
[ 88.234267] WARNING: CPU: 2 PID: 0 at
arch/arm/include/asm/proc-fns.h:126 secondary_start_kernel+0x214/0x270
[ 88.234273] Modules linked in:
[ 89.229219] CPU2: failed to boot: -110
[ 89.230012] Error taking CPU2 up: -110
[ 90.229071] CPU3: failed to boot: -110
[ 90.229823] Error taking CPU3 up: -110
[ 90.234887] s3c-i2c 13860000.i2c: slave address 0x00
[ 90.234917] s3c-i2c 13860000.i2c: bus frequency set to 390 KHz
[ 90.234955] s3c-i2c 13870000.i2c: slave address 0x00
[ 90.234975] s3c-i2c 13870000.i2c: bus frequency set to 97 KHz
[ 90.235012] s3c-i2c 13880000.i2c: slave address 0x00
[ 90.235031] s3c-i2c 13880000.i2c: bus frequency set to 97 KHz
[ 90.235067] s3c-i2c 138e0000.i2c: slave address 0x00
[ 90.235086] s3c-i2c 138e0000.i2c: bus frequency set to 97 KHz
[ 90.255430] s3c-rtc 10070000.rtc: rtc disabled, re-enabling
[ 90.255985] usb usb1: root hub lost power or was reset
[ 90.261948] s3c2410-wdt 10060000.watchdog: watchdog disabled
[ 90.262139] wake disabled for irq 123
[ 90.273868] usb3503 0-0008: switched to HUB mode
[ 90.364530] wake disabled for irq 119
[ 90.364688] dwc2 12480000.hsotg: resuming usb gadget g_ether
[ 90.649045] usb 1-2: reset high-speed USB device number 2 using exynos-ehci
[ 91.001232] usb 1-3: reset high-speed USB device number 3 using exynos-ehci
[ 91.539004] usb 1-3.3: reset high-speed USB device number 4 using exynos-ehci
[ 92.027260] OOM killer enabled.
[ 92.030413] Restarting tasks ... done.
[ 92.078154] PM: suspend exit
[root@archlinux-u3 alarm]# [ 92.451624] smsc95xx 1-2:1.0 eth0: link
up, 100Mbps, full-duplex, lpa 0xC5E1
Here is the summary of the regulator to be turned off during suspend
regulator-off-in-suspend
LDO1, LDO2, LDO3, LDO6, LDO7, LDO8, LDO10, LDO11, LDO12, LDO13, LDO14,
LDO15, LDO16, LDO20, LDO21, LDO22, LDO25,BUCK4, BUCK5, BUCK6, BUCK7,
regulator-on-in-suspend
LDO4, LDO5, LD021, BUCK1, BUCK2, BUCK3.
Please let me know if this would be fine with you, so that I could
send patch v2.
Best Regards
-Anand
_______________________________________________
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 1/4] ARM: dts: imx6qdl-sabresd: Move regulators outside of "simple-bus"
From: Shawn Guo @ 2018-12-06 7:48 UTC (permalink / raw)
To: Anson Huang
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org,
s.hauer@pengutronix.de, linux-kernel@vger.kernel.org,
robh+dt@kernel.org, dl-linux-imx, kernel@pengutronix.de,
Fabio Estevam, linux-arm-kernel@lists.infradead.org
In-Reply-To: <1544060203-22163-1-git-send-email-Anson.Huang@nxp.com>
On Thu, Dec 06, 2018 at 01:42:30AM +0000, Anson Huang wrote:
> From: Fabio Estevam <festevam@gmail.com>
>
> It is not recommended to place regulators inside "simple-bus", so move
> them out to make it cleaner the addition of new regulators.
>
> Signed-off-by: Fabio Estevam <festevam@gmail.com>
Applied all, thanks.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] PCI: controller: dwc: Make PCI_IMX6 depend on PCIEPORTBUS
From: Andrey Smirnov @ 2018-12-06 7:45 UTC (permalink / raw)
To: linux-pci
Cc: A.s. Dong, Richard Zhu, linux-arm-kernel, Andrey Smirnov,
linux-kernel, linux-imx, bhelgaas, Leonard Crestez, cphealy,
l.stach
Building a kernel with CONFIG_PCI_IMX6=y, but CONFIG_PCIEPORTBUS=n
produces a system where built-in PCIE bridge (16c3:abcd) isn't bound
to pcieport driver. This, in turn, results in a PCIE bus that is
capable of enumerating attached PCIE device, but lacks functional
interrupt support.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
Assuming this is a reasonable dependency, shold this be done to more
than just i.MX6 driver?
drivers/pci/controller/dwc/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 2b139acccf32..44ededbeab85 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -92,6 +92,7 @@ config PCI_IMX6
bool "Freescale i.MX6 PCIe controller"
depends on SOC_IMX8MQ || SOC_IMX6Q || (ARM && COMPILE_TEST)
depends on PCI_MSI_IRQ_DOMAIN
+ depends on PCIEPORTBUS
select PCIE_DW_HOST
config PCIE_SPEAR13XX
--
2.19.1
_______________________________________________
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 v2 1/3] ARM: dts: imx53-voipac-dmm-668: Fix memory node duplication
From: Shawn Guo @ 2018-12-06 7:43 UTC (permalink / raw)
To: marcofrk; +Cc: robh, Marco Franchi, festevam, kernel, linux-arm-kernel
In-Reply-To: <20181205181003.30404-1-marcofrk@gmail.com>
On Wed, Dec 05, 2018 at 04:10:01PM -0200, marcofrk@gmail.com wrote:
> From: Fabio Estevam <festevam@gmail.com>
>
> imx53-voipac-dmm-668 has two memory nodes, but the correct representation
> would be to use a single one with two reg entries - one for each RAM chip
> select, so fix it accordingly.
>
> Reported-by: Marco Franchi <marco.franchi@nxp.com>
> Signed-off-by: Fabio Estevam <festevam@gmail.com>
> Signed-off-by: Marco Franchi <marco.franchi@nxp.com>
Applied all, thanks.
_______________________________________________
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 04/14] dt-bindings: timer: Add Milbeaut M10V timer description
From: Sugaya, Taichi @ 2018-12-06 7:42 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, devicetree, Masami Hiramatsu, Stephen Boyd,
Greg Kroah-Hartman, Michael Turquette, Daniel Lezcano,
linux-kernel, Russell King, Jassi Brar, linux-serial, Jiri Slaby,
Thomas Gleixner, linux-clk, linux-arm-kernel
In-Reply-To: <20181204230354.GA26204@bogus>
Hi,
Thank you for your comments.
On 2018/12/05 8:03, Rob Herring wrote:
> On Mon, Nov 19, 2018 at 10:01:09AM +0900, Sugaya Taichi wrote:
>> Add DT bindings document for Milbeaut M10V timer.
>>
>> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com>
>> ---
>> .../bindings/timer/socionext,milbeaut-timer.txt | 17 +++++++++++++++++
>> 1 file changed, 17 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/timer/socionext,milbeaut-timer.txt
>>
>> diff --git a/Documentation/devicetree/bindings/timer/socionext,milbeaut-timer.txt b/Documentation/devicetree/bindings/timer/socionext,milbeaut-timer.txt
>> new file mode 100644
>> index 0000000..ddb1b31
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/timer/socionext,milbeaut-timer.txt
>> @@ -0,0 +1,17 @@
>> +Milbeaut SoCs Timer Controller
>> +
>> +Required properties:
>> +
>> +- compatible : should be "socionext,milbeaut-m10v-timer"
>> +- reg : Specifies base physical address and size of the registers.
>
> How many register ranges? Looks like 2.
Yes, has two ranges.
So add the description about it.
>
>> +- interrupts : The interrupt of the first timer
>> +- clocks: should be "rclk"
>> +
>> +Example:
>> +
>> +timer {
>
> timer@1e000050
Okay.
Thanks
Sugaya Taichi
>
>> + compatible = "socionext,milbeaut-m10v-timer";
>> + reg = <0x1e000050 0x10>, <0x1e000060 0x10>;
>> + interrupts = <0 91 4>;
>> + clocks = <&rclk>;
>> +};
>> --
>> 1.9.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 v2 3/3] PCI: imx: Add support for i.MX8MQ
From: Andrey Smirnov @ 2018-12-06 7:35 UTC (permalink / raw)
To: linux-pci
Cc: A.s. Dong, Mark Rutland, Richard Zhu, linux-arm-kernel,
Rob Herring, Andrey Smirnov, linux-kernel, Fabio Estevam,
devicetree, linux-imx, bhelgaas, Leonard Crestez, cphealy,
l.stach
In-Reply-To: <20181206073545.10967-1-andrew.smirnov@gmail.com>
Add code needed to support i.MX8MQ variant.
Cc: bhelgaas@google.com
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: cphealy@gmail.com
Cc: l.stach@pengutronix.de
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Cc: "A.s. Dong" <aisheng.dong@nxp.com>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: linux-imx@nxp.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Rob Herring <robh@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
.../bindings/pci/fsl,imx6q-pcie.txt | 6 +-
drivers/pci/controller/dwc/Kconfig | 2 +-
drivers/pci/controller/dwc/pci-imx6.c | 85 +++++++++++++++++--
3 files changed, 86 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
index f37494d5a7be..40b46d11e7e7 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
@@ -9,6 +9,7 @@ Required properties:
- "fsl,imx6sx-pcie",
- "fsl,imx6qp-pcie"
- "fsl,imx7d-pcie"
+ - "fsl,imx8mq-pcie"
- reg: base address and length of the PCIe controller
- interrupts: A list of interrupt outputs of the controller. Must contain an
entry for each entry in the interrupt-names property.
@@ -43,7 +44,7 @@ Additional required properties for imx6sx-pcie:
- "pcie_inbound_axi"
- power-domains: Must be set to a phandle pointing to the PCIE_PHY power domain
-Additional required properties for imx7d-pcie:
+Additional required properties for imx7d-pcie and imx8mq-pcie:
- power-domains: Must be set to a phandle pointing to PCIE_PHY power domain
- resets: Must contain phandles to PCIe-related reset lines exposed by SRC
IP block
@@ -52,6 +53,9 @@ Additional required properties for imx7d-pcie:
- "apps"
- "turnoff"
+Additional required properties for imx8mq-pcie:
+- fsl,controller-id: Logical ID of a given PCIE controller. PCIE1 is 0, PCIE2 is 1;
+
Example:
pcie@01000000 {
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 91b0194240a5..2b139acccf32 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -90,7 +90,7 @@ config PCI_EXYNOS
config PCI_IMX6
bool "Freescale i.MX6 PCIe controller"
- depends on SOC_IMX6Q || (ARM && COMPILE_TEST)
+ depends on SOC_IMX8MQ || SOC_IMX6Q || (ARM && COMPILE_TEST)
depends on PCI_MSI_IRQ_DOMAIN
select PCIE_DW_HOST
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 3c3002861d25..326f71698ac2 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -8,6 +8,7 @@
* Author: Sean Cross <xobs@kosagi.com>
*/
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
@@ -30,6 +31,11 @@
#include "pcie-designware.h"
+#define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9)
+#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN BIT(10)
+#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE BIT(11)
+#define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE GENMASK(11, 8)
+
#define to_imx6_pcie(x) dev_get_drvdata((x)->dev)
enum imx6_pcie_variants {
@@ -37,6 +43,7 @@ enum imx6_pcie_variants {
IMX6SX,
IMX6QP,
IMX7D,
+ IMX8MQ,
};
struct imx6_pcie {
@@ -48,6 +55,7 @@ struct imx6_pcie {
struct clk *pcie_inbound_axi;
struct clk *pcie;
struct regmap *iomuxc_gpr;
+ u32 controller_id;
struct reset_control *pciephy_reset;
struct reset_control *apps_reset;
struct reset_control *turnoff_reset;
@@ -245,7 +253,8 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
{
u32 tmp;
- if (imx6_pcie->variant == IMX7D)
+ if (imx6_pcie->variant == IMX7D ||
+ imx6_pcie->variant == IMX8MQ)
return;
pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp);
@@ -261,6 +270,7 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp);
}
+#ifdef CONFIG_ARM
/* Added for PCI abort handling */
static int imx6q_pcie_abort_handler(unsigned long addr,
unsigned int fsr, struct pt_regs *regs)
@@ -294,6 +304,7 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
return 1;
}
+#endif
static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
@@ -301,6 +312,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
switch (imx6_pcie->variant) {
case IMX7D:
+ case IMX8MQ: /* FALLTHROUGH */
reset_control_assert(imx6_pcie->pciephy_reset);
reset_control_assert(imx6_pcie->apps_reset);
break;
@@ -339,6 +351,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
{
struct dw_pcie *pci = imx6_pcie->pci;
struct device *dev = pci->dev;
+ unsigned int offset;
int ret = 0;
switch (imx6_pcie->variant) {
@@ -369,6 +382,29 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
break;
case IMX7D:
break;
+ case IMX8MQ:
+ switch (imx6_pcie->controller_id) {
+ case 0:
+ offset = IOMUXC_GPR14;
+ break;
+ case 1:
+ offset = IOMUXC_GPR16;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * Set the over ride low and enabled
+ * make sure that REF_CLK is turned on.
+ */
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, offset,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE,
+ 0);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, offset,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
+ IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN);
+ break;
}
return ret;
@@ -445,6 +481,9 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
}
switch (imx6_pcie->variant) {
+ case IMX8MQ:
+ reset_control_deassert(imx6_pcie->pciephy_reset);
+ break;
case IMX7D:
reset_control_deassert(imx6_pcie->pciephy_reset);
imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
@@ -482,7 +521,34 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
+ unsigned int mask, val, offset;
+
+ mask = IMX6Q_GPR12_DEVICE_TYPE;
+ val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT);
+
switch (imx6_pcie->variant) {
+ case IMX8MQ:
+ switch (imx6_pcie->controller_id) {
+ case 0:
+ offset = IOMUXC_GPR14;
+ break;
+ case 1:
+ offset = IOMUXC_GPR16;
+ mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE;
+ val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
+ PCI_EXP_TYPE_ROOT_PORT);
+ break;
+ default:
+ return;
+ }
+ /*
+ * TODO: Currently this code assumes external
+ * oscillator is being used
+ */
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, offset,
+ IMX8MQ_GPR_PCIE_REF_USE_PAD,
+ IMX8MQ_GPR_PCIE_REF_USE_PAD);
+ break;
case IMX7D:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
@@ -518,8 +584,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
break;
}
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val);
}
static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
@@ -528,7 +593,8 @@ static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
int mult, div;
u32 val;
- if (imx6_pcie->variant == IMX7D)
+ if (imx6_pcie->variant == IMX7D ||
+ imx6_pcie->variant == IMX8MQ)
return 0;
switch (phy_rate) {
@@ -616,6 +682,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
IMX6Q_GPR12_PCIE_CTL_2);
break;
case IMX7D:
+ case IMX8MQ: /* FALLTHROUGH */
reset_control_deassert(imx6_pcie->apps_reset);
break;
}
@@ -870,6 +937,10 @@ static int imx6_pcie_probe(struct platform_device *pdev)
imx6_pcie->variant =
(enum imx6_pcie_variants)of_device_get_match_data(dev);
+ if (of_property_read_u32(node, "fsl,controller-id",
+ &imx6_pcie->controller_id))
+ imx6_pcie->controller_id = 0;
+
dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
if (IS_ERR(pci->dbi_base))
@@ -921,7 +992,8 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx6_pcie->pcie_inbound_axi);
}
break;
- case IMX7D:
+ case IMX8MQ:
+ case IMX7D: /* FALLTHROUGH */
imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev,
"pciephy");
if (IS_ERR(imx6_pcie->pciephy_reset)) {
@@ -1011,6 +1083,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
{ .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, },
{ .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
{ .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, },
+ { .compatible = "fsl,imx8mq-pcie", .data = (void *)IMX8MQ, } ,
{},
};
@@ -1027,6 +1100,7 @@ static struct platform_driver imx6_pcie_driver = {
static int __init imx6_pcie_init(void)
{
+#ifdef CONFIG_ARM
/*
* Since probe() can be deferred we need to make sure that
* hook_fault_code is not called after __init memory is freed
@@ -1036,6 +1110,7 @@ static int __init imx6_pcie_init(void)
*/
hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0,
"external abort on non-linefetch");
+#endif
return platform_driver_register(&imx6_pcie_driver);
}
--
2.19.1
_______________________________________________
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 v2] ARM: dts: imx7d-nitrogen7: Fix the description of the Wifi clock
From: Shawn Guo @ 2018-12-06 7:38 UTC (permalink / raw)
To: Fabio Estevam; +Cc: gary.bisson, linux-arm-kernel, troy.kisky
In-Reply-To: <1544007930-16670-1-git-send-email-festevam@gmail.com>
On Wed, Dec 05, 2018 at 09:05:30AM -0200, Fabio Estevam wrote:
> According to bindings/regulator/fixed-regulator.txt the 'clocks' and
> 'clock-names' properties are not valid ones.
>
> In order to turn on the Wifi clock the correct location for describing
> the CLKO2 clock is via a mmc-pwrseq handle, so do it accordingly.
>
> Fixes: 56354959cfec ("ARM: dts: imx: add Boundary Devices Nitrogen7 board")
> Signed-off-by: Fabio Estevam <festevam@gmail.com>
> Acked-by: Troy Kisky <troy.kisky@boundarydevices.com>
Applied, thanks.
_______________________________________________
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] ARM: dts: imx6qdl-sabresd: add egalax touch screen support on i2c2 bus
From: Shawn Guo @ 2018-12-06 7:35 UTC (permalink / raw)
To: Anson Huang
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org,
s.hauer@pengutronix.de, linux-kernel@vger.kernel.org,
robh+dt@kernel.org, dl-linux-imx, kernel@pengutronix.de,
Fabio Estevam, linux-arm-kernel@lists.infradead.org
In-Reply-To: <1543972116-22505-1-git-send-email-Anson.Huang@nxp.com>
On Wed, Dec 05, 2018 at 01:14:25AM +0000, Anson Huang wrote:
> Add egalax touch screen support on i2c2 bus, it is connected
> to LVDS0, while the existing one on i2c3 bus is connected to
> LVDS1.
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Applied, thanks.
_______________________________________________
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