Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 2/2] KVM: arm/arm64: Route vtimer events to user space
From: Marc Zyngier @ 2016-09-19 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474283695-212421-3-git-send-email-agraf@suse.de>

On 19/09/16 12:14, Alexander Graf wrote:
> We have 2 modes for dealing with interrupts in the ARM world. We can either
> handle them all using hardware acceleration through the vgic or we can emulate
> a gic in user space and only drive CPU IRQ pins from there.
> 
> Unfortunately, when driving IRQs from user space, we never tell user space
> about timer events that may result in interrupt line state changes, so we
> lose out on timer events if we run with user space gic emulation.
> 
> This patch fixes that by routing vtimer expiration events to user space.
> With this patch I can successfully run edk2 and Linux with user space gic
> emulation.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> 
> ---
> 
> v1 -> v2:
> 
>   - Add back curly brace that got lost
> 
> v2 -> v3:
> 
>   - Split into patch set
> 
> v3 -> v4:
> 
>   - Improve documentation
> ---
>  Documentation/virtual/kvm/api.txt |  30 ++++++++-
>  arch/arm/include/asm/kvm_host.h   |   3 +
>  arch/arm/kvm/arm.c                |  22 ++++---
>  arch/arm64/include/asm/kvm_host.h |   3 +
>  include/uapi/linux/kvm.h          |  14 +++++
>  virt/kvm/arm/arch_timer.c         | 125 +++++++++++++++++++++++++++-----------
>  6 files changed, 155 insertions(+), 42 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 23937e0..1c0bd86 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -3202,9 +3202,14 @@ struct kvm_run {
>  	/* in */
>  	__u8 request_interrupt_window;
>  
> -Request that KVM_RUN return when it becomes possible to inject external
> +[x86] Request that KVM_RUN return when it becomes possible to inject external
>  interrupts into the guest.  Useful in conjunction with KVM_INTERRUPT.
>  
> +[arm*] Bits set to 1 in here mask IRQ lines that would otherwise potentially
> +trigger forever. These lines are available:
> +
> +    KVM_IRQWINDOW_VTIMER  -  Masks hw virtual timer irq while in guest
> +
>  	__u8 padding1[7];
>  
>  	/* out */
> @@ -3519,6 +3524,18 @@ Hyper-V SynIC state change. Notification is used to remap SynIC
>  event/message pages and to enable/disable SynIC messages/events processing
>  in userspace.
>  
> +		/* KVM_EXIT_ARM_TIMER */
> +		struct {
> +			__u8 timesource;
> +		} arm_timer;
> +
> +Indicates that a timer triggered that user space needs to handle and
> +potentially mask with vcpu->run->request_interrupt_window to allow the
> +guest to proceed. This only happens for timers that got enabled through
> +KVM_CAP_ARM_TIMER. The following time sources are available:
> +
> +    KVM_ARM_TIMER_VTIMER  - virtual cpu timer
> +
>  		/* Fix the size of the union. */
>  		char padding[256];
>  	};
> @@ -3739,6 +3756,17 @@ Once this is done the KVM_REG_MIPS_VEC_* and KVM_REG_MIPS_MSA_* registers can be
>  accessed, and the Config5.MSAEn bit is accessible via the KVM API and also from
>  the guest.
>  
> +6.11 KVM_CAP_ARM_TIMER
> +
> +Architectures: arm, arm64
> +Target: vcpu
> +Parameters: args[0] contains a bitmap of timers to select (see 5.)
> +
> +This capability allows to route per-core timers into user space. When it's
> +enabled and no in-kernel interrupt controller is in use, the timers selected
> +by args[0] trigger KVM_EXIT_ARM_TIMER guest exits when they are pending,
> +unless masked by vcpu->run->request_interrupt_window (see 5.).
> +
>  7. Capabilities that can be enabled on VMs
>  ------------------------------------------
>  
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index de338d9..77d1f73 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -180,6 +180,9 @@ struct kvm_vcpu_arch {
>  
>  	/* Detect first run of a vcpu */
>  	bool has_run_once;
> +
> +	/* User space wants timer notifications */
> +	bool user_space_arm_timers;

Please move this to the timer structure.

>  };
>  
>  struct kvm_vm_stat {
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index c84b6ad..57bdb71 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -187,6 +187,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>  	case KVM_CAP_ARM_PSCI_0_2:
>  	case KVM_CAP_READONLY_MEM:
>  	case KVM_CAP_MP_STATE:
> +	case KVM_CAP_ARM_TIMER:
>  		r = 1;
>  		break;
>  	case KVM_CAP_COALESCED_MMIO:
> @@ -474,13 +475,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>  			return ret;
>  	}
>  
> -	/*
> -	 * Enable the arch timers only if we have an in-kernel VGIC
> -	 * and it has been properly initialized, since we cannot handle
> -	 * interrupts from the virtual timer with a userspace gic.
> -	 */
> -	if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
> -		ret = kvm_timer_enable(vcpu);
> +	ret = kvm_timer_enable(vcpu);
>  
>  	return ret;
>  }
> @@ -601,6 +596,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  			run->exit_reason = KVM_EXIT_INTR;
>  		}
>  
> +		if (kvm_check_request(KVM_REQ_PENDING_TIMER, vcpu)) {

Since this is a very unlikely event (in the grand scheme of things), how
about making this unlikely()?

> +			/* Tell user space about the pending vtimer */
> +			ret = 0;
> +			run->exit_reason = KVM_EXIT_ARM_TIMER;
> +			run->arm_timer.timesource = KVM_ARM_TIMER_VTIMER;
> +		}

More importantly: why does it have to be indirected by a
make_request/check_request, and not be handled as part of the
kvm_timer_sync() call? We do update the state there, and you could
directly find out whether an exit is required.

