* [PATCH] KVM: arm/arm64: vgic: Prevent access to invalid SPIs
From: Marc Zyngier @ 2016-10-28 10:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Andre Przywara <andre.przywara@arm.com>
In our VGIC implementation we limit the number of SPIs to a number
that the userland application told us. Accordingly we limit the
allocation of memory for virtual IRQs to that number.
However in our MMIO dispatcher we didn't check if we ever access an
IRQ beyond that limit, leading to out-of-bound accesses.
Add a test against the number of allocated SPIs in check_region().
[maz: cleaned-up original patch]
Cc: stable at vger.kernel.org
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
virt/kvm/arm/vgic/vgic-mmio.c | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index e18b30d..ebe1b9f 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -453,17 +453,33 @@ struct vgic_io_device *kvm_to_vgic_iodev(const struct kvm_io_device *dev)
return container_of(dev, struct vgic_io_device, dev);
}
-static bool check_region(const struct vgic_register_region *region,
+static bool check_region(const struct kvm *kvm,
+ const struct vgic_register_region *region,
gpa_t addr, int len)
{
- if ((region->access_flags & VGIC_ACCESS_8bit) && len == 1)
- return true;
- if ((region->access_flags & VGIC_ACCESS_32bit) &&
- len == sizeof(u32) && !(addr & 3))
- return true;
- if ((region->access_flags & VGIC_ACCESS_64bit) &&
- len == sizeof(u64) && !(addr & 7))
- return true;
+ int flags, nr_irqs = kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
+
+ switch (len) {
+ case sizeof(u8):
+ flags = VGIC_ACCESS_8bit;
+ break;
+ case sizeof(u32):
+ flags = VGIC_ACCESS_32bit;
+ break;
+ case sizeof(u64):
+ flags = VGIC_ACCESS_64bit;
+ break;
+ default:
+ return false;
+ }
+
+ if ((region->access_flags & flags) && IS_ALIGNED(addr, len)) {
+ if (!region->bits_per_irq)
+ return true;
+
+ /* Do we access a non-allocated IRQ? */
+ return VGIC_ADDR_TO_INTID(addr, region->bits_per_irq) < nr_irqs;
+ }
return false;
}
@@ -477,7 +493,7 @@ static int dispatch_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
addr - iodev->base_addr);
- if (!region || !check_region(region, addr, len)) {
+ if (!region || !check_region(vcpu->kvm, region, addr, len)) {
memset(val, 0, len);
return 0;
}
@@ -510,10 +526,7 @@ static int dispatch_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
addr - iodev->base_addr);
- if (!region)
- return 0;
-
- if (!check_region(region, addr, len))
+ if (!region || !check_region(vcpu->kvm, region, addr, len))
return 0;
switch (iodev->iodev_type) {
--
2.1.4
^ permalink raw reply related
* [PATCH v4] drivers: psci: PSCI checker module
From: Kevin Brodsky @ 2016-10-28 10:31 UTC (permalink / raw)
To: linux-arm-kernel
On arm and arm64, PSCI is one of the possible firmware interfaces
used for power management. This includes both turning CPUs on and off,
and suspending them (entering idle states).
This patch adds a PSCI checker module that enables basic testing of
PSCI operations during startup. There are two main tests: CPU
hotplugging and suspending.
In the hotplug tests, the hotplug API is used to turn off and on again
all CPUs in the system, and then all CPUs in each cluster, checking
the consistency of the return codes.
In the suspend tests, a high-priority thread is created on each core
and uses low-level cpuidle functionalities to enter suspend, in all
the possible states and multiple times. This should allow a maximum
number of CPUs to enter the same sleep state at the same or slightly
different time.
In essence, the suspend tests use a principle similar to that of the
intel_powerclamp driver (drivers/thermal/intel_powerclamp.c), but the
threads are only kept for the duration of the test (they are already
gone when userspace is started).
While in theory power management PSCI functions (CPU_{ON,OFF,SUSPEND})
could be directly called, this proved too difficult as it would imply
the duplication of all the logic used by the kernel to allow for a
clean shutdown/bringup/suspend of the CPU (the deepest sleep states
implying potentially the shutdown of the CPU).
Note that this file cannot be compiled as a loadable module, since it
uses a number of non-exported identifiers (essentially for
PSCI-specific checks and direct use of cpuidle) and relies on the
absence of userspace to avoid races when calling hotplug and cpuidle
functions.
For now at least, CONFIG_PSCI_CHECKER is mutually exclusive with
CONFIG_TORTURE_TEST, because torture tests may also use hotplug and
cause false positives in the hotplug tests.
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kevin Hilman <khilman@kernel.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
Changelog v3..v4:
* Prevent enabling CONFIG_PSCI_CHECKER if CONFIG_TORTURE_TEST is
selected, to avoid any interference during hotplug operations. Both
could potentially be made to work together subsequently.
Cheers,
Kevin
drivers/firmware/Kconfig | 11 +
drivers/firmware/Makefile | 1 +
drivers/firmware/psci_checker.c | 488 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 500 insertions(+)
create mode 100644 drivers/firmware/psci_checker.c
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index bca172d42c74..3b526291c1a6 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -206,6 +206,17 @@ config QCOM_SCM_64
config HAVE_ARM_SMCCC
bool
+config PSCI_CHECKER
+ bool "PSCI checker"
+ depends on ARM_PSCI_FW && HOTPLUG_CPU && !TORTURE_TEST
+ help
+ Run the PSCI checker during startup. This checks that hotplug and
+ suspend operations work correctly when using PSCI.
+
+ The torture tests may interfere with the PSCI checker by turning CPUs
+ on and off through hotplug, so for now torture tests and PSCI checker
+ are mutually exclusive.
+
source "drivers/firmware/broadcom/Kconfig"
source "drivers/firmware/google/Kconfig"
source "drivers/firmware/efi/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 898ac41fa8b3..e7248eacc796 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_QCOM_SCM) += qcom_scm.o
obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o
obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o
CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
+obj-$(CONFIG_PSCI_CHECKER) += psci_checker.o
obj-y += broadcom/
obj-y += meson/
diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c
new file mode 100644
index 000000000000..a49794a50ed6
--- /dev/null
+++ b/drivers/firmware/psci_checker.c
@@ -0,0 +1,488 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/atomic.h>
+#include <linux/completion.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/psci.h>
+#include <linux/slab.h>
+#include <linux/tick.h>
+#include <linux/topology.h>
+
+#include <asm/cpuidle.h>
+
+#include <uapi/linux/psci.h>
+
+#define NUM_SUSPEND_CYCLE (10)
+
+static unsigned int nb_available_cpus;
+static int tos_resident_cpu = -1;
+
+static atomic_t nb_active_threads;
+static struct completion suspend_threads_started =
+ COMPLETION_INITIALIZER(suspend_threads_started);
+static struct completion suspend_threads_done =
+ COMPLETION_INITIALIZER(suspend_threads_done);
+
+/*
+ * We assume that PSCI operations are used if they are available. This is not
+ * necessarily true on arm64, since the decision is based on the
+ * "enable-method" property of each CPU in the DT, but given that there is no
+ * arch-specific way to check this, we assume that the DT is sensible.
+ */
+static int psci_ops_check(void)
+{
+ int migrate_type = -1;
+ int cpu;
+
+ if (!(psci_ops.cpu_off && psci_ops.cpu_on && psci_ops.cpu_suspend)) {
+ pr_warn("Missing PSCI operations, aborting tests\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (psci_ops.migrate_info_type)
+ migrate_type = psci_ops.migrate_info_type();
+
+ if (migrate_type == PSCI_0_2_TOS_UP_MIGRATE ||
+ migrate_type == PSCI_0_2_TOS_UP_NO_MIGRATE) {
+ /* There is a UP Trusted OS, find on which core it resides. */
+ for_each_online_cpu(cpu)
+ if (psci_tos_resident_on(cpu)) {
+ tos_resident_cpu = cpu;
+ break;
+ }
+ if (tos_resident_cpu == -1)
+ pr_warn("UP Trusted OS resides on no online CPU\n");
+ }
+
+ return 0;
+}
+
+static int find_clusters(const struct cpumask *cpus,
+ const struct cpumask **clusters)
+{
+ unsigned int nb = 0;
+ cpumask_var_t tmp;
+
+ if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
+ return -ENOMEM;
+ cpumask_copy(tmp, cpus);
+
+ while (!cpumask_empty(tmp)) {
+ const struct cpumask *cluster =
+ topology_core_cpumask(cpumask_any(tmp));
+
+ clusters[nb++] = cluster;
+ cpumask_andnot(tmp, tmp, cluster);
+ }
+
+ free_cpumask_var(tmp);
+ return nb;
+}
+
+/*
+ * offlined_cpus is a temporary array but passing it as an argument avoids
+ * multiple allocations.
+ */
+static unsigned int down_and_up_cpus(const struct cpumask *cpus,
+ struct cpumask *offlined_cpus)
+{
+ int cpu;
+ int err = 0;
+
+ cpumask_clear(offlined_cpus);
+
+ /* Try to power down all CPUs in the mask. */
+ for_each_cpu(cpu, cpus) {
+ int ret = cpu_down(cpu);
+
+ /*
+ * cpu_down() checks the number of online CPUs before the TOS
+ * resident CPU.
+ */
+ if (cpumask_weight(offlined_cpus) + 1 == nb_available_cpus) {
+ if (ret != -EBUSY) {
+ pr_err("Unexpected return code %d while trying "
+ "to power down last online CPU %d\n",
+ ret, cpu);
+ ++err;
+ }
+ } else if (cpu == tos_resident_cpu) {
+ if (ret != -EPERM) {
+ pr_err("Unexpected return code %d while trying "
+ "to power down TOS resident CPU %d\n",
+ ret, cpu);
+ ++err;
+ }
+ } else if (ret != 0) {
+ pr_err("Error occurred (%d) while trying "
+ "to power down CPU %d\n", ret, cpu);
+ ++err;
+ }
+
+ if (ret == 0)
+ cpumask_set_cpu(cpu, offlined_cpus);
+ }
+
+ /* Try to power up all the CPUs that have been offlined. */
+ for_each_cpu(cpu, offlined_cpus) {
+ int ret = cpu_up(cpu);
+
+ if (ret != 0) {
+ pr_err("Error occurred (%d) while trying "
+ "to power up CPU %d\n", ret, cpu);
+ ++err;
+ } else {
+ cpumask_clear_cpu(cpu, offlined_cpus);
+ }
+ }
+
+ /*
+ * Something went bad at some point and some CPUs could not be turned
+ * back on.
+ */
+ WARN_ON(!cpumask_empty(offlined_cpus) ||
+ num_online_cpus() != nb_available_cpus);
+
+ return err;
+}
+
+static int hotplug_tests(void)
+{
+ int err;
+ cpumask_var_t offlined_cpus;
+ int i, nb_cluster;
+ const struct cpumask **clusters;
+ char *page_buf;
+
+ err = -ENOMEM;
+ if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
+ return err;
+ /* We may have up to nb_available_cpus clusters. */
+ clusters = kmalloc_array(nb_available_cpus, sizeof(*clusters),
+ GFP_KERNEL);
+ if (!clusters)
+ goto out_free_cpus;
+ page_buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!page_buf)
+ goto out_free_clusters;
+
+ err = 0;
+ nb_cluster = find_clusters(cpu_online_mask, clusters);
+
+ /*
+ * Of course the last CPU cannot be powered down and cpu_down() should
+ * refuse doing that.
+ */
+ pr_info("Trying to turn off and on again all CPUs\n");
+ err += down_and_up_cpus(cpu_online_mask, offlined_cpus);
+
+ /*
+ * Take down CPUs by cluster this time. When the last CPU is turned
+ * off, the cluster itself should shut down.
+ */
+ for (i = 0; i < nb_cluster; ++i) {
+ int cluster_id =
+ topology_physical_package_id(cpumask_any(clusters[i]));
+ ssize_t len = cpumap_print_to_pagebuf(true, page_buf,
+ clusters[i]);
+ /* Remove trailing newline. */
+ page_buf[len - 1] = '\0';
+ pr_info("Trying to turn off and on again cluster %d "
+ "(CPUs %s)\n", cluster_id, page_buf);
+ err += down_and_up_cpus(clusters[i], offlined_cpus);
+ }
+
+ free_page((unsigned long)page_buf);
+out_free_clusters:
+ kfree(clusters);
+out_free_cpus:
+ free_cpumask_var(offlined_cpus);
+ return err;
+}
+
+static void dummy_callback(unsigned long ignored) {}
+
+static int suspend_cpu(int index, bool broadcast)
+{
+ int ret;
+
+ arch_cpu_idle_enter();
+
+ if (broadcast) {
+ /*
+ * The local timer will be shut down, we need to enter tick
+ * broadcast.
+ */
+ ret = tick_broadcast_enter();
+ if (ret) {
+ /*
+ * In the absence of hardware broadcast mechanism,
+ * this CPU might be used to broadcast wakeups, which
+ * may be why entering tick broadcast has failed.
+ * There is little the kernel can do to work around
+ * that, so enter WFI instead (idle state 0).
+ */
+ cpu_do_idle();
+ ret = 0;
+ goto out_arch_exit;
+ }
+ }
+
+ /*
+ * Replicate the common ARM cpuidle enter function
+ * (arm_enter_idle_state).
+ */
+ ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
+
+ if (broadcast)
+ tick_broadcast_exit();
+
+out_arch_exit:
+ arch_cpu_idle_exit();
+
+ return ret;
+}
+
+static int suspend_test_thread(void *arg)
+{
+ int cpu = (long)arg;
+ int i, nb_suspend = 0, nb_shallow_sleep = 0, nb_err = 0;
+ struct sched_param sched_priority = { .sched_priority = MAX_RT_PRIO-1 };
+ struct cpuidle_device *dev;
+ struct cpuidle_driver *drv;
+ /* No need for an actual callback, we just want to wake up the CPU. */
+ struct timer_list wakeup_timer =
+ TIMER_INITIALIZER(dummy_callback, 0, 0);
+
+ /* Wait for the main thread to give the start signal. */
+ wait_for_completion(&suspend_threads_started);
+
+ /* Set maximum priority to preempt all other threads on this CPU. */
+ if (sched_setscheduler_nocheck(current, SCHED_FIFO, &sched_priority))
+ pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
+ cpu);
+
+ dev = this_cpu_read(cpuidle_devices);
+ drv = cpuidle_get_cpu_driver(dev);
+
+ pr_info("CPU %d entering suspend cycles, states 1 through %d\n",
+ cpu, drv->state_count - 1);
+
+ for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) {
+ int index;
+ /*
+ * Test all possible states, except 0 (which is usually WFI and
+ * doesn't use PSCI).
+ */
+ for (index = 1; index < drv->state_count; ++index) {
+ struct cpuidle_state *state = &drv->states[index];
+ bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
+ int ret;
+
+ /*
+ * Set the timer to wake this CPU up in some time (which
+ * should be largely sufficient for entering suspend).
+ * If the local tick is disabled when entering suspend,
+ * suspend_cpu() takes care of switching to a broadcast
+ * tick, so the timer will still wake us up.
+ */
+ mod_timer(&wakeup_timer, jiffies +
+ usecs_to_jiffies(state->target_residency));
+
+ /* IRQs must be disabled during suspend operations. */
+ local_irq_disable();
+
+ ret = suspend_cpu(index, broadcast);
+
+ /*
+ * We have woken up. Re-enable IRQs to handle any
+ * pending interrupt, do not wait until the end of the
+ * loop.
+ */
+ local_irq_enable();
+
+ if (ret == index) {
+ ++nb_suspend;
+ } else if (ret >= 0) {
+ /* We did not enter the expected state. */
+ ++nb_shallow_sleep;
+ } else {
+ pr_err("Failed to suspend CPU %d: error %d "
+ "(requested state %d, cycle %d)\n",
+ cpu, ret, index, i);
+ ++nb_err;
+ }
+ }
+ }
+
+ /*
+ * Disable the timer to make sure that the timer will not trigger
+ * later.
+ */
+ del_timer(&wakeup_timer);
+
+ if (atomic_dec_return_relaxed(&nb_active_threads) == 0)
+ complete(&suspend_threads_done);
+
+ /* Give up on RT scheduling and wait for termination. */
+ sched_priority.sched_priority = 0;
+ if (sched_setscheduler_nocheck(current, SCHED_NORMAL, &sched_priority))
+ pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
+ cpu);
+ for (;;) {
+ /* Needs to be set first to avoid missing a wakeup. */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (kthread_should_stop()) {
+ __set_current_state(TASK_RUNNING);
+ break;
+ }
+ schedule();
+ }
+
+ pr_info("CPU %d suspend test results: success %d, shallow states %d, errors %d\n",
+ cpu, nb_suspend, nb_shallow_sleep, nb_err);
+
+ return nb_err;
+}
+
+static int suspend_tests(void)
+{
+ int i, cpu, err = 0;
+ struct task_struct **threads;
+ int nb_threads = 0;
+
+ threads = kmalloc_array(nb_available_cpus, sizeof(*threads),
+ GFP_KERNEL);
+ if (!threads)
+ return -ENOMEM;
+
+ for_each_online_cpu(cpu) {
+ struct task_struct *thread;
+ /* Check that cpuidle is available on that CPU. */
+ struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+
+ if (cpuidle_not_available(drv, dev)) {
+ pr_warn("cpuidle not available on CPU %d, ignoring\n",
+ cpu);
+ continue;
+ }
+
+ thread = kthread_create_on_cpu(suspend_test_thread,
+ (void *)(long)cpu, cpu,
+ "psci_suspend_test");
+ if (IS_ERR(thread))
+ pr_err("Failed to create kthread on CPU %d\n", cpu);
+ else
+ threads[nb_threads++] = thread;
+ }
+ if (nb_threads < 1) {
+ kfree(threads);
+ return -ENODEV;
+ }
+
+ atomic_set(&nb_active_threads, nb_threads);
+
+ /*
+ * Stop cpuidle to prevent the idle tasks from entering a deep sleep
+ * mode, as it might interfere with the suspend threads on other CPUs.
+ * This does not prevent the suspend threads from using cpuidle (only
+ * the idle tasks check this status).
+ */
+ cpuidle_pause();
+
+ /*
+ * Wake up the suspend threads. To avoid the main thread being preempted
+ * before all the threads have been unparked, the suspend threads will
+ * wait for the completion of suspend_threads_started.
+ */
+ for (i = 0; i < nb_threads; ++i)
+ wake_up_process(threads[i]);
+ complete_all(&suspend_threads_started);
+
+ wait_for_completion(&suspend_threads_done);
+
+ cpuidle_resume();
+
+ /* Stop and destroy all threads, get return status. */
+ for (i = 0; i < nb_threads; ++i)
+ err += kthread_stop(threads[i]);
+
+ kfree(threads);
+ return err;
+}
+
+static int __init psci_checker(void)
+{
+ int ret;
+
+ /*
+ * Since we're in an initcall, we assume that all the CPUs that all
+ * CPUs that can be onlined have been onlined.
+ *
+ * The tests assume that hotplug is enabled but nobody else is using it,
+ * otherwise the results will be unpredictable. However, since there
+ * is no userspace yet in initcalls, that should be fine, as long as
+ * no torture test is running@the same time (see Kconfig).
+ */
+ nb_available_cpus = num_online_cpus();
+
+ /* Check PSCI operations are set up and working. */
+ ret = psci_ops_check();
+ if (ret)
+ return ret;
+
+ pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);
+
+ pr_info("Starting hotplug tests\n");
+ ret = hotplug_tests();
+ if (ret == 0)
+ pr_info("Hotplug tests passed OK\n");
+ else if (ret > 0)
+ pr_err("%d error(s) encountered in hotplug tests\n", ret);
+ else {
+ pr_err("Out of memory\n");
+ return ret;
+ }
+
+ pr_info("Starting suspend tests (%d cycles per state)\n",
+ NUM_SUSPEND_CYCLE);
+ ret = suspend_tests();
+ if (ret == 0)
+ pr_info("Suspend tests passed OK\n");
+ else if (ret > 0)
+ pr_err("%d error(s) encountered in suspend tests\n", ret);
+ else {
+ switch (ret) {
+ case -ENOMEM:
+ pr_err("Out of memory\n");
+ break;
+ case -ENODEV:
+ pr_warn("Could not start suspend tests on any CPU\n");
+ break;
+ }
+ }
+
+ pr_info("PSCI checker completed\n");
+ return ret < 0 ? ret : 0;
+}
+late_initcall(psci_checker);
--
2.10.0
^ permalink raw reply related
* [PATCH v7, 0/8] Add MediaTek USB3 DRD Driver
From: Matthias Brugger @ 2016-10-28 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476844107-31087-1-git-send-email-chunfeng.yun@mediatek.com>
Hi Chunfeng,
On 10/19/2016 04:28 AM, Chunfeng Yun wrote:
> These patches introduce the MediaTek USB3 dual-role controller
> driver.
>
> The driver can be configured as Dual-Role Device (DRD),
> Peripheral Only and Host Only (xHCI) modes. It works well
> with Mass Storage, RNDIS and g_zero on FS/HS and SS. And it is
> tested on MT8173 platform which only contains USB2.0 device IP,
> and on MT6290 platform which contains USB3.0 device IP.
>
> Change in v7:
> 1. split dual-role driver into four patchs
> 2. remove QMU done tasklet
> 3. add a bool in xhci_hcd_mtk to signal absence of IPPC
>
> Change in v6:
> 1. handle endianness of GPD and SETUP data
> 2. remove dummy error log and return suitable error number
> 3. cancel delay work when deregiseter driver
>
> Change in v5:
> 1. modify some comments
> 2. rename some unsuitable variables
> 3. add reg-names property for host node
> 4. add USB_MTU3_DEBUG to control debug messages
>
> Change in v4:
> 1. fix build errors on non-mediatek platforms
> 2. provide manual dual-role switch via debugfs instead of sysfs
>
> Change in v3:
> 1. fix some typo error
> 2. rename mtu3.txt to mt8173-mtu3.txt
>
> Change in v2:
> 1. modify binding docs according to suggestions
> 2. modify some comments and remove some dummy blank lines
> 3. fix memory leakage
>
>
> Chunfeng Yun (8):
> dt-bindings: mt8173-xhci: support host side of dual-role mode
> dt-bindings: mt8173-mtu3: add devicetree bindings
> usb: xhci-mtk: make IPPC register optional
> usb: Add MediaTek USB3 DRD driver
> usb: mtu3: Super-Speed Peripheral mode support
> usb: mtu3: host only mode support
> usb: mtu3: dual-role mode support
> arm64: dts: mediatek: add USB3 DRD driver
>
I tried the driver with my mt8173-evb, but wasn't able to get USB
working (no usb stick detected when adding to the usb port).
# dmesg |grep mtu
[ 0.428420] mtu3 11271000.usb: failed to get vusb33
[ 0.510570] mtu3 11271000.usb: failed to get vbus
[ 0.592103] mtu3 11271000.usb: failed to get vbus
Relevant config options:
CONFIG_USB_MTU3=y
CONFIG_USB_MTU3_HOST=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_PHY_MT65XX_USB3=y
Looks like an error in the device tree. I can see that the mt6397
regulater get's initialized *after* the mtu3 driver:
[ 0.505166] mt6397-regulator mt6397-regulator: Chip ID = 0x4097
Not sure if this is related.
Any idea whats going wrong here?
Cheers,
Matthias
^ permalink raw reply
* [PATCH] drm/mediatek: fix null pointer dereference
From: Matthias Brugger @ 2016-10-28 10:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477643686.17640.3.camel@mtksdaap41>
On 10/28/2016 10:34 AM, CK Hu wrote:
> Hi, Matthias:
>
> Even though OVL HW would not be enabled before component_add() in
> current design, your patch would be safe for any situation.
Maybe the FW I use left an interrupt pending before loading the kernel
and this leads to the case where we enter the handler before all data
structures are set up.
>
> Acked-by CK Hu <ck.hu@mediatek.com>
Thanks!
Matthias
^ permalink raw reply
* [PATCH] arm64: swp emulation: bound LL/SC retries before rescheduling
From: Will Deacon @ 2016-10-28 10:42 UTC (permalink / raw)
To: linux-arm-kernel
commit 1c5b51dfb7b4564008e0cadec5381a69e88b0d21 upstream.
If a CPU does not implement a global monitor for certain memory types,
then userspace can attempt a kernel DoS by issuing SWP instructions
targetting the problematic memory (for example, a framebuffer mapped
with non-cacheable attributes).
The SWP emulation code protects against these sorts of attacks by
checking for pending signals and potentially rescheduling when the STXR
instruction fails during the emulation. Whilst this is good for avoiding
livelock, it harms emulation of legitimate SWP instructions on CPUs
where forward progress is not guaranteed if there are memory accesses to
the same reservation granule (up to 2k) between the failing STXR and
the retry of the LDXR.
This patch solves the problem by retrying the STXR a bounded number of
times (4) before breaking out of the LL/SC loop and looking for
something else to do.
Cc: <stable@vger.kernel.org> # 4.4
Fixes: bd35a4adc413 ("arm64: Port SWP/SWPB emulation support from arm")
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/armv8_deprecated.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index 937f5e58a4d3..8496770723dd 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -280,21 +280,28 @@ static void register_insn_emulation_sysctl(struct ctl_table *table)
/*
* Error-checking SWP macros implemented using ldxr{b}/stxr{b}
*/
-#define __user_swpX_asm(data, addr, res, temp, B) \
+
+/* Arbitrary constant to ensure forward-progress of the LL/SC loop */
+#define __SWP_LL_SC_LOOPS 4
+
+#define __user_swpX_asm(data, addr, res, temp, temp2, B) \
__asm__ __volatile__( \
+ " mov %w3, %w7\n" \
ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, \
CONFIG_ARM64_PAN) \
- "0: ldxr"B" %w2, [%3]\n" \
- "1: stxr"B" %w0, %w1, [%3]\n" \
+ "0: ldxr"B" %w2, [%4]\n" \
+ "1: stxr"B" %w0, %w1, [%4]\n" \
" cbz %w0, 2f\n" \
- " mov %w0, %w4\n" \
+ " sub %w3, %w3, #1\n" \
+ " cbnz %w3, 0b\n" \
+ " mov %w0, %w5\n" \
" b 3f\n" \
"2:\n" \
" mov %w1, %w2\n" \
"3:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
- "4: mov %w0, %w5\n" \
+ "4: mov %w0, %w6\n" \
" b 3b\n" \
" .popsection" \
" .pushsection __ex_table,\"a\"\n" \
@@ -304,14 +311,15 @@ static void register_insn_emulation_sysctl(struct ctl_table *table)
" .popsection\n" \
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
CONFIG_ARM64_PAN) \
- : "=&r" (res), "+r" (data), "=&r" (temp) \
- : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
+ : "=&r" (res), "+r" (data), "=&r" (temp), "=&r" (temp2) \
+ : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT), \
+ "i" (__SWP_LL_SC_LOOPS) \
: "memory")
-#define __user_swp_asm(data, addr, res, temp) \
- __user_swpX_asm(data, addr, res, temp, "")
-#define __user_swpb_asm(data, addr, res, temp) \
- __user_swpX_asm(data, addr, res, temp, "b")
+#define __user_swp_asm(data, addr, res, temp, temp2) \
+ __user_swpX_asm(data, addr, res, temp, temp2, "")
+#define __user_swpb_asm(data, addr, res, temp, temp2) \
+ __user_swpX_asm(data, addr, res, temp, temp2, "b")
/*
* Bit 22 of the instruction encoding distinguishes between
@@ -353,12 +361,12 @@ static int emulate_swpX(unsigned int address, unsigned int *data,
}
while (1) {
- unsigned long temp;
+ unsigned long temp, temp2;
if (type == TYPE_SWPB)
- __user_swpb_asm(*data, address, res, temp);
+ __user_swpb_asm(*data, address, res, temp, temp2);
else
- __user_swp_asm(*data, address, res, temp);
+ __user_swp_asm(*data, address, res, temp, temp2);
if (likely(res != -EAGAIN) || signal_pending(current))
break;
--
2.5.0
^ permalink raw reply related
* [v15, 6/7] base: soc: introduce soc_device_match() interface
From: Arnd Bergmann @ 2016-10-28 10:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477637418-38938-7-git-send-email-yangbo.lu@nxp.com>
On Friday, October 28, 2016 2:50:17 PM CEST Yangbo Lu wrote:
> +
> +static int soc_device_match_one(struct device *dev, void *arg)
> +{
> + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
> + const struct soc_device_attribute *match = arg;
> +
> + if (match->machine &&
> + !glob_match(match->machine, soc_dev->attr->machine))
> + return 0;
> +
> + if (match->family &&
> + !glob_match(match->family, soc_dev->attr->family))
> + return 0;
> +
>
Geert found a bug in my code, and submitted a fix at
https://patchwork.kernel.org/patch/9361395/
I think you should include that one in your series.
Arnd
^ permalink raw reply
* [PATCH v5 1/7] ARM: dts: r8a7743: initial SoC device tree
From: Geert Uytterhoeven @ 2016-10-28 10:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <13559419.B3v0G6vn24@wasted.cogentembedded.com>
Hi Sergei,
On Thu, Oct 27, 2016 at 11:36 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> The initial R8A7743 SoC device tree including CPU0, GIC, timer, SYSC, RST,
> CPG, and the required clock descriptions.
>
> Based on the original (and large) patch by Dmitry Shifrin
> <dmitry.shifrin@cogentembedded.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> ---
> Changes in version 5:
> - added the RST device node, updated the patch description accordingly.
Thanks for the update!
> +++ renesas/arch/arm/boot/dts/r8a7743.dtsi
> @@ -0,0 +1,120 @@
> + rst: reset-controller at e6160000 {
> + compatible = "renesas,r8a7743-rst";
> + reg = <0 0xe6160000 0 0x0200>;
I'd use "reg = <0 0xe6160000 0 0x0100>".
Only R-Car Gen3 has registers above offset 0x100.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [v15, 3/7] powerpc/fsl: move mpc85xx.h to include/linux/fsl
From: Arnd Bergmann @ 2016-10-28 10:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477637418-38938-4-git-send-email-yangbo.lu@nxp.com>
On Friday, October 28, 2016 2:50:14 PM CEST Yangbo Lu wrote:
> Move mpc85xx.h to include/linux/fsl and rename it to svr.h as a common
> header file. This SVR numberspace is used on some ARM chips as well as
> PPC, and even to check for a PPC SVR multi-arch drivers would otherwise
> need to ifdef the header inclusion and all references to the SVR symbols.
>
>
I don't see any of the contents of this header referenced by the soc driver
any more. I think you can just drop this patch.
Arnd
^ permalink raw reply
* [v15, 0/7] Fix eSDHC host version register bug
From: Arnd Bergmann @ 2016-10-28 10:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477637418-38938-1-git-send-email-yangbo.lu@nxp.com>
On Friday, October 28, 2016 2:50:11 PM CEST Yangbo Lu wrote:
> This patchset is used to fix a host version register bug in the T4240-R1.0-R2.0
> eSDHC controller. To match the SoC version and revision, 10 previous version
> patchsets had tried many methods but all of them were rejected by reviewers.
> Such as
> - dts compatible method
> - syscon method
> - ifdef PPC method
> - GUTS driver getting SVR method
> Anrd suggested a soc_device_match method in v10, and this is the only available
> method left now. This v11 patchset introduces the soc_device_match interface in
> soc driver.
>
> The first five patches of Yangbo are to add the GUTS driver. This is used to
> register a soc device which contain soc version and revision information.
> The other two patches introduce the soc_device_match method in soc driver
> and apply it on esdhc driver to fix this bug.
>
Looks good overall. With patch 3 dropped (or an explanation why it's still
needed), everything
Acked-by: Arnd Bergmann <arnd@arndb.de>
Arnd
^ permalink raw reply
* [PATCH v6] tty/serial: at91: fix hardware handshake on Atmel platforms
From: Richard Genoud @ 2016-10-28 10:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161028095151.f24lhelfknzrpy6c@pengutronix.de>
2016-10-28 11:51 GMT+02:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Fri, Oct 28, 2016 at 01:13:31AM +0200, Alexandre Belloni wrote:
>> On 27/10/2016 at 20:02:29 +0200, Uwe Kleine-K?nig wrote :
>> > Hello Richard,
>> >
>> > On Thu, Oct 27, 2016 at 06:04:06PM +0200, Richard Genoud wrote:
>> > > diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
>> > > index fd8aa1f4ba78..168b10cad47b 100644
>> > > --- a/drivers/tty/serial/atmel_serial.c
>> > > +++ b/drivers/tty/serial/atmel_serial.c
>> > > @@ -2132,11 +2132,29 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
>> > > mode |= ATMEL_US_USMODE_RS485;
>> > > } else if (termios->c_cflag & CRTSCTS) {
>> > > /* RS232 with hardware handshake (RTS/CTS) */
>> > > - if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) {
>> > > - dev_info(port->dev, "not enabling hardware flow control because DMA is used");
>> > > - termios->c_cflag &= ~CRTSCTS;
>> > > - } else {
>> > > + if (atmel_use_fifo(port) &&
>> > > + !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
>> > > + /*
>> > > + * with ATMEL_US_USMODE_HWHS set, the controller will
>> > > + * be able to drive the RTS pin high/low when the RX
>> > > + * FIFO is above RXFTHRES/below RXFTHRES2.
>> > > + * It will also disable the transmitter when the CTS
>> > > + * pin is high.
>> > > + * This mode is not activated if CTS pin is a GPIO
>> > > + * because in this case, the transmitter is always
>> > > + * disabled (there must be an internal pull-up
>> > > + * responsible for this behaviour).
>> > > + * If the RTS pin is a GPIO, the controller won't be
>> > > + * able to drive it according to the FIFO thresholds,
>> > > + * but it will be handled by the driver.
>> > > + */
>> > > mode |= ATMEL_US_USMODE_HWHS;
>> >
>> > You use
>> >
>> > !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)
>> >
>> > as indicator that the cts mode of the respective pin is used. Is this
>> > reliable? (It's not if there are machines that don't use CTS, neither as
>> > gpio nor using the hardware function.) Maybe this needs a dt property to
>> > indicate that there is no (hw)handshaking available?
>> >
>>
>> We had a call today were we agreed that this should be added in a future
>> patch. Let's fix the regression for now.
>
> A machine without CTS (neither gpio nor hw function) used to work fine
> before the breaking commit, right? So this case is part of the
> regression and needs a fix?
Actually, a machine with a FIFO and without CTS didn't even exist at the
time of the breaking commit (v4.0), the FIFO handling was introduced later,
so it's not even a regression !
> Anyhow, this probably shouldn't stop the commit entering mainline
> because there are probably very few such machines (if any).
>
> So:
> Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>
> Best regards
> Uwe
Thanks !
Greg, could you take this in your tree ?
regards,
Richard.
^ permalink raw reply
* [PATCH v2] irqchip/bcm2836: Prevent spurious interrupts
From: Thomas Gleixner @ 2016-10-28 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161027182038.11312-1-eric@anholt.net>
On Thu, 27 Oct 2016, Eric Anholt wrote:
> From: Phil Elwell <phil@raspberrypi.org>
>
> The old arch-specific IRQ macros included a dsb to ensure the
> write to clear the mailbox interrupt completed before returning
> from the interrupt. The BCM2836 irqchip driver needs the same
> precaution to avoid spurious interrupts.
This is missing a fixes tag. I have no idea when that problem was
introduced, so I have no way to decide whether this needs to be tagged
stable or not.
Thanks,
tglx
>
> Signed-off-by: Phil Elwell <phil@raspberrypi.org>
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
> drivers/irqchip/irq-bcm2836.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
> index d96b2c947e74..93e3f7660c42 100644
> --- a/drivers/irqchip/irq-bcm2836.c
> +++ b/drivers/irqchip/irq-bcm2836.c
> @@ -175,6 +175,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
> u32 ipi = ffs(mbox_val) - 1;
>
> writel(1 << ipi, mailbox0);
> + dsb(sy);
> handle_IPI(ipi, regs);
> #endif
> } else if (stat) {
> --
> 2.9.3
>
>
^ permalink raw reply
* [PATCH] fpga zynq: Check the bitstream for validity
From: Matthias Brugger @ 2016-10-28 11:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161027143937.GC6818@obsidianresearch.com>
On 10/27/2016 04:39 PM, Jason Gunthorpe wrote:
> On Thu, Oct 27, 2016 at 10:50:48AM +0200, Matthias Brugger wrote:
>>> + /* Sanity check the proposed bitstream. It must start with the
>>> + * sync word in the correct byte order and be a multiple of 4
>>> + * bytes.
>>> + */
>>> + if (count <= 4 || buf[0] != 0x66 || buf[1] != 0x55 ||
>>> + buf[2] != 0x99 || buf[3] != 0xaa) {
>>
>> This checks if the bit stream is bigger then 4 bytes. We error out before,
>> if it is smaller.
>
> We do? Where?
>
Just a few lines before:
+ /* All valid bitstreams are multiples of 32 bits */
+ if ((count % 4) != 0)
+ return -EINVAL;
+
The only case we don't check is, if count == 0. If we check that here,
we can get rid of the count <= 4 check.
>> So you should fix the wording in the comment and check for count ==
>> 4.
>
> Ah right, the comment reflected an earlier revision that had the
> length check here.
>
> The count <= 4 should stay here since it is primarily guarding against
> read past the buffer in the if.
If you insist in doing this check, it should be count < 4, because we
check the first four elements of buf, or do I miss something?
Cheers,
Matthias
>
> Jason
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* [RFC][PATCH] arm64: Add support for CONFIG_DEBUG_VIRTUAL
From: Mark Rutland @ 2016-10-28 11:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu9-Pm_j-3shoiGZY+8zMBjTpNOXOphwea+tdC4KPbie3Q@mail.gmail.com>
On Fri, Oct 28, 2016 at 08:52:50AM +0100, Ard Biesheuvel wrote:
> Hi Laura,
>
> On 28 October 2016 at 01:18, Laura Abbott <labbott@redhat.com> wrote:
> > x86 has an option CONFIG_DEBUG_VIRTUAL to do additional checks
> > on virt_to_phys calls. The goal is to catch users who are calling
> > virt_to_phys on non-linear addresses immediately. As features
> > such as CONFIG_VMAP_STACK get enabled for arm64, this becomes
> > increasingly important. Add checks to catch bad virt_to_phys
> > usage.
>
> I think this is a useful thing to have. However, the Kconfig
> description talks about virt to page translations, not virt to phys.
> Of course, this is a shift away from being equivalent on x86, but not
> so much on arm64. Any concerns there?
See commit 59ea746337c69f6a ("MM: virtual address debug"); the existing
x86 cases cover virt to phys also.
The Kconfig text does say "and friends"...
Thanks,
Mark.
^ permalink raw reply
* [PATCH] fpga zynq: Check the bitstream for validity
From: Matthias Brugger @ 2016-10-28 11:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161026225413.GA6220@obsidianresearch.com>
On 10/27/2016 12:54 AM, Jason Gunthorpe wrote:
> There is no sense in sending a bitstream we know will not work, and
> with the variety of options for bitstream generation in Xilinx tools
> it is not terribly clear or very well documented what the correct
> input should be, especially since auto-detection was removed from this
> driver.
>
> All Zynq full configuration bitstreams must start with the sync word in
> the correct byte order.
>
> Zynq is also only able to DMA dword quantities, so bitstreams must be
> a multiple of 4 bytes. This also fixes a DMA-past the end bug.
>
The you can also fix the transfer_length calculation in
zynq_fpga_ops_write, as we don't allow buffers which are not a multiple
of 4.
Regards,
Matthias
^ permalink raw reply
* [PATCH 1/2] irqchip/gic-v3: Convert arm64 GIC accessors to {read, write}_sysreg_s
From: Will Deacon @ 2016-10-28 11:23 UTC (permalink / raw)
To: linux-arm-kernel
The GIC system registers are accessed using open-coded wrappers around
the mrs_s/msr_s asm macros.
This patch moves the code over to the {read,wrote}_sysreg_s accessors
instead, reducing the amount of explicit asm blocks in the arch headers.
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/arch_gicv3.h | 45 ++++++++++++++-----------------------
1 file changed, 17 insertions(+), 28 deletions(-)
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index f8ae6d6e4767..fdf34f8b4ee0 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -80,18 +80,8 @@
#include <linux/stringify.h>
#include <asm/barrier.h>
-#define read_gicreg(r) \
- ({ \
- u64 reg; \
- asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
- reg; \
- })
-
-#define write_gicreg(v,r) \
- do { \
- u64 __val = (v); \
- asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
- } while (0)
+#define read_gicreg read_sysreg_s
+#define write_gicreg write_sysreg_s
/*
* Low-level accessors
@@ -102,13 +92,13 @@
static inline void gic_write_eoir(u32 irq)
{
- asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" ((u64)irq));
+ write_sysreg_s(irq, ICC_EOIR1_EL1);
isb();
}
static inline void gic_write_dir(u32 irq)
{
- asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" ((u64)irq));
+ write_sysreg_s(irq, ICC_DIR_EL1);
isb();
}
@@ -116,7 +106,7 @@ static inline u64 gic_read_iar_common(void)
{
u64 irqstat;
- asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
+ irqstat = read_sysreg_s(ICC_IAR1_EL1);
dsb(sy);
return irqstat;
}
@@ -134,10 +124,12 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
asm volatile(
"nop;nop;nop;nop\n\t"
- "nop;nop;nop;nop\n\t"
- "mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
- "nop;nop;nop;nop"
- : "=r" (irqstat));
+ "nop;nop;nop;nop");
+
+ irqstat = read_sysreg_s(ICC_IAR1_EL1);
+
+ asm volatile(
+ "nop;nop;nop;nop");
mb();
return irqstat;
@@ -145,37 +137,34 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
static inline void gic_write_pmr(u32 val)
{
- asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" ((u64)val));
+ write_sysreg_s(val, ICC_PMR_EL1);
}
static inline void gic_write_ctlr(u32 val)
{
- asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" ((u64)val));
+ write_sysreg_s(val, ICC_CTLR_EL1);
isb();
}
static inline void gic_write_grpen1(u32 val)
{
- asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" ((u64)val));
+ write_sysreg_s(val, ICC_GRPEN1_EL1);
isb();
}
static inline void gic_write_sgi1r(u64 val)
{
- asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
+ write_sysreg_s(val, ICC_SGI1R_EL1);
}
static inline u32 gic_read_sre(void)
{
- u64 val;
-
- asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
- return val;
+ return read_sysreg_s(ICC_SRE_EL1);
}
static inline void gic_write_sre(u32 val)
{
- asm volatile("msr_s " __stringify(ICC_SRE_EL1) ", %0" : : "r" ((u64)val));
+ write_sysreg_s(val, ICC_SRE_EL1);
isb();
}
--
2.1.4
^ permalink raw reply related
* [PATCH 2/2] irqchip/gic-v3: Use nops macro for Cavium ThunderX erratum 23154
From: Will Deacon @ 2016-10-28 11:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477653838-21569-1-git-send-email-will.deacon@arm.com>
The workaround for Cavium ThunderX erratum 23154 has a homebrew
pipeflush built out of NOP sequences around the read of the IAR.
This patch converts the code to use the new nops macro, which makes it
a little easier to read.
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/arch_gicv3.h | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index fdf34f8b4ee0..0313670a3e3f 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -122,14 +122,9 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
{
u64 irqstat;
- asm volatile(
- "nop;nop;nop;nop\n\t"
- "nop;nop;nop;nop");
-
+ nops(8);
irqstat = read_sysreg_s(ICC_IAR1_EL1);
-
- asm volatile(
- "nop;nop;nop;nop");
+ nops(4);
mb();
return irqstat;
--
2.1.4
^ permalink raw reply related
* [GIT PULL] firmware: SCPI updates for v4.10
From: Sudeep Holla @ 2016-10-28 11:29 UTC (permalink / raw)
To: linux-arm-kernel
Hi ARM-SoC Team,
Please pull !
--
Regards,
Sudeep
The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/scpi-updates-4.10
for you to fetch changes up to a9e0192d8b35c6ab115a154ed1499ff39a0e5b06:
firmware: arm_scpi: add support for legacy match table on Amlogic GXBB SoC (2016-10-19 15:17:28 +0100)
----------------------------------------------------------------
SCPI updates for v4.10
1. Adds support for Legacy SCPI(pre- SCPI v1.0) protocol
2. Adds support for SCPI used on Amlogic GXBB SoC using the legacy
SCPI protocol
----------------------------------------------------------------
Neil Armstrong (5):
dt-bindings: Add support for Amlogic GXBB SCPI Interface
firmware: arm_scpi: increase MAX_DVFS_OPPS to 16 entries
firmware: arm_scpi: add alternative legacy structures, functions and macros
firmware: arm_scpi: allow firmware with get_capabilities not implemented
firmware: arm_scpi: add support for legacy match table on Amlogic GXBB SoC
Sudeep Holla (1):
firmware: arm_scpi: add command indirection to support legacy commands
Documentation/devicetree/bindings/arm/arm,scpi.txt | 8 +-
drivers/firmware/arm_scpi.c | 276 ++++++++++++++++++---
2 files changed, 249 insertions(+), 35 deletions(-)
^ permalink raw reply
* [GIT PULL] ARM: vexpress: fixes for v4.10
From: Sudeep Holla @ 2016-10-28 11:30 UTC (permalink / raw)
To: linux-arm-kernel
Hi ARM SoC team,
These couple of fixes help to boot TC2 in HYP mode with CONFIG_MCPM
enabled. This was not supported directly before and hence targeting for
v4.10. Currently those who want to boot in HYP mode have to disable
MCPM config in the build.
Please pull.
--
Regards,
Sudeep
The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/vexpress-fixes-4.10
for you to fetch changes up to 801f33be8e902d8cea75cb7ac056d07c4fdd25f8:
drivers: cci: add missing CCI port availability firmware check (2016-10-17 14:27:54 +0100)
----------------------------------------------------------------
ARMv7 Vexpress fixes for v4.10
Couple of fixes to MCPM/CCI drivers to check and ensure that the kernel
is actually allowed to take control over CCI ports(i.e. running in
secure mode) before enabling MCPM.
This is needed to boot Linux in HYP mode (very useful for development
on virtualization) with CONFIG_MCPM enabled kernel.
----------------------------------------------------------------
Lorenzo Pieralisi (2):
ARM: vexpress: refine MCPM smp operations override criteria
drivers: cci: add missing CCI port availability firmware check
arch/arm/mach-vexpress/platsmp.c | 34 ++++++++++++++++++++++++++--------
drivers/bus/arm-cci.c | 10 ++++++++++
2 files changed, 36 insertions(+), 8 deletions(-)
^ permalink raw reply
* [GIT PULL] ARM: dts: vexpress: fixes/updates for v4.10
From: Sudeep Holla @ 2016-10-28 11:30 UTC (permalink / raw)
To: linux-arm-kernel
Hi ARM Soc Team,
Please pull !
--
Regards,
Sudeep
The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/vexpress-dt-4.10
for you to fetch changes up to b01c3994817dc4e117c5642c3e09e0a231b5b477:
ARM: dts: vexpress: add TC2 cpu capacity-dmips-mhz information (2016-10-17 17:05:58 +0100)
----------------------------------------------------------------
ARMv7 Vexpress DT fixes/updates for v4.10
1. Addition of CPU dmips/capacity information to TC2 platform
2. Cleanup/fix unit address warnings and removal of skeleton.dtsi from
MPS2 device tree
----------------------------------------------------------------
Juri Lelli (1):
ARM: dts: vexpress: add TC2 cpu capacity-dmips-mhz information
Vladimir Murzin (1):
ARM: dts: mps2: remove skeleton.dtsi include and fix unit address warnings
arch/arm/boot/dts/mps2-an385.dts | 2 +-
arch/arm/boot/dts/mps2-an399.dts | 2 +-
arch/arm/boot/dts/mps2.dtsi | 4 +++-
arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 5 +++++
4 files changed, 10 insertions(+), 3 deletions(-)
^ permalink raw reply
* [GIT PULL] arm64: dts: juno: updates for v4.10
From: Sudeep Holla @ 2016-10-28 11:31 UTC (permalink / raw)
To: linux-arm-kernel
Hi ARM SoC Team,
Please pull.
--
Regards,
Sudeep
The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/juno-dt-4.10
for you to fetch changes up to c1ab65b24065ab04bdb0bc4e89d88784d38dc644:
arm64: dts: juno: add cpu capacity-dmips-mhz information to R2 boards (2016-10-17 17:43:22 +0100)
----------------------------------------------------------------
ARMv8 Vexpress/Juno DT updates for v4.10
1. Addition of SMMU(MMU-401) device nodes mainly to assist other
developments and testing
2. Addition of CPU dmips/capacity information on all the Juno boards
----------------------------------------------------------------
Juri Lelli (3):
arm64: dts: juno: add cpu capacity-dmips-mhz information to R0 boards
arm64: dts: juno: add cpu capacity-dmips-mhz information to R1 boards
arm64: dts: juno: add cpu capacity-dmips-mhz information to R2 boards
Robin Murphy (1):
arm64: dts: juno: Add SMMUs device nodes
arch/arm64/boot/dts/arm/juno-base.dtsi | 80 ++++++++++++++++++++++++++++++++++
arch/arm64/boot/dts/arm/juno-r1.dts | 6 +++
arch/arm64/boot/dts/arm/juno-r2.dts | 6 +++
arch/arm64/boot/dts/arm/juno.dts | 6 +++
4 files changed, 98 insertions(+)
^ permalink raw reply
* [PATCH 1/1] ARM: dts: imx6ul-14x14-evk: add USB dual-role support
From: Fabio Estevam @ 2016-10-28 11:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1470128903-942-1-git-send-email-peter.chen@nxp.com>
On Tue, Aug 2, 2016 at 6:08 AM, Peter Chen <peter.chen@nxp.com> wrote:
> With commit 851ce932242d ("usb: chipidea: otg: don't wait vbus
> drops below BSV when starts host"), the driver can support
> enabling vbus output without software control, so this board
> (control vbus output through ID pin) can support dual-role now.
>
> Signed-off-by: Peter Chen <peter.chen@nxp.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
^ permalink raw reply
* [PATCH v3 1/2] clk: imx: fix integer overflow in AV PLL round rate
From: Fabio Estevam @ 2016-10-28 11:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161028014127.GD16026@codeaurora.org>
Hi Stephen,
On Thu, Oct 27, 2016 at 11:41 PM, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 10/12, Emil Lundmark wrote:
>> Since 'parent_rate * mfn' may overflow 32 bits, the result should be
>> stored using 64 bits.
>>
>> The problem was discovered when trying to set the rate of the audio PLL
>> (pll4_post_div) on an i.MX6Q. The desired rate was 196.608 MHz, but
>> the actual rate returned was 192.000570 MHz. The round rate function should
>> have been able to return 196.608 MHz, i.e., the desired rate.
>>
>> Fixes: ba7f4f557eb6 ("clk: imx: correct AV PLL rate formula")
>> Cc: Anson Huang <b20788@freescale.com>
>> Signed-off-by: Emil Lundmark <emil@limesaudio.com>
>> ---
>
> Applied to clk-next
This one fixes a regression caused by ba7f4f557eb6 ("clk: imx: correct
AV PLL rate formula").
So it should go to clk-fixes instead with the stable tag:
Cc: <stable@vger.kernel.org> # 4.8.x
Thanks
^ permalink raw reply
* [PATCHv4 4/4] arm64: dump: Add checking for writable and exectuable pages
From: Ard Biesheuvel @ 2016-10-28 11:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477585654-8908-5-git-send-email-labbott@redhat.com>
On 27 October 2016 at 17:27, Laura Abbott <labbott@redhat.com> wrote:
>
> Page mappings with full RWX permissions are a security risk. x86
> has an option to walk the page tables and dump any bad pages.
> (See e1a58320a38d ("x86/mm: Warn on W^X mappings")). Add a similar
> implementation for arm64.
>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Reviewed-by: Mark Rutland <mark.rutland@arm.com>
> Tested-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Laura Abbott <labbott@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> v4: Changed pr_info -> pr_warn. Added a separate count variable for uxn to avoid
> double counting.
> ---
> arch/arm64/Kconfig.debug | 29 ++++++++++++++++++++++
> arch/arm64/include/asm/ptdump.h | 8 +++++++
> arch/arm64/mm/dump.c | 53 +++++++++++++++++++++++++++++++++++++++++
> arch/arm64/mm/mmu.c | 2 ++
> 4 files changed, 92 insertions(+)
>
> diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
> index 21a5b74..d1ebd46 100644
> --- a/arch/arm64/Kconfig.debug
> +++ b/arch/arm64/Kconfig.debug
> @@ -42,6 +42,35 @@ config ARM64_RANDOMIZE_TEXT_OFFSET
> of TEXT_OFFSET and platforms must not require a specific
> value.
>
> +config DEBUG_WX
> + bool "Warn on W+X mappings at boot"
> + select ARM64_PTDUMP_CORE
> + ---help---
> + Generate a warning if any W+X mappings are found at boot.
> +
> + This is useful for discovering cases where the kernel is leaving
> + W+X mappings after applying NX, as such mappings are a security risk.
> + This check also includes UXN, which should be set on all kernel
> + mappings.
> +
> + Look for a message in dmesg output like this:
> +
> + arm64/mm: Checked W+X mappings: passed, no W+X pages found.
> +
> + or like this, if the check failed:
> +
> + arm64/mm: Checked W+X mappings: FAILED, <N> W+X pages found.
> +
> + Note that even if the check fails, your kernel is possibly
> + still fine, as W+X mappings are not a security hole in
> + themselves, what they do is that they make the exploitation
> + of other unfixed kernel bugs easier.
> +
> + There is no runtime or memory usage effect of this option
> + once the kernel has booted up - it's a one time check.
> +
> + If in doubt, say "Y".
> +
> config DEBUG_SET_MODULE_RONX
> bool "Set loadable kernel module data as NX and text as RO"
> depends on MODULES
> diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
> index f72ee69..6afd847 100644
> --- a/arch/arm64/include/asm/ptdump.h
> +++ b/arch/arm64/include/asm/ptdump.h
> @@ -42,5 +42,13 @@ static inline int ptdump_debugfs_register(struct ptdump_info *info,
> return 0;
> }
> #endif
> +void ptdump_check_wx(void);
> #endif /* CONFIG_ARM64_PTDUMP_CORE */
> +
> +#ifdef CONFIG_DEBUG_WX
> +#define debug_checkwx() ptdump_check_wx()
> +#else
> +#define debug_checkwx() do { } while (0)
> +#endif
> +
> #endif /* __ASM_PTDUMP_H */
> diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
> index bb36649..ef8aca8 100644
> --- a/arch/arm64/mm/dump.c
> +++ b/arch/arm64/mm/dump.c
> @@ -74,6 +74,9 @@ struct pg_state {
> unsigned long start_address;
> unsigned level;
> u64 current_prot;
> + bool check_wx;
> + unsigned long wx_pages;
> + unsigned long uxn_pages;
> };
>
> struct prot_bits {
> @@ -202,6 +205,35 @@ static void dump_prot(struct pg_state *st, const struct prot_bits *bits,
> }
> }
>
> +static void note_prot_uxn(struct pg_state *st, unsigned long addr)
> +{
> + if (!st->check_wx)
> + return;
> +
> + if ((st->current_prot & PTE_UXN) == PTE_UXN)
> + return;
> +
> + WARN_ONCE(1, "arm64/mm: Found non-UXN mapping at address %p/%pS\n",
> + (void *)st->start_address, (void *)st->start_address);
> +
> + st->uxn_pages += (addr - st->start_address) / PAGE_SIZE;
> +}
> +
> +static void note_prot_wx(struct pg_state *st, unsigned long addr)
> +{
> + if (!st->check_wx)
> + return;
> + if ((st->current_prot & PTE_RDONLY) == PTE_RDONLY)
> + return;
> + if ((st->current_prot & PTE_PXN) == PTE_PXN)
> + return;
> +
> + WARN_ONCE(1, "arm64/mm: Found insecure W+X mapping at address %p/%pS\n",
> + (void *)st->start_address, (void *)st->start_address);
> +
> + st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
> +}
> +
> static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
> u64 val)
> {
> @@ -219,6 +251,8 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
> unsigned long delta;
>
> if (st->current_prot) {
> + note_prot_uxn(st, addr);
> + note_prot_wx(st, addr);
> pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx ",
> st->start_address, addr);
>
> @@ -344,6 +378,25 @@ static struct ptdump_info kernel_ptdump_info = {
> .base_addr = VA_START,
> };
>
> +void ptdump_check_wx(void)
> +{
> + struct pg_state st = {
> + .seq = NULL,
> + .marker = (struct addr_marker[]) {
> + { -1, NULL},
> + },
> + .check_wx = true,
> + };
> +
> + walk_pgd(&st, &init_mm, 0);
> + note_page(&st, 0, 0, 0);
> + if (st.wx_pages || st.uxn_pages)
> + pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UXN pages found\n",
> + st.wx_pages, st.uxn_pages);
> + else
> + pr_info("Checked W+X mappings: passed, no W+X pages found\n");
> +}
> +
> static int ptdump_init(void)
> {
> ptdump_initialize();
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 05615a3..2cbe2fe 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -42,6 +42,7 @@
> #include <asm/tlb.h>
> #include <asm/memblock.h>
> #include <asm/mmu_context.h>
> +#include <asm/ptdump.h>
>
> u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
>
> @@ -396,6 +397,7 @@ void mark_rodata_ro(void)
> section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
> create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata,
> section_size, PAGE_KERNEL_RO);
> + debug_checkwx();
> }
>
> static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v2 2/2] arm64: dts: hi6220: add resets property into dwmmc nodes
From: Jaehoon Chung @ 2016-10-28 11:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161028101919.GA25564@leoy-linaro>
Hi,
On 10/28/2016 07:19 PM, Leo Yan wrote:
> On Fri, Oct 28, 2016 at 06:54:58PM +0900, Jaehoon Chung wrote:
>
> [...]
>
>>>>> Could you share the log? Is there any log about failure?
>>>>
>>>> Sure, please see below log:
>>>
>>> It's related with -EPROBE_DEFER..I'm not sure but if CONFIG_RESET_CONTROLLER is enabled, it's searching for reset controller.
>>> Maybe hi6220 has handled the reset controller(?)...
>>>
>>> I'm checking devm_reset_control_xxx...It's possible to occur the other boards which enabled RESET_CONTROLLER..
>>
>> Could you check the below thing..
>>
>> /* find reset controller when exist */
>> - pdata->rstc = devm_reset_control_get_optional(dev, NULL);
>> + pdata->rstc = devm_reset_control_get_optional(dev, "dwmci-reset");
>> if (IS_ERR(pdata->rstc)) {
>> if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER)
>> return ERR_PTR(-EPROBE_DEFER);
>
> Confirmed with this fixing, the kernel can bootup successfully.
>
> Thanks for this.
Thanks for checking this..If this approach is not bad, i will send the patch.
Or if there are other good approaches, let me know, plz.
Best Regards,
Jaehoon Chung
>
>> To prevent the wrong controlling, how about adding "#reset-names" for dwmmc controller?
>>
>>
>> Best Regards,
>> Jaehoon Chung
>
>
>
^ permalink raw reply
* [PATCH] ARM: davinci: enable PM for DT boot
From: Sekhar Nori @ 2016-10-28 12:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161025214738.27744-1-khilman@baylibre.com>
Hi Kevin,
On Wednesday 26 October 2016 03:17 AM, Kevin Hilman wrote:
> Currently system PM is only enabled for legacy (non-DT) boot. Enable
> for DT boot also.
>
> Tested on da850-lcdk using "rtcwake -m mem -s5 -d rtc0".
>
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
> ---
> arch/arm/mach-davinci/da8xx-dt.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
> index c9f7e9274aa8..a8089fa40d86 100644
> --- a/arch/arm/mach-davinci/da8xx-dt.c
> +++ b/arch/arm/mach-davinci/da8xx-dt.c
> @@ -43,8 +43,26 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
>
> #ifdef CONFIG_ARCH_DAVINCI_DA850
>
> +static struct davinci_pm_config da850_pm_pdata = {
> + .sleepcount = 128,
> +};
> +
> +static struct platform_device da850_pm_device = {
> + .name = "pm-davinci",
> + .dev = {
> + .platform_data = &da850_pm_pdata,
> + },
> + .id = -1,
> +};
> +
> static void __init da850_init_machine(void)
> {
> + int ret;
> +
> + ret = da850_register_pm(&da850_pm_device);
I am not sure if it makes sense to keep the "pm device" around anymore.
I think for both DT and non-DT boot, we can get rid of the fake PM
device and combine da850_register_pm() and davinci_pm_probe() into a
single davinci_init_suspend() function which can then be called both for
DT and non-DT boot.
This was we can also avoid replication of the platform data and platform
device structures.
Thanks,
Sekhar
^ 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