> +
>  		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
>  			vcpu->arch.power_off || vcpu->arch.pause) {
>  			local_irq_enable();
> @@ -887,6 +889,12 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
>  		return -EINVAL;
>  
>  	switch (cap->cap) {
> +	case KVM_CAP_ARM_TIMER:
> +		r = 0;
> +		if (cap->args[0] != KVM_ARM_TIMER_VTIMER)
> +			return -EINVAL;
> +		vcpu->arch.user_space_arm_timers = true;
> +		break;
>  	default:
>  		r = -EINVAL;
>  		break;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 3eda975..3d01481 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -270,6 +270,9 @@ struct kvm_vcpu_arch {
>  
>  	/* Detect first run of a vcpu */
>  	bool has_run_once;
> +
> +	/* User space wants timer notifications */
> +	bool user_space_arm_timers;
>  };
>  
>  #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 300ef25..00f4948 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -205,6 +205,7 @@ struct kvm_hyperv_exit {
>  #define KVM_EXIT_S390_STSI        25
>  #define KVM_EXIT_IOAPIC_EOI       26
>  #define KVM_EXIT_HYPERV           27
> +#define KVM_EXIT_ARM_TIMER        28
>  
>  /* For KVM_EXIT_INTERNAL_ERROR */
>  /* Emulate instruction failed. */
> @@ -361,6 +362,10 @@ struct kvm_run {
>  		} eoi;
>  		/* KVM_EXIT_HYPERV */
>  		struct kvm_hyperv_exit hyperv;
> +		/* KVM_EXIT_ARM_TIMER */
> +		struct {
> +			__u8 timesource;
> +		} arm_timer;
>  		/* Fix the size of the union. */
>  		char padding[256];
>  	};
> @@ -870,6 +875,7 @@ struct kvm_ppc_smmu_info {
>  #define KVM_CAP_S390_USER_INSTR0 130
>  #define KVM_CAP_MSI_DEVID 131
>  #define KVM_CAP_PPC_HTM 132
> +#define KVM_CAP_ARM_TIMER 133
>  
>  #ifdef KVM_CAP_IRQ_ROUTING
>  
> @@ -1327,4 +1333,12 @@ struct kvm_assigned_msix_entry {
>  #define KVM_X2APIC_API_USE_32BIT_IDS            (1ULL << 0)
>  #define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK  (1ULL << 1)
>  
> +/* Available with KVM_CAP_ARM_TIMER */
> +
> +/* Bits for run->request_interrupt_window */
> +#define KVM_IRQWINDOW_VTIMER		(1 << 0)
> +
> +/* Bits for run->arm_timer.timesource */
> +#define KVM_ARM_TIMER_VTIMER		(1 << 0)
> +
>  #endif /* __LINUX_KVM_H */
> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> index 4309b60..cbbb50dd 100644
> --- a/virt/kvm/arm/arch_timer.c
> +++ b/virt/kvm/arm/arch_timer.c
> @@ -170,16 +170,45 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
>  {
>  	int ret;
>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
> +	struct kvm_run *run = vcpu->run;
>  
> -	BUG_ON(!vgic_initialized(vcpu->kvm));
> +	BUG_ON(irqchip_in_kernel(vcpu->kvm) && !vgic_initialized(vcpu->kvm));
>  
>  	timer->active_cleared_last = false;
>  	timer->irq.level = new_level;
> -	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->irq.irq,
> +	trace_kvm_timer_update_irq(vcpu->vcpu_id, host_vtimer_irq,
>  				   timer->irq.level);
> -	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
> -					 timer->irq.irq,
> -					 timer->irq.level);
> +
> +	if (irqchip_in_kernel(vcpu->kvm) && vgic_initialized(vcpu->kvm)) {

Given how many times you repeat this idiom in this patch, you should
have a single condition that encapsulate it once and for all.

> +		/* Fire the timer in the VGIC */
> +
> +		ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
> +						 timer->irq.irq,
> +						 timer->irq.level);
> +	} else if (!vcpu->arch.user_space_arm_timers) {
> +		/* User space has not activated timer use */
> +		ret = 0;
> +	} else {
> +		/*
> +		 * Set PENDING_TIMER so that user space can handle the event if
> +		 *
> +		 *   1) Level is high
> +		 *   2) The vtimer is not suppressed by user space
> +		 *   3) We are not in the timer trigger exit path
> +		 */
> +		if (new_level &&
> +		    !(run->request_interrupt_window & KVM_IRQWINDOW_VTIMER) &&
> +		    (run->exit_reason != KVM_EXIT_ARM_TIMER)) {
> +			/* KVM_REQ_PENDING_TIMER means vtimer triggered */
> +			kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
> +		}
> +
> +		/* Force a new level high check on next entry */
> +		timer->irq.level = 0;

I think this could become a bit more simple if you follow the flow I
mentioned earlier involving kvm_timer_sync(). Also, I only see how you
flag the line as being high, but not how you lower it. Care to explain
that flow?

> +
> +		ret = 0;
> +	}
> +
>  	WARN_ON(ret);
>  }
>  
> @@ -197,7 +226,8 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
>  	 * because the guest would never see the interrupt.  Instead wait
>  	 * until we call this function from kvm_timer_flush_hwstate.
>  	 */
> -	if (!vgic_initialized(vcpu->kvm) || !timer->enabled)
> +	if ((irqchip_in_kernel(vcpu->kvm) && !vgic_initialized(vcpu->kvm)) ||
> +	    !timer->enabled)
>  		return -ENODEV;
>  
>  	if (kvm_timer_should_fire(vcpu) != timer->irq.level)
> @@ -275,35 +305,57 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
>  	* to ensure that hardware interrupts from the timer triggers a guest
>  	* exit.
>  	*/
> -	phys_active = timer->irq.level ||
> -			kvm_vgic_map_is_active(vcpu, timer->irq.irq);
> -
> -	/*
> -	 * We want to avoid hitting the (re)distributor as much as
> -	 * possible, as this is a potentially expensive MMIO access
> -	 * (not to mention locks in the irq layer), and a solution for
> -	 * this is to cache the "active" state in memory.
> -	 *
> -	 * Things to consider: we cannot cache an "active set" state,
> -	 * because the HW can change this behind our back (it becomes
> -	 * "clear" in the HW). We must then restrict the caching to
> -	 * the "clear" state.
> -	 *
> -	 * The cache is invalidated on:
> -	 * - vcpu put, indicating that the HW cannot be trusted to be
> -	 *   in a sane state on the next vcpu load,
> -	 * - any change in the interrupt state
> -	 *
> -	 * Usage conditions:
> -	 * - cached value is "active clear"
> -	 * - value to be programmed is "active clear"
> -	 */
> -	if (timer->active_cleared_last && !phys_active)
> -		return;
> +	if (irqchip_in_kernel(vcpu->kvm) && vgic_initialized(vcpu->kvm)) {
> +		phys_active = timer->irq.level ||
> +				kvm_vgic_map_is_active(vcpu, timer->irq.irq);
> +
> +		/*
> +		 * We want to avoid hitting the (re)distributor as much as
> +		 * possible, as this is a potentially expensive MMIO access
> +		 * (not to mention locks in the irq layer), and a solution for
> +		 * this is to cache the "active" state in memory.
> +		 *
> +		 * Things to consider: we cannot cache an "active set" state,
> +		 * because the HW can change this behind our back (it becomes
> +		 * "clear" in the HW). We must then restrict the caching to
> +		 * the "clear" state.
> +		 *
> +		 * The cache is invalidated on:
> +		 * - vcpu put, indicating that the HW cannot be trusted to be
> +		 *   in a sane state on the next vcpu load,
> +		 * - any change in the interrupt state
> +		 *
> +		 * Usage conditions:
> +		 * - cached value is "active clear"
> +		 * - value to be programmed is "active clear"
> +		 */
> +		if (timer->active_cleared_last && !phys_active)
> +			return;
> +
> +		ret = irq_set_irqchip_state(host_vtimer_irq,
> +					    IRQCHIP_STATE_ACTIVE,
> +					    phys_active);
> +	} else {
> +		/* User space tells us whether the timer is in active mode */
> +		phys_active = vcpu->run->request_interrupt_window &
> +			      KVM_IRQWINDOW_VTIMER;

No, this just says "mask the interrupt". It doesn't say anything about
the state of the timer. More importantly: you sample the shared page.
What guarantees that the information there is preserved? Is userspace
writing that bit each time the vcpu thread re-enters the kernel with
this interrupt being in flight?

> +
> +		/* However if the line is high, we exit anyway, so we want
> +		 * to keep the IRQ masked */
> +		phys_active = phys_active || timer->irq.level;

Why would you force the interrupt to be masked as soon as the timer is
firing? If userspace hasn't masked it, I don't think you should paper
over it.

> +
> +		/*
> +		 * So we can just explicitly mask or unmask the IRQ, gaining
> +		 * more compatibility with oddball irq controllers.
> +		 */
> +		if (phys_active)
> +			disable_percpu_irq(host_vtimer_irq);
> +		else
> +			enable_percpu_irq(host_vtimer_irq, 0);

Since you are now targeting random irqchips (as opposed to a GIC
specifically), what guarantees that the timer is a per-cpu IRQ?

> +
> +		ret = 0;
> +	}
>  
> -	ret = irq_set_irqchip_state(host_vtimer_irq,
> -				    IRQCHIP_STATE_ACTIVE,
> -				    phys_active);
>  	WARN_ON(ret);
>  
>  	timer->active_cleared_last = !phys_active;
> @@ -479,6 +531,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>  	if (timer->enabled)
>  		return 0;
>  
> +	/* No need to route physical IRQs when we don't use the vgic */
> +	if (!irqchip_in_kernel(vcpu->kvm))
> +		goto no_vgic;
> +
>  	/*
>  	 * Find the physical IRQ number corresponding to the host_vtimer_irq
>  	 */
> @@ -502,6 +558,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>  	if (ret)
>  		return ret;
>  
> +no_vgic:
>  
>  	/*
>  	 * There is a potential race here between VCPUs starting for the first
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [GIT PULL 1/5] i.MX cleanup for 4.9
From: Arnd Bergmann @ 2016-09-19 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473670948-4265-1-git-send-email-shawnguo@kernel.org>

On Monday, September 12, 2016 5:02:24 PM CEST Shawn Guo wrote:
> i.MX cleanup for 4.9:
>  - Drop i.MX1 board files and make i.MX1 a DT only platform.
>  - Remove obsolete ENET initialization code for TX28 board, since FEC
>    driver handles those setup well now.
>  - A couple of cleanups on i.MX31 IOMUX headers to drop duplications
>  - A few other random and trivial cleanups
> 

Pulled into next/cleanup, thanks!

	Arnd

^ permalink raw reply

* [GIT PULL] ARM: mediatek: soc updates for v4.9
From: Arnd Bergmann @ 2016-09-19 14:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <dd55c369-3684-2a27-6b66-7a98fa485627@gmail.com>

On Monday, September 12, 2016 5:52:30 PM CEST Matthias Brugger wrote:
> - extent the waiting time of the pmic wrapper to 10 ms which
> reduces the failure rate on the data transfer between pmic and
> pmic wrapper.
> 
> ----------------------------------------------------------------
> 

Pulled into next/drivers, thanks!

	Arnd

^ permalink raw reply

* [RFC] Arm64 boot fail with numa enable in BIOS
From: Will Deacon @ 2016-09-19 14:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919140709.GA17464@leverpostej>

On Mon, Sep 19, 2016 at 03:07:19PM +0100, Mark Rutland wrote:
> [adding LAKML, arm64 maintainers]

I've also looped in Euler ThunderTown, since (a) he's at Huawei and is
assumedly testing this stuff and (b) he has a fairly big NUMA patch
series doing the rounds (some of which I've queued).

> On Mon, Sep 19, 2016 at 09:05:26PM +0800, Yisheng Xie wrote:
> In future, please make sure to Cc LAKML along with relevant parties when
> sending arm64 patches/queries.
> 
> For everyone newly Cc'd, the original message (with attachments) can be
> found at:
> 
> http://lkml.kernel.org/r/7618d76d-bfa8-d8aa-59aa-06f9d90c1a98 at huawei.com
> 
> > When I enable NUMA in BIOS for arm64, it failed to boot on v4.8-rc4-162-g071e31e.
> 
> That commit ID doesn't seem to be in mainline (I can't find it in my
> local tree). Which tree are you using? Do you have local patches
> applied?

That commit is in mainline:

  http://git.kernel.org/linus/071e31e

It would be nice to know if the problem also exists on the arm64
for-next/core branch.

Will


> I take it that by "enable NUMA in BIOS", you mean exposing SRAT to the
> OS?
> 
> > For the crash log, it seems caused by error number of cpumask.
> > Any ideas about it?
> 
> Much earlier in your log, there was a (non-fatal) warning, as below. Do
> you see this without NUMA/SRAT enabled in your FW? I don't see how the
> SRAT should affect the secondaries we try to bring online.
> 
> Given your MPIDRs have Aff2 bits set, I wonder if we've conflated a
> logical ID with a physical ID somewhere, and it just so happens that the
> NUMA code is more likely to poke something based on that.
> 
> Can you modify the warning in cpumask.h to dump the bad CPU number? That
> would make it fairly clear if that's the case.
> 
> Thanks,
> Mark.
> 
> > [    0.297337] Detected PIPT I-cache on CPU1
> > [    0.297347] GICv3: CPU1: found redistributor 10001 region 1:0x000000004d140000
> > [    0.297356] CPU1: Booted secondary processor [410fd082]
> > [    0.297375] ------------[ cut here ]------------
> > [    0.320390] WARNING: CPU: 1 PID: 0 at ./include/linux/cpumask.h:121 gic_raise_softirq+0x128/0x17c
> > [    0.329356] Modules linked in:
> > [    0.332434] 
> > [    0.333932] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0-rc4-00163-g803ea3a #21
> > [    0.341581] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
> > [    0.347735] task: ffff8013e9dd0000 task.stack: ffff8013e9dcc000
> > [    0.353714] PC is at gic_raise_softirq+0x128/0x17c
> > [    0.358550] LR is at gic_raise_softirq+0xa0/0x17c
> > [    0.363298] pc : [<ffff00000838c124>] lr : [<ffff00000838c09c>] pstate: 200001c5
> > [    0.370770] sp : ffff8013e9dcfde0
> > [    0.374112] x29: ffff8013e9dcfde0 x28: 0000000000000000 
> > [    0.379476] x27: 000000000083207c x26: ffff000008ca5d70 
> > [    0.384841] x25: 0000000100000001 x24: ffff000008d63ff3 
> > [    0.390205] x23: 0000000000000000 x22: ffff000008cb0000 
> > [    0.395569] x21: ffff00000884edb0 x20: 0000000000000001 
> > [    0.400933] x19: 0000000100000000 x18: 0000000000000000 
> > [    0.406298] x17: 0000000000000000 x16: 0000000003010066 
> > [    0.411661] x15: ffff000008ca8000 x14: 0000000000000013 
> > [    0.417025] x13: 0000000000000000 x12: 0000000000000013 
> > [    0.422389] x11: 0000000000000013 x10: 0000000002e92aa7 
> > [    0.427754] x9 : 0000000000000000 x8 : ffff8413eb6ca668 
> > [    0.433118] x7 : ffff8413eb6ca690 x6 : 0000000000000000 
> > [    0.438482] x5 : fffffffffffffffe x4 : 0000000000000000 
> > [    0.443845] x3 : 0000000000000040 x2 : 0000000000000041 
> > [    0.449209] x1 : 0000000000000000 x0 : 0000000000000001 
> > [    0.454573] 
> > [    0.456069] ---[ end trace b58e70f3295a8cd7 ]---
> > [    0.460730] Call trace:
> > [    0.463193] Exception stack(0xffff8013e9dcfc10 to 0xffff8013e9dcfd40)
> > [    0.469699] fc00:                                   0000000100000000 0001000000000000
> > [    0.477611] fc20: ffff8013e9dcfde0 ffff00000838c124 ffff000008d72228 ffff8013e9dcff70
> > [    0.485524] fc40: ffff000008d72608 ffff000008ab02a4 0000000000000000 0000000000000000
> > [    0.493436] fc60: 0000000000000000 3464313430303030 0000000000000000 0000000000000000
> > [    0.501348] fc80: ffff8013e9dcfc90 ffff00000836e678 ffff8013e9dcfca0 ffff00000836e910
> > [    0.509259] fca0: ffff8013e9dcfd30 ffff00000836ec10 0000000000000001 0000000000000000
> > [    0.517171] fcc0: 0000000000000041 0000000000000040 0000000000000000 fffffffffffffffe
> > [    0.525083] fce0: 0000000000000000 ffff8413eb6ca690 ffff8413eb6ca668 0000000000000000
> > [    0.532995] fd00: 0000000002e92aa7 0000000000000013 0000000000000013 0000000000000000
> > [    0.540907] fd20: 0000000000000013 ffff000008ca8000 0000000003010066 0000000000000000
> > [    0.548819] [<ffff00000838c124>] gic_raise_softirq+0x128/0x17c
> > [    0.554713] [<ffff00000808e1f4>] smp_send_reschedule+0x34/0x3c
> > [    0.560605] [<ffff0000080ddf18>] resched_curr+0x40/0x5c
> > [    0.565881] [<ffff0000080de650>] check_preempt_curr+0x58/0xa0
> > [    0.571685] [<ffff0000080de6b0>] ttwu_do_wakeup+0x18/0x80
> > [    0.577136] [<ffff0000080de790>] ttwu_do_activate+0x78/0x88
> > [    0.582763] [<ffff0000080df5cc>] try_to_wake_up+0x1f8/0x300
> > [    0.588390] [<ffff0000080df79c>] default_wake_function+0x10/0x18
> > [    0.594458] [<ffff0000080f3210>] __wake_up_common+0x5c/0x9c
> > [    0.600085] [<ffff0000080f3264>] __wake_up_locked+0x14/0x1c
> > [    0.605712] [<ffff0000080f3e10>] complete+0x40/0x5c
> > [    0.610635] [<ffff00000808dba8>] secondary_start_kernel+0x148/0x1a8
> > [    0.616965] [<00000000000831a8>] 0x831a8
> 

^ permalink raw reply

* [PATCH] ASoC: rk3399_gru_sound: fix recording pop at first attempt
From: Mark Rutland @ 2016-09-19 14:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474295379-16936-1-git-send-email-zhengxing@rock-chips.com>

On Mon, Sep 19, 2016 at 10:29:39PM +0800, Xing Zheng wrote:
> From: Wonjoon Lee <woojoo.lee@samsung.com>
> 
> Pop happens when mclk applied but dmic's own boot-time
> Specify dmic delay times in dt to make sure
> clocks are ready earlier than dmic working
> 
> Signed-off-by: Wonjoon Lee <woojoo.lee@samsung.com>
> Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
> ---
> 
>  .../bindings/sound/rockchip,rk3399-gru-sound.txt   |    6 ++++++
>  sound/soc/rockchip/rk3399_gru_sound.c              |   14 ++++++++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
> index f19b6c8..b7dd3ab 100644
> --- a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
> +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
> @@ -6,6 +6,12 @@ Required properties:
>    connected to the codecs
>  - rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs
>  
> +Optional properties:
> +- dmic-delay : specify delay time for DMIC ready.
> +  If this option is specified, which means it's required dmic need
> +  delay for DMIC to ready so that rt5514 can avoid recording before
> +  DMIC send valid data

What units is this in? Per the code it looks like ms, so if we follow
Documentation/devicetree/bindings/property-units.txt, thous should be
named something like dmic-enable-delay-ms.

That said, do we even need a property for this? Does this vary much in
practice?

If it does, can we not derive this delay from other information (e.g.
the rates of input clocks and so on)? What exactly determines the
necessary delay?

Thanks,
Mark.

>  
>  sound {
> diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
> index 164b6da..6ab838b 100644
> --- a/sound/soc/rockchip/rk3399_gru_sound.c
> +++ b/sound/soc/rockchip/rk3399_gru_sound.c
> @@ -37,6 +37,8 @@
>  
>  #define SOUND_FS	256
>  
> +unsigned int rt5514_dmic_delay;
> +
>  static struct snd_soc_jack rockchip_sound_jack;
>  
>  static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
> @@ -122,6 +124,9 @@ static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
>  		return ret;
>  	}
>  
> +	/* Wait for DMIC stable */
> +	msleep(rt5514_dmic_delay);
> +
>  	return 0;
>  }
>  
> @@ -334,6 +339,15 @@ static int rockchip_sound_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> +	/* Set DMIC delay */
> +	ret = device_property_read_u32(&pdev->dev, "dmic-delay",
> +					&rt5514_dmic_delay);
> +	if (ret) {
> +		rt5514_dmic_delay = 0;
> +		dev_dbg(&pdev->dev,
> +			"no optional property 'dmic-delay' found, default: no delay\n");
> +	}
> +
>  	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
>  	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
>  	rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
> -- 
> 1.7.9.5
> 
> 

^ permalink raw reply

* [PATCH v3 1/8] scpi: Add cmd indirection table to prepare for legacy commands
From: Sudeep Holla @ 2016-09-19 14:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473262477-18045-2-git-send-email-narmstrong@baylibre.com>

Hi Neil,

On 07/09/16 16:34, Neil Armstrong wrote:
> Add indirection table to permit multiple command values for legacy support.
>

I wrote the most of the patch and you changed the author too ;)

> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/firmware/arm_scpi.c | 145 ++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 127 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
> index 4388937..9a87687 100644
> --- a/drivers/firmware/arm_scpi.c
> +++ b/drivers/firmware/arm_scpi.c

[..]

> @@ -161,6 +194,7 @@ struct scpi_drvinfo {
>  	u32 protocol_version;
>  	u32 firmware_version;
>  	int num_chans;
> +	int *scpi_cmds;
>  	atomic_t next_chan;
>  	struct scpi_ops *scpi_ops;
>  	struct scpi_chan *channels;
> @@ -390,6 +424,19 @@ static u32 scpi_get_version(void)
>  	return scpi_info->protocol_version;
>  }
>
> +static inline int check_cmd(unsigned int offset)
> +{
> +	if (offset >= CMD_MAX_COUNT ||

If we call scpi_send_message internally(as it's static) why is this
check needed ?


> +	    !scpi_info ||
> +	    !scpi_info->scpi_cmds)

Will be even reach to this point if above is true ?

> +		return -EINVAL;
> +
> +	if (scpi_info->scpi_cmds[offset] < 0)
> +		return -EOPNOTSUPP;

IMO just above couple of lines in the beginning of scpi_send_message
will suffice. You can just add this to my original patch.

>  static int
>  scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
>  {
> @@ -397,8 +444,13 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
>  	struct clk_get_info clk;
>  	__le16 le_clk_id = cpu_to_le16(clk_id);
>
> -	ret = scpi_send_message(SCPI_CMD_GET_CLOCK_INFO, &le_clk_id,
> -				sizeof(le_clk_id), &clk, sizeof(clk));
> +	ret = check_cmd(CMD_GET_CLOCK_INFO);
> +	if (ret)
> +		return ret;
> +

It's totally unnecessary to add check in each and every function calling
scpi_send_message, why not add it to scpi_send_message instead.

-- 
Regards,
Sudeep

^ permalink raw reply

* [PATCH] ARM: mvebu: Select corediv clk for all mvebu v7 SoC
From: Gregory CLEMENT @ 2016-09-19 14:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919135230.3ukszs3ybd5fjfx2@pengutronix.de>

Hi Uwe,
 
 On lun., sept. 19 2016, Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de> wrote:

> On Mon, Sep 19, 2016 at 01:52:07PM +0200, Gregory CLEMENT wrote:
>> Since the commit bd3677ff31a3 ("clk: mvebu: Remove corediv clock from
>> Armada XP"), the corediv clk is no more selected for Armada XP, however
>> this clock is used for Armada XP using the compatible
>> armada-370-corediv-clock.
>> 
>> More over even if with the commit 1594d568c6e3 ("clk: mvebu: Move corediv
>> config to mvebu config"), it was selected for Armada 38x and Armada 375,
>> it was still not selected for Armada 39x.
>
> Instead of the above paragraph I'd write:
>
> 	While since commit 1594d568c6e3 ("clk: mvebu: Move corediv
> 	config to mvebu config") Armada 38x and Armada 375 got corediv
> 	support again, not only Armada XP was missed but also Armada
> 	39x.

Thanks for your suggestion I will use it.

>
>> Actually all the SoC selecting MVEBU_V7 config need this clock:
>> git grep "\-corediv-clock" arch/arm/boot/dts
>> arch/arm/boot/dts/armada-370-xp.dtsi: compatible = "marvell,armada-370-corediv-clock";
>> arch/arm/boot/dts/armada-375.dtsi:    compatible = "marvell,armada-375-corediv-clock";
>> arch/arm/boot/dts/armada-38x.dtsi:    compatible = "marvell,armada-380-corediv-clock";
>> arch/arm/boot/dts/armada-39x.dtsi:    compatible = "marvell,armada-390-corediv-clock"
>> 
>> This commit now fixes this behavior.
>
> ... by letting MVEBU_V7 select MVEBU_CLK_COREDIV.


I didn't want describe the content of the patch but I don't mind adding
it.

Thanks,

Gregory

>> Fixes: bd3677ff31a3 ("clk: mvebu: Remove corediv clock from Armada XP")
>> Cc: stable at vger.kernel.org
>> Reported-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>
> BTW, I considered doing this, too, but failed to see that 39x is
> missing, too, and so thought this to be wrong.
>
> Best regards
> Uwe
>
> -- 
> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH] ASoC: rk3399_gru_sound: fix recording pop at first attempt
From: Xing Zheng @ 2016-09-19 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

From: Wonjoon Lee <woojoo.lee@samsung.com>

Pop happens when mclk applied but dmic's own boot-time
Specify dmic delay times in dt to make sure
clocks are ready earlier than dmic working

Signed-off-by: Wonjoon Lee <woojoo.lee@samsung.com>
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
---

 .../bindings/sound/rockchip,rk3399-gru-sound.txt   |    6 ++++++
 sound/soc/rockchip/rk3399_gru_sound.c              |   14 ++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
index f19b6c8..b7dd3ab 100644
--- a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
+++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
@@ -6,6 +6,12 @@ Required properties:
   connected to the codecs
 - rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs
 
+Optional properties:
+- dmic-delay : specify delay time for DMIC ready.
+  If this option is specified, which means it's required dmic need
+  delay for DMIC to ready so that rt5514 can avoid recording before
+  DMIC send valid data
+
 Example:
 
 sound {
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index 164b6da..6ab838b 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -37,6 +37,8 @@
 
 #define SOUND_FS	256
 
+unsigned int rt5514_dmic_delay;
+
 static struct snd_soc_jack rockchip_sound_jack;
 
 static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
@@ -122,6 +124,9 @@ static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
 		return ret;
 	}
 
+	/* Wait for DMIC stable */
+	msleep(rt5514_dmic_delay);
+
 	return 0;
 }
 
@@ -334,6 +339,15 @@ static int rockchip_sound_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	/* Set DMIC delay */
+	ret = device_property_read_u32(&pdev->dev, "dmic-delay",
+					&rt5514_dmic_delay);
+	if (ret) {
+		rt5514_dmic_delay = 0;
+		dev_dbg(&pdev->dev,
+			"no optional property 'dmic-delay' found, default: no delay\n");
+	}
+
 	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
 	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
 	rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 3/3] arm: dts: imx7-colibri: Use enable-gpios for BL_ON
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Use pwm-backlight driver 'enable-gpios' property for backlight on/off control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 arch/arm/boot/dts/imx7-colibri.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 2af5e3e..ce5edb5 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -43,7 +43,10 @@
 / {
 	bl: backlight {
 		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_bl_on>;
 		pwms = <&pwm1 0 5000000 0>;
+		enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
 	};
 
 	reg_module_3v3: regulator-module-3v3 {
@@ -356,7 +359,6 @@
 		fsl,pins = <
 			MX7D_PAD_ECSPI2_SS0__GPIO4_IO23		0x14 /* SODIMM 65 */
 			MX7D_PAD_SD1_CD_B__GPIO5_IO0		0x14 /* SODIMM 69 */
-			MX7D_PAD_SD1_WP__GPIO5_IO1		0x14 /* SODIMM 71 */
 			MX7D_PAD_I2C4_SDA__GPIO4_IO15		0x14 /* SODIMM 75 */
 			MX7D_PAD_ECSPI1_MISO__GPIO4_IO18	0x14 /* SODIMM 79 */
 			MX7D_PAD_I2C3_SCL__GPIO4_IO12		0x14 /* SODIMM 81 */
@@ -388,6 +390,12 @@
 		>;
 	};
 
+		pinctrl_gpio_bl_on: gpio-bl-on {
+			fsl,pins = <
+				MX7D_PAD_SD1_WP__GPIO5_IO1		0x14
+			>;
+		};
+
 	pinctrl_i2c1_int: i2c1-int-grp { /* PMIC / TOUCH */
 		fsl,pins = <
 			MX7D_PAD_GPIO1_IO13__GPIO1_IO13	0x79
-- 
2.9.2

^ permalink raw reply related

* [PATCH 2/3] arm: dts: imx7-colibri: Use pwm polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Configure PWM polarity control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 arch/arm/boot/dts/imx7-colibri.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index a9cc657..2af5e3e 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -43,7 +43,7 @@
 / {
 	bl: backlight {
 		compatible = "pwm-backlight";
-		pwms = <&pwm1 0 5000000>;
+		pwms = <&pwm1 0 5000000 0>;
 	};
 
 	reg_module_3v3: regulator-module-3v3 {
-- 
2.9.2

^ permalink raw reply related

* [PATCH 1/3] arm: dts: imx7: Update #pwm-cells for PWM polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Update #pwm-cells to 3 in order to support PWM signal polarity control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 Documentation/devicetree/bindings/pwm/imx-pwm.txt | 6 +++---
 arch/arm/boot/dts/imx7s.dtsi                      | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
index e00c2e9..c61bdf8 100644
--- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
@@ -6,8 +6,8 @@ Required properties:
   - "fsl,imx1-pwm" for PWM compatible with the one integrated on i.MX1
   - "fsl,imx27-pwm" for PWM compatible with the one integrated on i.MX27
 - reg: physical base address and length of the controller's registers
-- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
-  the cells format.
+- #pwm-cells: 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.txt
+  in this directory for a description of the cells format.
 - clocks : Clock specifiers for both ipg and per clocks.
 - clock-names : Clock names should include both "ipg" and "per"
 See the clock consumer binding,
@@ -17,7 +17,7 @@ See the clock consumer binding,
 Example:
 
 pwm1: pwm at 53fb4000 {
-	#pwm-cells = <2>;
+	#pwm-cells = <3>;
 	compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
 	reg = <0x53fb4000 0x4000>;
 	clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 0d7d5ac..8d1d471 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -601,7 +601,7 @@
 				clocks = <&clks IMX7D_PWM1_ROOT_CLK>,
 					 <&clks IMX7D_PWM1_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -612,7 +612,7 @@
 				clocks = <&clks IMX7D_PWM2_ROOT_CLK>,
 					 <&clks IMX7D_PWM2_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -623,7 +623,7 @@
 				clocks = <&clks IMX7D_PWM3_ROOT_CLK>,
 					 <&clks IMX7D_PWM3_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -634,7 +634,7 @@
 				clocks = <&clks IMX7D_PWM4_ROOT_CLK>,
 					 <&clks IMX7D_PWM4_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
-- 
2.9.2

^ permalink raw reply related

* [PATCH 0/3] iMX7 PWM polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset depends on this patchset[1] and this patch[2] which adds support
for polarity control in imx-pwm driver.

- Use pwm polarity control on iMX7 based modules.
- Enable polarity control on Toradex Colibri iMX7D/S module.
- Add BL_ON GPIO control for Toradex Colibri iMX7D/S module.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/294027.html
[2] https://www.spinics.net/lists/arm-kernel/msg530818.html

Bhuvanchandra DV (3):
  arm: dts: imx7: Update #pwm-cells for PWM polarity control
  arm: dts: imx7-colibri: Use pwm polarity control
  arm: dts: imx7-colibri: Use enable-gpios for BL_ON

 Documentation/devicetree/bindings/pwm/imx-pwm.txt |  6 +++---
 arch/arm/boot/dts/imx7-colibri.dtsi               | 12 ++++++++++--
 arch/arm/boot/dts/imx7s.dtsi                      |  8 ++++----
 3 files changed, 17 insertions(+), 9 deletions(-)

-- 
2.9.2

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Will Deacon @ 2016-09-19 14:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <99ee0946-c7ff-e6e4-08c1-ff686ea1a8a5@arm.com>

On Mon, Sep 19, 2016 at 01:41:47PM +0100, Robin Murphy wrote:
> On 19/09/16 13:24, Will Deacon wrote:
> > On Mon, Sep 19, 2016 at 02:13:45PM +0200, Auger Eric wrote:
> >> On 16/09/2016 18:18, Robin Murphy wrote:
> >>> What I probably will do, though, since we have the functionality in
> >>> place for the sake of the old binding, and I think there are other folks
> >>> who want PCI iommu-map support but would prefer not to bother with DMA
> >>> ops on the host, is add a command-line option to disable DMA domains
> >>> even for the generic bindings.
> >>
> >> Yes this would be a good thing I think. This series has an important
> >> impact on platforms which do not have smmu v3, where contexts are scarce
> >> HW resources.
> > 
> > Rather than disabling DMA domains entirely, we could specify a number
> > of contexts to reserve for other use (e.g. VFIO). It's a pity that these
> > options are global for the system, as opposed to per SMMU instance,
> > but I can't see a good way around that.
> 
> The problem with that approach is that due to bus traversal order you'd
> typically end up with the even-more-limited number of non-reserved
> contexts getting consumed by bridges that are unlikely to ever actually
> use their DMA ops, so you end up barely any better off than just not
> doing DMA ops at all, which we already have the code for.

For Seattle, perhaps, but that's quite a big generalisation. If we're
going to add an option, I'd much rather add something with some flexibility,
rather than end up supporting both "disable_dma_domains" and
"reserved_s2_contexts" in the long run.

> And yeah, if you had, say, "arm-smmu.reserved_s2_contexts=4", for the
> benefit of your PCI SMMU, what do the SMMUs in front of your other
> platform devices with only 2 contexts (and which only want DMA ops) do?

There's two things in this example:

  (1) If other SMMUs only have 2 contexts, then they reserve both and warn
  (2) If some SMMUs want DMA ops and others don't, then you have an issue
      with *any* sort of cmdline option to control this

Will

^ permalink raw reply

* [RFC] Arm64 boot fail with numa enable in BIOS
From: Mark Rutland @ 2016-09-19 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7618d76d-bfa8-d8aa-59aa-06f9d90c1a98@huawei.com>

[adding LAKML, arm64 maintainers]

On Mon, Sep 19, 2016 at 09:05:26PM +0800, Yisheng Xie wrote:
> hi all,

Hi,

In future, please make sure to Cc LAKML along with relevant parties when
sending arm64 patches/queries.

For everyone newly Cc'd, the original message (with attachments) can be
found at:

http://lkml.kernel.org/r/7618d76d-bfa8-d8aa-59aa-06f9d90c1a98 at huawei.com

> When I enable NUMA in BIOS for arm64, it failed to boot on v4.8-rc4-162-g071e31e.

That commit ID doesn't seem to be in mainline (I can't find it in my
local tree). Which tree are you using? Do you have local patches
applied?

I take it that by "enable NUMA in BIOS", you mean exposing SRAT to the
OS?

> For the crash log, it seems caused by error number of cpumask.
> Any ideas about it?

Much earlier in your log, there was a (non-fatal) warning, as below. Do
you see this without NUMA/SRAT enabled in your FW? I don't see how the
SRAT should affect the secondaries we try to bring online.

Given your MPIDRs have Aff2 bits set, I wonder if we've conflated a
logical ID with a physical ID somewhere, and it just so happens that the
NUMA code is more likely to poke something based on that.

Can you modify the warning in cpumask.h to dump the bad CPU number? That
would make it fairly clear if that's the case.

Thanks,
Mark.

> [    0.297337] Detected PIPT I-cache on CPU1
> [    0.297347] GICv3: CPU1: found redistributor 10001 region 1:0x000000004d140000
> [    0.297356] CPU1: Booted secondary processor [410fd082]
> [    0.297375] ------------[ cut here ]------------
> [    0.320390] WARNING: CPU: 1 PID: 0 at ./include/linux/cpumask.h:121 gic_raise_softirq+0x128/0x17c
> [    0.329356] Modules linked in:
> [    0.332434] 
> [    0.333932] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0-rc4-00163-g803ea3a #21
> [    0.341581] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
> [    0.347735] task: ffff8013e9dd0000 task.stack: ffff8013e9dcc000
> [    0.353714] PC is at gic_raise_softirq+0x128/0x17c
> [    0.358550] LR is at gic_raise_softirq+0xa0/0x17c
> [    0.363298] pc : [<ffff00000838c124>] lr : [<ffff00000838c09c>] pstate: 200001c5
> [    0.370770] sp : ffff8013e9dcfde0
> [    0.374112] x29: ffff8013e9dcfde0 x28: 0000000000000000 
> [    0.379476] x27: 000000000083207c x26: ffff000008ca5d70 
> [    0.384841] x25: 0000000100000001 x24: ffff000008d63ff3 
> [    0.390205] x23: 0000000000000000 x22: ffff000008cb0000 
> [    0.395569] x21: ffff00000884edb0 x20: 0000000000000001 
> [    0.400933] x19: 0000000100000000 x18: 0000000000000000 
> [    0.406298] x17: 0000000000000000 x16: 0000000003010066 
> [    0.411661] x15: ffff000008ca8000 x14: 0000000000000013 
> [    0.417025] x13: 0000000000000000 x12: 0000000000000013 
> [    0.422389] x11: 0000000000000013 x10: 0000000002e92aa7 
> [    0.427754] x9 : 0000000000000000 x8 : ffff8413eb6ca668 
> [    0.433118] x7 : ffff8413eb6ca690 x6 : 0000000000000000 
> [    0.438482] x5 : fffffffffffffffe x4 : 0000000000000000 
> [    0.443845] x3 : 0000000000000040 x2 : 0000000000000041 
> [    0.449209] x1 : 0000000000000000 x0 : 0000000000000001 
> [    0.454573] 
> [    0.456069] ---[ end trace b58e70f3295a8cd7 ]---
> [    0.460730] Call trace:
> [    0.463193] Exception stack(0xffff8013e9dcfc10 to 0xffff8013e9dcfd40)
> [    0.469699] fc00:                                   0000000100000000 0001000000000000
> [    0.477611] fc20: ffff8013e9dcfde0 ffff00000838c124 ffff000008d72228 ffff8013e9dcff70
> [    0.485524] fc40: ffff000008d72608 ffff000008ab02a4 0000000000000000 0000000000000000
> [    0.493436] fc60: 0000000000000000 3464313430303030 0000000000000000 0000000000000000
> [    0.501348] fc80: ffff8013e9dcfc90 ffff00000836e678 ffff8013e9dcfca0 ffff00000836e910
> [    0.509259] fca0: ffff8013e9dcfd30 ffff00000836ec10 0000000000000001 0000000000000000
> [    0.517171] fcc0: 0000000000000041 0000000000000040 0000000000000000 fffffffffffffffe
> [    0.525083] fce0: 0000000000000000 ffff8413eb6ca690 ffff8413eb6ca668 0000000000000000
> [    0.532995] fd00: 0000000002e92aa7 0000000000000013 0000000000000013 0000000000000000
> [    0.540907] fd20: 0000000000000013 ffff000008ca8000 0000000003010066 0000000000000000
> [    0.548819] [<ffff00000838c124>] gic_raise_softirq+0x128/0x17c
> [    0.554713] [<ffff00000808e1f4>] smp_send_reschedule+0x34/0x3c
> [    0.560605] [<ffff0000080ddf18>] resched_curr+0x40/0x5c
> [    0.565881] [<ffff0000080de650>] check_preempt_curr+0x58/0xa0
> [    0.571685] [<ffff0000080de6b0>] ttwu_do_wakeup+0x18/0x80
> [    0.577136] [<ffff0000080de790>] ttwu_do_activate+0x78/0x88
> [    0.582763] [<ffff0000080df5cc>] try_to_wake_up+0x1f8/0x300
> [    0.588390] [<ffff0000080df79c>] default_wake_function+0x10/0x18
> [    0.594458] [<ffff0000080f3210>] __wake_up_common+0x5c/0x9c
> [    0.600085] [<ffff0000080f3264>] __wake_up_locked+0x14/0x1c
> [    0.605712] [<ffff0000080f3e10>] complete+0x40/0x5c
> [    0.610635] [<ffff00000808dba8>] secondary_start_kernel+0x148/0x1a8
> [    0.616965] [<00000000000831a8>] 0x831a8

^ permalink raw reply

* [PATCH v2 1/3] ipmi: add an Aspeed BT IPMI BMC driver
From: Corey Minyard @ 2016-09-19 14:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9ce54c4c-e8ae-7ac2-de9c-71402dfa4c39@kaod.org>

On 09/19/2016 03:00 AM, C?dric Le Goater wrote:
> On 09/16/2016 09:41 PM, Corey Minyard wrote:
>> On 09/16/2016 05:39 AM, C?dric Le Goater wrote:
>>> From: Alistair Popple <alistair@popple.id.au>
>>>
>>> This patch adds a simple device driver to expose the iBT interface on
>>> Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
>>> commonly used as BMCs (BaseBoard Management Controllers) and this
>>> driver implements the BMC side of the BT interface.
>>>
>>> The BT (Block Transfer) interface is used to perform in-band IPMI
>>> communication between a host and its BMC. Entire messages are buffered
>>> before sending a notification to the other end, host or BMC, that
>>> there is data to be read. Usually, the host emits requests and the BMC
>>> responses but the specification provides a mean for the BMC to send
>>> SMS Attention (BMC-to-Host attention or System Management Software
>>> attention) messages.
>>>
>>> For this purpose, the driver introduces a specific ioctl on the
>>> device: 'BT_BMC_IOCTL_SMS_ATN' that can be used by the system running
>>> on the BMC to signal the host of such an event.
>>>
>>> The device name defaults to '/dev/ipmi-bt-host'
>> Others have reviewed this for style and such, and I have looked
>> at it from a protocol point of view.  it looks to be sound for the
>> most part.  I have some higher level concerns:
>>
>> There appears to be no handling for multiple simultaneous users.
>> This interface can only be used by one task at a time, so you should
>> probably only allow one opener.  Well, I guess the BMC could be split
>> into a reader and a writer task, so I'm not really sure about that, but
>> I would think in most situations having more than one opener is a
>> bug.  You do call clr_b_busy() on open, for instance, which might be
>> an issue for multiple openers.  Maybe a module parameter for
>> maximum number of openers? Just want to make sure this was
>> thought about, at least.
> yes but not implemented ... The open_count in the bt_bmc structure
> is unused. In v3, I will replace it with a global atomic_t tracked
> in the open and release operations.
>
>> There is also no mutex protecting reading or writing.  If multiple
>> threads call read or write at the same time, it probably wouldn't
>> work correctly.  I think you need a read and a write mutex on the
>> interface to protect against this.
> yes. I will add a mutex also in v3.
>
>> The spec says:
>>
>>     The BMC must not return a given response once the corresponding
>>     Request-to-Response interval has passed. The BMC can ensure this
>>     by maintaining its own internal list of outstanding requests through
>>     the interface. The BMC could age and expire the entries in the list
>>     by expiring the entries at an interval that is somewhat shorter than
>>     the specified Request-to-Response interval....
> This is clearly not handled in the driver.
>
> For this purpose, we could maintain a request expiry list using the seq
> field of the BT message. Update the list in the read and write operations
> and arm a timer to garbage collect any left overs. As for the errno in
> the write when a response had timeout'ed, may be ETIMEDOUT ?

I think that would work, though I don't think you really need an
error response in this case.

I was thinking more just a timeout in the write function.  Ideally
the timeout would be calculated at receive time and then be
passed in on every write, to preserve the request-to-response
time for slow messages.  I like the simplicity of the driver the
way it is.

The trouble is that there is no easy way to pass in a timeout
in a write operation.  You could pass in a structure where the
first part is a 32-bit timeout, or something like that.  Or
maybe just a fixed timeout and assume every message is
handled in a short enough time that it meets the spec
requirement.  But that doesn't handle slowness on the
host side.  You can send the message via an ioctl,  which
again isn't terribly ideal.

It would be nice if there was a write function which was
able to pass metadata, but AFAIK that's only available on
sockets.

> For configuration of the maximum response time, a sysfs file would do
> I think.
>
> Do you want that in v3 also ? I have some experimental patches for it,
> that I can send as follow ups.

I'm fine either way.

Thanks,

-corey

>
> Thanks,
>
> C.
>
>> On the write side, though, there doesn't seem to be a way to handle a
>> situation where the host side doesn't respond for a while and the
>> pending message would need to be discarded.
>>
>> The spec doesn't mention much about error recovery on this interface,
>> but the way this is written should be fine, I think.
>>
>> I'm copying Rocky Craig, who wrote the host side driver for Linux, in
>> case he wants to comment on this.
>>
>> This is easy to read and understand, so I think v3 should be good.
>>
>> Thanks,
>>
>> -corey
>>
>>> Signed-off-by: Alistair Popple <alistair@popple.id.au>
>>> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
>>> Signed-off-by: Joel Stanley <joel@jms.id.au>
>>> [clg: - checkpatch fixes
>>>         - added a devicetree binding documentation
>>>         - replace 'bt_host' by 'bt_bmc' to reflect that the driver is
>>>           the BMC side of the IPMI BT interface
>>>         - renamed the device to 'ipmi-bt-host'
>>>         - introduced a temporary buffer to copy_{to,from}_user
>>>         - used platform_get_irq()
>>>         - moved the driver under drivers/char/ipmi/ but kept it as a misc
>>>           device
>>>         - changed the compatible cell to "aspeed,ast2400-bt-bmc"
>>> ]
>>> Signed-off-by: C?dric Le Goater <clg@kaod.org>
>>> ---
>>>
>>>    Changes since v1:
>>>
>>>    - replace 'bt_host' by 'bt_bmc' to reflect that the driver is
>>>      the BMC side of the IPMI BT interface
>>>    - renamed the device to 'ipmi-bt-host'
>>>    - introduced a temporary buffer to copy_{to,from}_user
>>>    - used platform_get_irq()
>>>    - moved the driver under drivers/char/ipmi/ but kept it as a misc
>>>      device
>>>    - changed the compatible cell to "aspeed,ast2400-bt-bmc"
>>>
>>>    .../bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt   |  23 +
>>>    drivers/Makefile                                   |   2 +-
>>>    drivers/char/ipmi/Kconfig                          |   7 +
>>>    drivers/char/ipmi/Makefile                         |   1 +
>>>    drivers/char/ipmi/bt-bmc.c                         | 486 +++++++++++++++++++++
>>>    include/uapi/linux/Kbuild                          |   1 +
>>>    include/uapi/linux/bt-bmc.h                        |  18 +
>>>    7 files changed, 537 insertions(+), 1 deletion(-)
>>>    create mode 100644 Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>>    create mode 100644 drivers/char/ipmi/bt-bmc.c
>>>    create mode 100644 include/uapi/linux/bt-bmc.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt b/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>> new file mode 100644
>>> index 000000000000..fbbacd958240
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>> @@ -0,0 +1,23 @@
>>> +* Aspeed BT (Block Transfer) IPMI interface
>>> +
>>> +The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs
>>> +(BaseBoard Management Controllers) and the BT interface can be used to
>>> +perform in-band IPMI communication with their host.
>>> +
>>> +Required properties:
>>> +
>>> +- compatible : should be "aspeed,ast2400-bt-bmc"
>>> +- reg: physical address and size of the registers
>>> +
>>> +Optional properties:
>>> +
>>> +- interrupts: interrupt generated by the BT interface. without an
>>> +  interrupt, the driver will operate in poll mode.
>>> +
>>> +Example:
>>> +
>>> +    ibt at 1e789140 {
>>> +        compatible = "aspeed,ast2400-bt-bmc";
>>> +        reg = <0x1e789140 0x18>;
>>> +        interrupts = <8>;
>>> +    };
>>> diff --git a/drivers/Makefile b/drivers/Makefile
>>> index 53abb4a5f736..5a9e7b6b7928 100644
>>> --- a/drivers/Makefile
>>> +++ b/drivers/Makefile
>>> @@ -21,7 +21,7 @@ obj-y                += video/
>>>    obj-y                += idle/
>>>      # IPMI must come before ACPI in order to provide IPMI opregion support
>>> -obj-$(CONFIG_IPMI_HANDLER)    += char/ipmi/
>>> +obj-y                += char/ipmi/
>>>      obj-$(CONFIG_ACPI)        += acpi/
>>>    obj-$(CONFIG_SFI)        += sfi/
>>> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
>>> index 5a9350b1069a..2c234e3e7513 100644
>>> --- a/drivers/char/ipmi/Kconfig
>>> +++ b/drivers/char/ipmi/Kconfig
>>> @@ -76,3 +76,10 @@ config IPMI_POWEROFF
>>>         the IPMI management controller is capable of this.
>>>      endif # IPMI_HANDLER
>>> +
>>> +config ASPEED_BT_IPMI_BMC
>>> +    tristate "BT IPMI bmc driver"
>>> +    help
>>> +      Provides a driver for the BT (Block Transfer) IPMI interface
>>> +      found on Aspeed SOCs (AST2400 and AST2500). The driver
>>> +      implements the BMC side of the BT interface.
>>> diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
>>> index f3ffde1f5f1f..0d98cd91def1 100644
>>> --- a/drivers/char/ipmi/Makefile
>>> +++ b/drivers/char/ipmi/Makefile
>>> @@ -11,3 +11,4 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o
>>>    obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
>>>    obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
>>>    obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
>>> +obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
>>> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
>>> new file mode 100644
>>> index 000000000000..b96cb421e1c2
>>> --- /dev/null
>>> +++ b/drivers/char/ipmi/bt-bmc.c
>>> @@ -0,0 +1,486 @@
>>> +/*
>>> + * Copyright (c) 2015-2016, IBM Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * as published by the Free Software Foundation; either version
>>> + * 2 of the License, or (at your option) any later version.
>>> + */
>>> +
>>> +#include <linux/module.h>
>>> +#include <linux/moduleparam.h>
>>> +#include <linux/errno.h>
>>> +#include <linux/poll.h>
>>> +#include <linux/sched.h>
>>> +#include <linux/spinlock.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/init.h>
>>> +#include <linux/device.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_irq.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/io.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/delay.h>
>>> +#include <linux/miscdevice.h>
>>> +#include <linux/timer.h>
>>> +#include <linux/jiffies.h>
>>> +#include <linux/bt-bmc.h>
>>> +
>>> +/*
>>> + * This is a BMC device used to communicate to the host
>>> + */
>>> +#define DEVICE_NAME    "ipmi-bt-host"
>>> +
>>> +#define BT_IO_BASE    0xe4
>>> +#define BT_IRQ        10
>>> +
>>> +#define BT_CR0        0x0
>>> +#define   BT_CR0_IO_BASE        16
>>> +#define   BT_CR0_IRQ            12
>>> +#define   BT_CR0_EN_CLR_SLV_RDP        0x8
>>> +#define   BT_CR0_EN_CLR_SLV_WRP        0x4
>>> +#define   BT_CR0_ENABLE_IBT        0x1
>>> +#define BT_CR1        0x4
>>> +#define   BT_CR1_IRQ_H2B    0x01
>>> +#define   BT_CR1_IRQ_HBUSY    0x40
>>> +#define BT_CR2        0x8
>>> +#define   BT_CR2_IRQ_H2B    0x01
>>> +#define   BT_CR2_IRQ_HBUSY    0x40
>>> +#define BT_CR3        0xc
>>> +#define BT_CTRL        0x10
>>> +#define   BT_CTRL_B_BUSY        0x80
>>> +#define   BT_CTRL_H_BUSY        0x40
>>> +#define   BT_CTRL_OEM0            0x20
>>> +#define   BT_CTRL_SMS_ATN        0x10
>>> +#define   BT_CTRL_B2H_ATN        0x08
>>> +#define   BT_CTRL_H2B_ATN        0x04
>>> +#define   BT_CTRL_CLR_RD_PTR        0x02
>>> +#define   BT_CTRL_CLR_WR_PTR        0x01
>>> +#define BT_BMC2HOST    0x14
>>> +#define BT_INTMASK    0x18
>>> +#define   BT_INTMASK_B2H_IRQEN        0x01
>>> +#define   BT_INTMASK_B2H_IRQ        0x02
>>> +#define   BT_INTMASK_BMC_HWRST        0x80
>>> +
>>> +struct bt_bmc {
>>> +    struct device        dev;
>>> +    struct miscdevice    miscdev;
>>> +    void __iomem        *base;
>>> +    int            open_count;
>>> +    int            irq;
>>> +    wait_queue_head_t    queue;
>>> +    struct timer_list    poll_timer;
>>> +};
>>> +
>>> +static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
>>> +{
>>> +    return ioread8(bt_bmc->base + reg);
>>> +}
>>> +
>>> +static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
>>> +{
>>> +    iowrite8(data, bt_bmc->base + reg);
>>> +}
>>> +
>>> +static void clr_rd_ptr(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_CLR_RD_PTR, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_wr_ptr(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_CLR_WR_PTR, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_h2b_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_H2B_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static void set_b_busy(struct bt_bmc *bt_bmc)
>>> +{
>>> +    if (!(bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_B_BUSY))
>>> +        bt_outb(bt_bmc, BT_CTRL_B_BUSY, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_b_busy(struct bt_bmc *bt_bmc)
>>> +{
>>> +    if (bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_B_BUSY)
>>> +        bt_outb(bt_bmc, BT_CTRL_B_BUSY, BT_CTRL);
>>> +}
>>> +
>>> +static void set_b2h_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_B2H_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static u8 bt_read(struct bt_bmc *bt_bmc)
>>> +{
>>> +    return bt_inb(bt_bmc, BT_BMC2HOST);
>>> +}
>>> +
>>> +static ssize_t bt_readn(struct bt_bmc *bt_bmc, u8 *buf, size_t n)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < n; i++)
>>> +        buf[i] = bt_read(bt_bmc);
>>> +    return n;
>>> +}
>>> +
>>> +static void bt_write(struct bt_bmc *bt_bmc, u8 c)
>>> +{
>>> +    bt_outb(bt_bmc, c, BT_BMC2HOST);
>>> +}
>>> +
>>> +static ssize_t bt_writen(struct bt_bmc *bt_bmc, u8 *buf, size_t n)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < n; i++)
>>> +        bt_write(bt_bmc, buf[i]);
>>> +    return n;
>>> +}
>>> +
>>> +static void set_sms_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_SMS_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static struct bt_bmc *file_bt_bmc(struct file *file)
>>> +{
>>> +    return container_of(file->private_data, struct bt_bmc, miscdev);
>>> +}
>>> +
>>> +static int bt_bmc_open(struct inode *inode, struct file *file)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +#define BT_BMC_BUFFER_SIZE 256
>>> +
>>> +/*
>>> + * The BT (Block Transfer) interface means that entire messages are
>>> + * buffered by the host before a notification is sent to the BMC that
>>> + * there is data to be read. The first byte is the length and the
>>> + * message data follows. The read operation just tries to capture the
>>> + * whole before returning it to userspace.
>>> + */
>>> +static ssize_t bt_bmc_read(struct file *file, char __user *buf,
>>> +                size_t count, loff_t *ppos)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    u8 len;
>>> +    int len_byte = 1;
>>> +    u8 kbuffer[BT_BMC_BUFFER_SIZE];
>>> +    ssize_t ret = 0;
>>> +    ssize_t nread;
>>> +
>>> +    if (!access_ok(VERIFY_WRITE, buf, count))
>>> +        return -EFAULT;
>>> +
>>> +    WARN_ON(*ppos);
>>> +
>>> +    if (wait_event_interruptible(bt_bmc->queue,
>>> +                bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_H2B_ATN))
>>> +        return -ERESTARTSYS;
>>> +
>>> +    set_b_busy(bt_bmc);
>>> +    clr_h2b_atn(bt_bmc);
>>> +    clr_rd_ptr(bt_bmc);
>>> +
>>> +    /*
>>> +     * The BT frames start with the message length, which does not
>>> +     * include the length byte.
>>> +     */
>>> +    kbuffer[0] = bt_read(bt_bmc);
>>> +    len = kbuffer[0];
>>> +
>>> +    /* We pass the length back to userspace as well */
>>> +    if (len + 1 > count)
>>> +        len = count - 1;
>>> +
>>> +    while (len) {
>>> +        nread = min_t(ssize_t, len, sizeof(kbuffer) - len_byte);
>>> +
>>> +        bt_readn(bt_bmc, kbuffer + len_byte, nread);
>>> +
>>> +        if (copy_to_user(buf, kbuffer, nread + len_byte)) {
>>> +            ret = -EFAULT;
>>> +            break;
>>> +        }
>>> +        len -= nread;
>>> +        buf += nread + len_byte;
>>> +        ret += nread + len_byte;
>>> +        len_byte = 0;
>>> +    }
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static ssize_t bt_bmc_write(struct file *file, const char __user *buf,
>>> +                size_t count, loff_t *ppos)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    u8 kbuffer[BT_BMC_BUFFER_SIZE];
>>> +    ssize_t ret = 0;
>>> +    ssize_t nwritten;
>>> +
>>> +    if (!access_ok(VERIFY_READ, buf, count))
>>> +        return -EFAULT;
>>> +
>>> +    WARN_ON(*ppos);
>>> +
>>> +    /* There's no interrupt for clearing bmc busy so we have to
>>> +     * poll
>>> +     */
>>> +    if (wait_event_interruptible(bt_bmc->queue,
>>> +                !(bt_inb(bt_bmc, BT_CTRL) &
>>> +                    (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN))))
>>> +        return -ERESTARTSYS;
>>> +
>>> +    clr_wr_ptr(bt_bmc);
>>> +
>>> +    while (count) {
>>> +        nwritten = min_t(ssize_t, count, sizeof(kbuffer));
>>> +        if (copy_from_user(&kbuffer, buf, nwritten)) {
>>> +            ret = -EFAULT;
>>> +            break;
>>> +        }
>>> +
>>> +        bt_writen(bt_bmc, kbuffer, nwritten);
>>> +
>>> +        count -= nwritten;
>>> +        buf += nwritten;
>>> +        ret += nwritten;
>>> +    }
>>> +
>>> +    set_b2h_atn(bt_bmc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static long bt_bmc_ioctl(struct file *file, unsigned int cmd,
>>> +        unsigned long param)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    switch (cmd) {
>>> +    case BT_BMC_IOCTL_SMS_ATN:
>>> +        set_sms_atn(bt_bmc);
>>> +        return 0;
>>> +    }
>>> +    return -EINVAL;
>>> +}
>>> +
>>> +static int bt_bmc_release(struct inode *inode, struct file *file)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    set_b_busy(bt_bmc);
>>> +    return 0;
>>> +}
>>> +
>>> +static unsigned int bt_bmc_poll(struct file *file, poll_table *wait)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    unsigned int mask = 0;
>>> +    uint8_t ctrl;
>>> +
>>> +    poll_wait(file, &bt_bmc->queue, wait);
>>> +
>>> +    ctrl = bt_inb(bt_bmc, BT_CTRL);
>>> +
>>> +    if (ctrl & BT_CTRL_H2B_ATN)
>>> +        mask |= POLLIN;
>>> +
>>> +    if (!(ctrl & (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN)))
>>> +        mask |= POLLOUT;
>>> +
>>> +    return mask;
>>> +}
>>> +
>>> +static const struct file_operations bt_bmc_fops = {
>>> +    .owner        = THIS_MODULE,
>>> +    .open        = bt_bmc_open,
>>> +    .read        = bt_bmc_read,
>>> +    .write        = bt_bmc_write,
>>> +    .release    = bt_bmc_release,
>>> +    .poll        = bt_bmc_poll,
>>> +    .unlocked_ioctl    = bt_bmc_ioctl,
>>> +};
>>> +
>>> +static void poll_timer(unsigned long data)
>>> +{
>>> +    struct bt_bmc *bt_bmc = (void *)data;
>>> +
>>> +    bt_bmc->poll_timer.expires += msecs_to_jiffies(500);
>>> +    wake_up(&bt_bmc->queue);
>>> +    add_timer(&bt_bmc->poll_timer);
>>> +}
>>> +
>>> +static irqreturn_t bt_bmc_irq(int irq, void *arg)
>>> +{
>>> +    struct bt_bmc *bt_bmc = arg;
>>> +    uint32_t reg;
>>> +
>>> +    reg = ioread32(bt_bmc->base + BT_CR2);
>>> +    reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
>>> +    if (!reg)
>>> +        return IRQ_NONE;
>>> +
>>> +    /* ack pending IRQs */
>>> +    iowrite32(reg, bt_bmc->base + BT_CR2);
>>> +
>>> +    wake_up(&bt_bmc->queue);
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>>> +        struct platform_device *pdev)
>>> +{
>>> +    struct device *dev = &pdev->dev;
>>> +    uint32_t reg;
>>> +    int rc;
>>> +
>>> +    bt_bmc->irq = platform_get_irq(pdev, 0);
>>> +    if (!bt_bmc->irq)
>>> +        return -ENODEV;
>>> +
>>> +    rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
>>> +            DEVICE_NAME, bt_bmc);
>>> +    if (rc < 0) {
>>> +        dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
>>> +        bt_bmc->irq = 0;
>>> +        return rc;
>>> +    }
>>> +
>>> +    /* Configure IRQs on the bmc clearing the H2B and HBUSY bits;
>>> +     * H2B will be asserted when the bmc has data for us; HBUSY
>>> +     * will be cleared (along with B2H) when we can write the next
>>> +     * message to the BT buffer
>>> +     */
>>> +    reg = ioread32(bt_bmc->base + BT_CR1);
>>> +    reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
>>> +    iowrite32(reg, bt_bmc->base + BT_CR1);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int bt_bmc_probe(struct platform_device *pdev)
>>> +{
>>> +    struct bt_bmc *bt_bmc;
>>> +    struct device *dev;
>>> +    struct resource *res;
>>> +    int rc;
>>> +
>>> +    if (!pdev || !pdev->dev.of_node)
>>> +        return -ENODEV;
>>> +
>>> +    dev = &pdev->dev;
>>> +    dev_info(dev, "Found bt bmc device\n");
>>> +
>>> +    bt_bmc = devm_kzalloc(dev, sizeof(*bt_bmc), GFP_KERNEL);
>>> +    if (!bt_bmc)
>>> +        return -ENOMEM;
>>> +
>>> +    dev_set_drvdata(&pdev->dev, bt_bmc);
>>> +
>>> +    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +    if (!res) {
>>> +        dev_err(dev, "Unable to find resources\n");
>>> +        rc = -ENXIO;
>>> +        goto out_free;
>>> +    }
>>> +
>>> +    bt_bmc->base = devm_ioremap_resource(&pdev->dev, res);
>>> +    if (!bt_bmc->base) {
>>> +        rc = -ENOMEM;
>>> +        goto out_free;
>>> +    }
>>> +
>>> +    init_waitqueue_head(&bt_bmc->queue);
>>> +
>>> +    bt_bmc->miscdev.minor    = MISC_DYNAMIC_MINOR,
>>> +    bt_bmc->miscdev.name    = DEVICE_NAME,
>>> +    bt_bmc->miscdev.fops    = &bt_bmc_fops,
>>> +    bt_bmc->miscdev.parent = dev;
>>> +    rc = misc_register(&bt_bmc->miscdev);
>>> +    if (rc) {
>>> +        dev_err(dev, "Unable to register device\n");
>>> +        goto out_unmap;
>>> +    }
>>> +
>>> +    bt_bmc_config_irq(bt_bmc, pdev);
>>> +
>>> +    if (bt_bmc->irq) {
>>> +        dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
>>> +    } else {
>>> +        dev_info(dev, "No IRQ; using timer\n");
>>> +        setup_timer(&bt_bmc->poll_timer, poll_timer,
>>> +                (unsigned long)bt_bmc);
>>> +        bt_bmc->poll_timer.expires = jiffies + msecs_to_jiffies(10);
>>> +        add_timer(&bt_bmc->poll_timer);
>>> +    }
>>> +
>>> +    iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) |
>>> +          (BT_IRQ << BT_CR0_IRQ) |
>>> +          BT_CR0_EN_CLR_SLV_RDP |
>>> +          BT_CR0_EN_CLR_SLV_WRP |
>>> +          BT_CR0_ENABLE_IBT,
>>> +          bt_bmc->base + BT_CR0);
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return 0;
>>> +
>>> +out_unmap:
>>> +    devm_iounmap(&pdev->dev, bt_bmc->base);
>>> +
>>> +out_free:
>>> +    devm_kfree(dev, bt_bmc);
>>> +    return rc;
>>> +
>>> +}
>>> +
>>> +static int bt_bmc_remove(struct platform_device *pdev)
>>> +{
>>> +    struct bt_bmc *bt_bmc = dev_get_drvdata(&pdev->dev);
>>> +
>>> +    misc_deregister(&bt_bmc->miscdev);
>>> +    if (!bt_bmc->irq)
>>> +        del_timer_sync(&bt_bmc->poll_timer);
>>> +    devm_iounmap(&pdev->dev, bt_bmc->base);
>>> +    devm_kfree(&pdev->dev, bt_bmc);
>>> +    bt_bmc = NULL;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static const struct of_device_id bt_bmc_match[] = {
>>> +    { .compatible = "aspeed,ast2400-bt-bmc" },
>>> +    { },
>>> +};
>>> +
>>> +static struct platform_driver bt_bmc_driver = {
>>> +    .driver = {
>>> +        .name        = DEVICE_NAME,
>>> +        .of_match_table = bt_bmc_match,
>>> +    },
>>> +    .probe = bt_bmc_probe,
>>> +    .remove = bt_bmc_remove,
>>> +};
>>> +
>>> +module_platform_driver(bt_bmc_driver);
>>> +
>>> +MODULE_DEVICE_TABLE(of, bt_bmc_match);
>>> +MODULE_LICENSE("GPL");
>>> +MODULE_AUTHOR("Alistair Popple <alistair@popple.id.au>");
>>> +MODULE_DESCRIPTION("Linux device interface to the BT interface");
>>> diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
>>> index 185f8ea2702f..17b12942c67d 100644
>>> --- a/include/uapi/linux/Kbuild
>>> +++ b/include/uapi/linux/Kbuild
>>> @@ -74,6 +74,7 @@ header-y += bpf_common.h
>>>    header-y += bpf.h
>>>    header-y += bpqether.h
>>>    header-y += bsg.h
>>> +header-y += bt-bmc.h
>>>    header-y += btrfs.h
>>>    header-y += can.h
>>>    header-y += capability.h
>>> diff --git a/include/uapi/linux/bt-bmc.h b/include/uapi/linux/bt-bmc.h
>>> new file mode 100644
>>> index 000000000000..d9ec766a63d0
>>> --- /dev/null
>>> +++ b/include/uapi/linux/bt-bmc.h
>>> @@ -0,0 +1,18 @@
>>> +/*
>>> + * Copyright (c) 2015-2016, IBM Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * as published by the Free Software Foundation; either version
>>> + * 2 of the License, or (at your option) any later version.
>>> + */
>>> +
>>> +#ifndef _UAPI_LINUX_BT_BMC_H
>>> +#define _UAPI_LINUX_BT_BMC_H
>>> +
>>> +#include <linux/ioctl.h>
>>> +
>>> +#define __BT_BMC_IOCTL_MAGIC    0xb1
>>> +#define BT_BMC_IOCTL_SMS_ATN    _IO(__BT_BMC_IOCTL_MAGIC, 0x00)
>>> +
>>> +#endif /* _UAPI_LINUX_BT_BMC_H */
>>

^ permalink raw reply

* [PATCH] ARM: mvebu: Select corediv clk for all mvebu v7 SoC
From: Uwe Kleine-König @ 2016-09-19 13:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919115207.19334-1-gregory.clement@free-electrons.com>

On Mon, Sep 19, 2016 at 01:52:07PM +0200, Gregory CLEMENT wrote:
> Since the commit bd3677ff31a3 ("clk: mvebu: Remove corediv clock from
> Armada XP"), the corediv clk is no more selected for Armada XP, however
> this clock is used for Armada XP using the compatible
> armada-370-corediv-clock.
> 
> More over even if with the commit 1594d568c6e3 ("clk: mvebu: Move corediv
> config to mvebu config"), it was selected for Armada 38x and Armada 375,
> it was still not selected for Armada 39x.

Instead of the above paragraph I'd write:

	While since commit 1594d568c6e3 ("clk: mvebu: Move corediv
	config to mvebu config") Armada 38x and Armada 375 got corediv
	support again, not only Armada XP was missed but also Armada
	39x.

> Actually all the SoC selecting MVEBU_V7 config need this clock:
> git grep "\-corediv-clock" arch/arm/boot/dts
> arch/arm/boot/dts/armada-370-xp.dtsi: compatible = "marvell,armada-370-corediv-clock";
> arch/arm/boot/dts/armada-375.dtsi:    compatible = "marvell,armada-375-corediv-clock";
> arch/arm/boot/dts/armada-38x.dtsi:    compatible = "marvell,armada-380-corediv-clock";
> arch/arm/boot/dts/armada-39x.dtsi:    compatible = "marvell,armada-390-corediv-clock"
> 
> This commit now fixes this behavior.

... by letting MVEBU_V7 select MVEBU_CLK_COREDIV.

> Fixes: bd3677ff31a3 ("clk: mvebu: Remove corediv clock from Armada XP")
> Cc: stable at vger.kernel.org
> Reported-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

BTW, I considered doing this, too, but failed to see that 39x is
missing, too, and so thought this to be wrong.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* [RESEND PATCH v4] thermal: tango: add resume support
From: Marc Gonzalez @ 2016-09-19 13:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474163885.3425.0.camel@intel.com>

On 18/09/2016 03:58, Zhang Rui wrote:

> On 2016-09-14 at 17:35 +0200, Marc Gonzalez wrote:
>
>> Hello Rui, Eduardo,
>>
>> The present patch has been reviewed by both Kevin Hilman and Arnd Bergmann,
>> two arm-soc maintainers. Can you pick it up in time for inclusion in v4.9?
> 
> It has already been in thermal -release branch for a while, and queued
> for 4.9.

Sorry, I was expecting an ACK on the list. It never occurred to me
to check your tree. Thanks for taking the patch.

https://git.kernel.org/cgit/linux/kernel/git/rzhang/linux.git/commit/?h=release&id=186e2aa3954c3201583e5ec3149faa6caa67d2b9

Regards.

^ permalink raw reply

* [PATCH] arm64: Add BCM2835 (Raspberry Pi 3) support to the defconfig
From: Eric Anholt @ 2016-09-19 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Most of the drivers are included as modules, except for serial (needed
for early console), WDT (required for reboot), and the dependency
chain of RASPBERRYPI_POWER (which is currently not buildable as a
module, but should be changed).

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm64/configs/defconfig | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fb8d84516e92..9748c4735a60 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -34,6 +34,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
+CONFIG_ARCH_BCM2835=y
 CONFIG_ARCH_BCM_IPROC=y
 CONFIG_ARCH_BERLIN=y
 CONFIG_ARCH_EXYNOS=y
@@ -193,6 +194,7 @@ CONFIG_USB_NET_SMSC75XX=m
 CONFIG_USB_NET_SMSC95XX=m
 CONFIG_USB_NET_PLUSB=m
 CONFIG_USB_NET_MCS7830=m
+CONFIG_BRCMFMAC=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SDIO=m
 CONFIG_INPUT_EVDEV=y
@@ -205,6 +207,9 @@ CONFIG_SERIO_AMBAKMI=y
 CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_BCM2835AUX=y
 CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_8250_UNIPHIER=y
@@ -228,6 +233,7 @@ CONFIG_VIRTIO_CONSOLE=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_BCM2835=m
 CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_I2C_IMX=y
 CONFIG_I2C_MESON=y
@@ -238,6 +244,8 @@ CONFIG_I2C_UNIPHIER_F=y
 CONFIG_I2C_RCAR=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SPI=y
+CONFIG_SPI_BCM2835=m
+CONFIG_SPI_BCM2835AUX=m
 CONFIG_SPI_MESON_SPIFC=m
 CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
@@ -272,6 +280,7 @@ CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_EXYNOS_THERMAL=y
 CONFIG_WATCHDOG=y
+CONFIG_BCM2835_WDT=y
 CONFIG_RENESAS_WDT=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_MESON_GXBB_WATCHDOG=m
@@ -294,6 +303,7 @@ CONFIG_REGULATOR_S2MPS11=y
 CONFIG_DRM=m
 CONFIG_DRM_NOUVEAU=m
 CONFIG_DRM_TEGRA=m
+CONFIG_DRM_VC4=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_HISI_KIRIN=m
@@ -308,6 +318,7 @@ CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
+CONFIG_SND_BCM2835_SOC_I2S=m
 CONFIG_SND_SOC_RCAR=y
 CONFIG_SND_SOC_SAMSUNG=y
 CONFIG_SND_SOC_AK4613=y
@@ -372,6 +383,7 @@ CONFIG_RTC_DRV_XGENE=y
 CONFIG_RTC_DRV_S3C=y
 CONFIG_DMADEVICES=y
 CONFIG_PL330_DMA=y
+CONFIG_DMA_BCM2835=m
 CONFIG_TEGRA20_APB_DMA=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_QCOM_HIDMA_MGMT=y
@@ -394,8 +406,10 @@ CONFIG_MSM_MMCC_8996=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_MAILBOX=y
 CONFIG_ARM_MHU=y
+CONFIG_BCM2835_MBOX=y
 CONFIG_HI6220_MBOX=y
 CONFIG_ARM_SMMU=y
+CONFIG_RASPBERRYPI_POWER=y
 CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
@@ -403,6 +417,7 @@ CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_PWM=y
+CONFIG_PWM_BCM2835=m
 CONFIG_PWM_TEGRA=m
 CONFIG_COMMON_RESET_HI6220=y
 CONFIG_PHY_RCAR_GEN3_USB2=y
@@ -414,6 +429,7 @@ CONFIG_ACPI=y
 CONFIG_IIO=y
 CONFIG_EXYNOS_ADC=y
 CONFIG_PWM_SAMSUNG=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 0/3] Armada 7k/8k CP110 system controller fixes
From: Marcin Wojtas @ 2016-09-19 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473183117-11889-1-git-send-email-mw@semihalf.com>

Hi Stephen,

Did you have any chance to take a look at v2? Do you have any remarks?

Best regards.
Marcin

2016-09-06 19:31 GMT+02:00 Marcin Wojtas <mw@semihalf.com>:
> Hi,
>
> Here is the second version of the patchset adding fixes to CP110
> system controller clock driver. As requested during review,
> an additional patch is submitted, which covers migration of the
> driver to clk_hw registration and API.
>
> Any feedback would be very welcome.
>
> Best regards,
> Marcin
>
> Changelog:
> v1 -> v2
> * replace setting CLK_IS_BASIC flag with clearing init structure fields
>   with memset
> * minor improvements of allocation and error checking
> * add migration to clk_hw
>
> Marcin Wojtas (3):
>   clk: mvebu: fix setting unwanted flags in CP110 gate clock
>   clk: mvebu: dynamically allocate resources in Armada CP110 system
>     controller
>   clk: mvebu: migrate CP110 system controller to clk_hw API and
>     registration
>
>  drivers/clk/mvebu/cp110-system-controller.c | 155 +++++++++++++++-------------
>  1 file changed, 81 insertions(+), 74 deletions(-)
>
> --
> 1.8.3.1
>

^ permalink raw reply

* [PATCH 1/1 v6] ARM: imx: Added perf functionality to mmdc driver
From: Mark Rutland @ 2016-09-19 12:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473864500-24256-1-git-send-email-Frank.Li@nxp.com>

Hi,

This is generally looking good now. There are just a few issues
remaining which I've noted below.

On Wed, Sep 14, 2016 at 09:48:20AM -0500, Frank Li wrote:
> From: Zhengyu Shen <zhengyu.shen@nxp.com>

> +static bool mmdc_pmu_group_is_valid(struct perf_event *event)

As a general note, you prefix other functions with mmdc_ rather than
mmdc_pmu. For consistency, it would be better for all the perf-specific
functions to be called mmdc_pmu_*. Likewise for attr_groups.

> +{
> +	struct pmu *pmu = event->pmu;
> +	struct perf_event *leader = event->group_leader;
> +	struct perf_event *sibling;
> +
> +	int cfg = leader->attr.config;
> +	int counter_mask = 0;
> +
> +	if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
> +		return false;

For any event managed by this PMU, this is checked in event_init, so
this check is unnecessary.

> +
> +	if (leader->pmu == pmu)
> +		counter_mask |= 1 << cfg;
> +	else if (!is_software_event(leader))
> +		return false;
> +
> +	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
> +		if (sibling->pmu == pmu) {
> +			cfg = sibling->attr.config;
> +			if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
> +				return false;

Likewise.

> +			counter_mask |= 1 << cfg;
> +		} else if (!is_software_event(sibling)) {
> +			return false;
> +		}
> +	}
> +
> +	if (event == leader)
> +		return true;
> +
> +	cfg = event->attr.config;
> +	if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
> +		return false;
> +
> +	return !(counter_mask & (1 << cfg));
> +}

I think this would be far clearer if written something like the below:

bool mmdc_pmu_group_event_is_valid(struct perf_event *event,
				   struct pmu *pmu,
				   unsigned long *used_counters)
{
	int counter = event->attr.config;

	if (is_software_event(event))
		return true;
	if (event->pmu != pmu)
		return false;
	return !test_and_set_bit(counter, &used_counters);
}

/*
 * Each event has a single fixed-purpose counter, so we can only have a
 * single active event for each at any point in time. Here we just check
 * for duplicates, and rely on mmdc_pmu_event_init to verify that the HW
 * event numbers are valid.
 */
bool mmdc_pmu_group_is_valid(struct perf_event *event)
{
	struct pmu *pmu = event->pmu;
	struct perf_event *leader = event->group_leader;
	struct perf_event *sibling;
	unigned long used_counters = 0;

	set_bit(counter(event), &used_counters);

	if (event != leader) {
		if (!mmdc_pmu_event_is_valid(event, pmu, &counter_mask))
			return false;
	}

	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
		if (!mmdc_pmu_group_event_is_valid(event, pmu, &used_counters))
			return false;
	}

	return true;
}

> +static int mmdc_event_add(struct perf_event *event, int flags)
> +{
> +	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	int cfg = event->attr.config;
> +
> +	if (WARN_ONCE((cfg < 0 || cfg >= MMDC_NUM_COUNTERS),
> +				"invalid configuration %d for mmdc", cfg))
> +		return -1;

This should never happen, as you checked this at event_init time.

If you must check this here, please use a real error code mnemonic
rather than -1 (which happens to be -EPERM).

> +
> +	if (flags & PERF_EF_START)
> +		mmdc_event_start(event, flags);
> +
> +	pmu_mmdc->mmdc_events[cfg] = event;
> +	pmu_mmdc->active_events++;
> +
> +	local64_set(&hwc->prev_count, mmdc_read_counter(pmu_mmdc, cfg));
> +
> +	return 0;
> +}

You must verify at pmu::add() time that the counter isn't in use
already, as you can have separate events (i.e. that aren't in the same
group) trying to reuse the same counter.

If you don't check that, then stopping/starting/resetting the counter
will not work as expected, and you will get erroneous results.

I think that here all you need to do is to check that check
pmu_mmdc->mmdc_events[cfg] is NULL before you assign to it. If it has a
non-NULL value, return -EAGAIN.

> +
> +static void mmdc_event_stop(struct perf_event *event, int flags)
> +{
> +	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
> +	void __iomem *mmdc_base, *reg;
> +	int cfg = (int)event->attr.config;
> +
> +	mmdc_base = pmu_mmdc->mmdc_base;
> +	reg = mmdc_base + MMDC_MADPCR0;
> +
> +	if (WARN_ONCE((cfg < 0 || cfg >= MMDC_NUM_COUNTERS),
> +				"invalid configuration %d for mmdc counter", cfg))
> +		return;

You checked this at event_init time. Is it really necessary to check
again?

> +static void mmdc_event_del(struct perf_event *event, int flags)
> +{
> +	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
> +	int cfg = event->attr.config;
> +
> +	pmu_mmdc->mmdc_events[cfg] = NULL;
> +	pmu_mmdc->active_events--;
> +
> +	if (pmu_mmdc->active_events <= 0)
> +		hrtimer_cancel(&pmu_mmdc->hrtimer);

You should only have to check that this is equal to zero. If
active_events is negative, you have a bigger problem.

Thanks,
Mark.

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Robin Murphy @ 2016-09-19 12:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919122435.GD9005@arm.com>

On 19/09/16 13:24, Will Deacon wrote:
> On Mon, Sep 19, 2016 at 02:13:45PM +0200, Auger Eric wrote:
>> On 16/09/2016 18:18, Robin Murphy wrote:
>>> What I probably will do, though, since we have the functionality in
>>> place for the sake of the old binding, and I think there are other folks
>>> who want PCI iommu-map support but would prefer not to bother with DMA
>>> ops on the host, is add a command-line option to disable DMA domains
>>> even for the generic bindings.
>>
>> Yes this would be a good thing I think. This series has an important
>> impact on platforms which do not have smmu v3, where contexts are scarce
>> HW resources.
> 
> Rather than disabling DMA domains entirely, we could specify a number
> of contexts to reserve for other use (e.g. VFIO). It's a pity that these
> options are global for the system, as opposed to per SMMU instance,
> but I can't see a good way around that.

The problem with that approach is that due to bus traversal order you'd
typically end up with the even-more-limited number of non-reserved
contexts getting consumed by bridges that are unlikely to ever actually
use their DMA ops, so you end up barely any better off than just not
doing DMA ops at all, which we already have the code for.

And yeah, if you had, say, "arm-smmu.reserved_s2_contexts=4", for the
benefit of your PCI SMMU, what do the SMMUs in front of your other
platform devices with only 2 contexts (and which only want DMA ops) do?

Robin.

> 
> Will
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
> 

^ permalink raw reply

* [PATCH] arm64/efi: efi_init error handling fix
From: Yisheng Xie @ 2016-09-19 12:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160913111804.GG3872@codeblueprint.co.uk>



On 2016/9/13 19:18, Matt Fleming wrote:
> On Wed, 07 Sep, at 07:15:48PM, Yisheng Xie wrote:
>>
>>
>> On 2016/9/5 21:57, Matt Fleming wrote:
>>> On Fri, 02 Sep, at 11:26:18AM, Will Deacon wrote:
>>>> On Fri, Sep 02, 2016 at 06:18:39PM +0800, Xie Yisheng wrote:
>>>>> From: Yisheng Xie <xieyisheng1@huawei.com>
>>>>>
>>>
>>> This should be a call to efi_memmap_unmap() because the EFI_MEMMAP
>>> flag also needs clearing.
>>>
>> Hi Matt,
>> Thanks for your reply.
>> You mean call the function efi_unmap_memmap() like x86?
>>
>> however, it seems no need to clear EFI_MEMMAP here. For arm*, the flag
>> EFI_MEMMAP is set in function reserve_regions(), which is called
>> only when uefi_init() return 0:
>>
>> efi_init()
>>    -> reserve_regions()
>>        -> set_bit(EFI_MEMMAP, &efi.flags);
> 
> This patch should be against the 'next' branch here,
> 
>   https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/log/?h=next
> 
> My comments were made with that branch in mind.
> 
Hi Matt,
Sorry for my misunderstanding, I will try to rebase to next branch.

Thanks.
Yisheng Xie.

> .
> 

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Will Deacon @ 2016-09-19 12:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <48f3bc10-3966-7d50-d070-7ec7f0946c92@redhat.com>

On Mon, Sep 19, 2016 at 02:13:45PM +0200, Auger Eric wrote:
> On 16/09/2016 18:18, Robin Murphy wrote:
> > What I probably will do, though, since we have the functionality in
> > place for the sake of the old binding, and I think there are other folks
> > who want PCI iommu-map support but would prefer not to bother with DMA
> > ops on the host, is add a command-line option to disable DMA domains
> > even for the generic bindings.
> 
> Yes this would be a good thing I think. This series has an important
> impact on platforms which do not have smmu v3, where contexts are scarce
> HW resources.

Rather than disabling DMA domains entirely, we could specify a number
of contexts to reserve for other use (e.g. VFIO). It's a pity that these
options are global for the system, as opposed to per SMMU instance,
but I can't see a good way around that.

Will

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Auger Eric @ 2016-09-19 12:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f16db032-1905-9804-0607-fe007af72b0e@arm.com>

Hi Robin,

On 16/09/2016 18:18, Robin Murphy wrote:
> Hi Eric,
> 
> On 15/09/16 17:46, Auger Eric wrote:
> [...]
>> Hum OK; thanks for the explanation. With that implementation however,
>> don't we face back the issue we encountered in early stage of default
>> domain implementation:
>>
>> With this sample config (AMD overdrive + I350-T2 + 2VFs per PF) I fill
>> the 8 context banks. Whereas practically we didn't need them before?
>>
>> 00:00.0 0600: 1022:1a00
>> 	Subsystem: 1022:1a00
>> 00:02.0 0600: 1022:1a01
>> 00:02.2 0604: 1022:1a02
>> 	Kernel driver in use: pcieport
>> 01:00.0 0200: 8086:1521 (rev 01)
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igb
>> 01:00.1 0200: 8086:1521 (rev 01)
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igb
>> 01:10.0 0200: 8086:1520 (rev 01) -> context 5
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: vfio-pci
>> 01:10.1 0200: 8086:1520 (rev 01) -> context 7
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igbvf
>> 01:10.4 0200: 8086:1520 (rev 01) -> context 6
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igbvf
>> 01:10.5 0200: 8086:1520 (rev 01) -> shortage
>> 	Subsystem: 8086:0002
>> 	Kernel driver in use: igbvf
>>
>> So I can't even do passthrough anymore with that config. Is there
>> anything wrong in my setup/understanding?
> 
> It's kind of hard to avoid, really - people want DMA ops support (try
> plugging a card which can only do 32-bit DMA into that Seattle, for
> instance); DMA ops need default domains; default domains are allocated
> per group; each domain requires a context bank to back it; thus if you
> have 9 groups and 8 context banks you're in a corner. It would relieve
> the pressure to have a single default domain per SMMU, but we've no way
> to do that due to the way the iommu_domain_alloc() API is intended to work.
> 
> Ultimately, it's a hardware limitation of that platform - plug in a card
> with 16 VFs with ACS, and either way you're stuck. There are a number of
> bodges I can think of that would make your specific situation work, but
> none of them are really sufficiently general to consider upstreaming.
> The most logical thing to do right now, if you were happy without DMA
> ops using the old binding before, is to keep using the old binding (just
> fixing your DT with #stream-id-cells=0 on the host controller so as not
> to create the fake aliasing problem). Hopefully future platforms will be
> in a position to couple their PCI host controllers to an IOMMU which is
> actually designed to support a PCI host controller.
> 
> What I probably will do, though, since we have the functionality in
> place for the sake of the old binding, and I think there are other folks
> who want PCI iommu-map support but would prefer not to bother with DMA
> ops on the host, is add a command-line option to disable DMA domains
> even for the generic bindings.

Yes this would be a good thing I think. This series has an important
impact on platforms which do not have smmu v3, where contexts are scarce
HW resources.

Thanks

Eric

> 
> Robin.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* [PATCH] ARM: mvebu: Select corediv clk for all mvebu v7 SoC
From: Gregory CLEMENT @ 2016-09-19 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

Since the commit bd3677ff31a3 ("clk: mvebu: Remove corediv clock from
Armada XP"), the corediv clk is no more selected for Armada XP, however
this clock is used for Armada XP using the compatible
armada-370-corediv-clock.

More over even if with the commit 1594d568c6e3 ("clk: mvebu: Move corediv
config to mvebu config"), it was selected for Armada 38x and Armada 375,
it was still not selected for Armada 39x.

Actually all the SoC selecting MVEBU_V7 config need this clock:
git grep "\-corediv-clock" arch/arm/boot/dts
arch/arm/boot/dts/armada-370-xp.dtsi: compatible = "marvell,armada-370-corediv-clock";
arch/arm/boot/dts/armada-375.dtsi:    compatible = "marvell,armada-375-corediv-clock";
arch/arm/boot/dts/armada-38x.dtsi:    compatible = "marvell,armada-380-corediv-clock";
arch/arm/boot/dts/armada-39x.dtsi:    compatible = "marvell,armada-390-corediv-clock"

This commit now fixes this behavior.

Fixes: bd3677ff31a3 ("clk: mvebu: Remove corediv clock from Armada XP")
Cc: stable at vger.kernel.org
Reported-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/Kconfig | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index f9b6bd306cfe..541647f57192 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -23,6 +23,7 @@ config MACH_MVEBU_V7
 	select CACHE_L2X0
 	select ARM_CPU_SUSPEND
 	select MACH_MVEBU_ANY
+	select MVEBU_CLK_COREDIV
 
 config MACH_ARMADA_370
 	bool "Marvell Armada 370 boards"
@@ -32,7 +33,6 @@ config MACH_ARMADA_370
 	select CPU_PJ4B
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_370
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 370 SoC with device tree.
@@ -50,7 +50,6 @@ config MACH_ARMADA_375
 	select HAVE_SMP
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_375
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 375 SoC with device tree.
@@ -68,7 +67,6 @@ config MACH_ARMADA_38X
 	select HAVE_SMP
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_38X
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 380/385 SoC with device tree.
-- 
2.9.3

^ permalink raw reply related


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