* [PATCH 1/6] arm64: Add macros to manage processor debug state
From: Vijay Kilari @ 2014-01-28 11:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140124163920.GI31040@mudshark.cambridge.arm.com>
Hi Wiil,
On Fri, Jan 24, 2014 at 10:09 PM, Will Deacon <will.deacon@arm.com> wrote:
> Hello,
>
> On Thu, Jan 23, 2014 at 03:29:07PM +0000, vijay.kilari at gmail.com wrote:
>> From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
>>
>> Add macros to enable and disable to manage PSTATE.D
>> for debugging. The macros local_dbg_save and local_dbg_restore
>> are moved to irqflags.h file
>>
>> KGDB boot tests fail because of PSTATE.D is masked.
>> unmask it for debugging support
>>
>> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
>> ---
>> arch/arm64/include/asm/debug-monitors.h | 17 -----------
>> arch/arm64/include/asm/irqflags.h | 48 +++++++++++++++++++++++++++++++
>> arch/arm64/kernel/debug-monitors.c | 1 +
>> 3 files changed, 49 insertions(+), 17 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
>> index 6231479..ee9f28e 100644
>> --- a/arch/arm64/include/asm/debug-monitors.h
>> +++ b/arch/arm64/include/asm/debug-monitors.h
>> @@ -43,23 +43,6 @@ enum debug_el {
>> #ifndef __ASSEMBLY__
>> struct task_struct;
>>
>> -#define local_dbg_save(flags) \
>> - do { \
>> - typecheck(unsigned long, flags); \
>> - asm volatile( \
>> - "mrs %0, daif // local_dbg_save\n" \
>> - "msr daifset, #8" \
>> - : "=r" (flags) : : "memory"); \
>> - } while (0)
>> -
>> -#define local_dbg_restore(flags) \
>> - do { \
>> - typecheck(unsigned long, flags); \
>> - asm volatile( \
>> - "msr daif, %0 // local_dbg_restore\n" \
>> - : : "r" (flags) : "memory"); \
>> - } while (0)
>> -
>> #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
>>
>> #define DBG_HOOK_HANDLED 0
>> diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
>> index b2fcfbc..f9b013e 100644
>> --- a/arch/arm64/include/asm/irqflags.h
>> +++ b/arch/arm64/include/asm/irqflags.h
>> @@ -90,5 +90,53 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
>> return flags & PSR_I_BIT;
>> }
>>
>> +/*
>> + * save and restore debug state
>> + */
>> +static inline unsigned long arch_local_dbg_save(void)
>> +{
>> + unsigned long flags;
>> + asm volatile(
>> + "mrs %0, daif // arch_local_dbg_save"
>> + "msr daifset, #8"
>> + : "=r" (flags) : : "memory");
>> + return flags;
>> +}
>> +
>> +static inline void arch_local_dbg_restore(unsigned long flags)
>> +{
>> + asm volatile(
>> + "msr daif, %0 // arch_local_dbg_restore"
>> + :
>> + : "r" (flags)
>> + : "memory");
>> +}
>> +
>> +#define raw_local_dbg_save(flags) \
>> + do { \
>> + typecheck(unsigned long, flags); \
>> + flags = arch_local_dbg_save(); \
>> + } while (0)
>> +
>> +#define raw_local_dbg_restore(flags) \
>> + do { \
>> + typecheck(unsigned long, flags); \
>> + arch_local_dbg_restore(flags); \
>> + } while (0)
>> +
>> +#define local_dbg_save(flags) \
>> + do { \
>> + raw_local_dbg_save(flags); \
>> + } while (0)
>> +
>> +#define local_dbg_restore(flags) \
>> + do { \
>> + typecheck(unsigned long, flags); \
>> + raw_local_dbg_restore(flags); \
>> + } while (0)
>
> Hehe, I think you took me a bit too literally when I said to follow what we
> do for irqs. This code is arm64-specific, so you don't need to construct it
> in the same way. All you need to do is *move* the existing code from
> debug-monitors.h to irqflags.h. That's it!
>
I have reposted the patch (v9) please review.
>> +#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory")
>> +#define local_dbg_disable() asm("msr daifset, #8" : : : "memory")
>
> I'm also fine with adding these two.
>
> Will
^ permalink raw reply
* [Patch v3 2/2] dmaengine: qcom_bam_dma: Add device tree binding
From: Vinod Koul @ 2014-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128111756.GE15937@n2100.arm.linux.org.uk>
On Tue, Jan 28, 2014 at 11:17:57AM +0000, Russell King - ARM Linux wrote:
> On Tue, Jan 28, 2014 at 10:16:53AM +0100, Arnd Bergmann wrote:
> > On Tuesday 28 January 2014 10:05:35 Lars-Peter Clausen wrote:
> > > Why does the direction needs to be specified in specifier? I see two
> > > options, either the direction per is fixed in hardware. In that case the DMA
> > > controller node should describe which channel is which direction. Or the
> > > direction is not fixed in hardware and can be changed at runtime in which
> > > case it should be set on a per descriptor basis.
> >
> > Normally the direction is implied by dmaengine_slave_config().
>
> No. The direction argument in there is deprecated - we've been talking
> about removing it for some time.
>
> DMA engine drivers should store all parameters of the configuration, and
> then select the appropriate ones when preparing a transfer (which itself
> involves a direction.)
Right all the prep_ calls for slave cases have explcit direction argument so
sending it using slave config makes no sense. So will remove it after the merge
window closes and fix :)
--
~Vinod
>
> Not doing this implies that if you have a half-duplex device, you have to
> repeatedly issue a dmaengine_slave_config() call, a prepare call, and a
> submit call to the DMA engine code for every segment you want to transfer.
> We don't need that kind of DMA engine specific behaviour in DMA engine
> users.
>
> --
> FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
> in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
> Estimate before purchase was "up to 13.2Mbit".
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
^ permalink raw reply
* [PATCH] ARM: dts: imx28-m28cu3: Remove 'reset-active-high'
From: Shawn Guo @ 2014-01-28 11:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390596324-20904-1-git-send-email-festevam@gmail.com>
On Fri, Jan 24, 2014 at 06:45:24PM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
>
> The 'reset-active-high' property is not defined anywhere, so just remove it.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Applied, thanks.
^ permalink raw reply
* [RFC PATCH 2/3] ARM/ARM64: KVM: Add support for PSCI v0.2 emulation
From: Marc Zyngier @ 2014-01-28 11:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390309301-28424-3-git-send-email-anup.patel@linaro.org>
Hi Anup,
On 21/01/14 13:01, Anup Patel wrote:
> Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to
> VCPUs. This patch extends current in-kernel PSCI emulation to provide
> PSCI v0.2 interface to VCPUs.
>
> By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for
> keeping the ABI backward-compatible.
>
> To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or
> KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU
> init using KVM_ARM_VCPU_INIT ioctl.
>
> Signed-off-by: Anup Patel <anup.patel@linaro.org>
> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
> ---
> arch/arm/include/asm/kvm_host.h | 2 +-
> arch/arm/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
> arch/arm/kvm/arm.c | 6 ++-
> arch/arm/kvm/psci.c | 79 ++++++++++++++++++++++++++++++-------
> arch/arm64/include/asm/kvm_host.h | 2 +-
> arch/arm64/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
> 6 files changed, 143 insertions(+), 24 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 8a6f6db..0239ac5 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -36,7 +36,7 @@
> #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
> #define KVM_HAVE_ONE_REG
>
> -#define KVM_VCPU_MAX_FEATURES 1
> +#define KVM_VCPU_MAX_FEATURES 2
>
> #include <kvm/arm_vgic.h>
>
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index c498b60..d9eb74c 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -83,6 +83,7 @@ struct kvm_regs {
> #define KVM_VGIC_V2_CPU_SIZE 0x2000
>
> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
> +#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
>
> struct kvm_vcpu_init {
> __u32 target;
> @@ -164,7 +165,7 @@ struct kvm_arch_memory_slot {
> /* Highest supported SPI, from VGIC_NR_IRQS */
> #define KVM_ARM_IRQ_GIC_MAX 127
>
> -/* PSCI interface */
> +/* PSCI v0.1 interface */
> #define KVM_PSCI_FN_BASE 0x95c1ba5e
> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>
> @@ -173,9 +174,41 @@ struct kvm_arch_memory_slot {
> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>
> +/* PSCI v0.2 interface */
> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
> +
> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
> + KVM_PSCI_0_2_FN(6)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN(7)
> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
> +
> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN64(7)
> +
> +/* PSCI return values */
> #define KVM_PSCI_RET_SUCCESS 0
> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
This is a massive no-no. It is already part of the userspace API, and we
cannot break it (neither arm nor arm64). These #defines have to stay
forever.
> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
As such, you can drop these two defines, and use the original ones in
your new code, which will reduce the churn.
> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>
> #endif /* __ARM_KVM_H__ */
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 2a700e0..0b7817a 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -193,6 +193,7 @@ int kvm_dev_ioctl_check_extension(long ext)
> case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
> case KVM_CAP_ONE_REG:
> case KVM_CAP_ARM_PSCI:
> + case KVM_CAP_ARM_PSCI_0_2:
> r = 1;
> break;
> case KVM_CAP_COALESCED_MMIO:
> @@ -483,7 +484,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
> * PSCI code.
> */
> if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) {
> - *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
Can you make this a function? Something like:
int get_psci_version(struct kvm_vcpu *vcpu)
{
if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
return PSCI_VERSION_0_2;
return PSCI_VERSION_0_1;
}
probably located in psci.c. This way, when PSCI version 3.14159 comes
along, we'll have some mechanism in place, and we're free to change the
detection method without impacting the rest of the code.
> + *vcpu_reg(vcpu, 0) = KVM_PSCI_0_2_FN_CPU_OFF;
> + else
> + *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
> kvm_psci_call(vcpu);
> }
>
> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
> index 0881bf1..ee044a3 100644
> --- a/arch/arm/kvm/psci.c
> +++ b/arch/arm/kvm/psci.c
> @@ -55,13 +55,13 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
> }
>
> if (!vcpu)
> - return KVM_PSCI_RET_INVAL;
> + return KVM_PSCI_RET_INVALID_PARAMS;
>
> target_pc = *vcpu_reg(source_vcpu, 2);
>
> wq = kvm_arch_vcpu_wq(vcpu);
> if (!waitqueue_active(wq))
> - return KVM_PSCI_RET_INVAL;
> + return KVM_PSCI_RET_INVALID_PARAMS;
>
> kvm_reset_vcpu(vcpu);
>
> @@ -84,17 +84,49 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
> return KVM_PSCI_RET_SUCCESS;
> }
>
> -/**
> - * kvm_psci_call - handle PSCI call if r0 value is in range
> - * @vcpu: Pointer to the VCPU struct
> - *
> - * Handle PSCI calls from guests through traps from HVC instructions.
> - * The calling convention is similar to SMC calls to the secure world where
> - * the function number is placed in r0 and this function returns true if the
> - * function number specified in r0 is withing the PSCI range, and false
> - * otherwise.
> - */
> -bool kvm_psci_call(struct kvm_vcpu *vcpu)
> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
> +{
> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
> + unsigned long val;
> +
> + switch (psci_fn) {
> + case KVM_PSCI_0_2_FN_PSCI_VERSION:
> + /*
> + * Bits[31:16] = Major Version = 0
> + * Bits[15:0] = Minor Version = 2
> + */
> + val = 2;
> + break;
> + case KVM_PSCI_0_2_FN_CPU_OFF:
> + kvm_psci_vcpu_off(vcpu);
> + val = KVM_PSCI_RET_SUCCESS;
> + break;
> + case KVM_PSCI_0_2_FN_CPU_ON:
> + case KVM_PSCI_0_2_FN64_CPU_ON:
> + val = kvm_psci_vcpu_on(vcpu);
> + break;
> + case KVM_PSCI_0_2_FN_CPU_SUSPEND:
> + case KVM_PSCI_0_2_FN_AFFINITY_INFO:
> + case KVM_PSCI_0_2_FN_MIGRATE:
> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
> + case KVM_PSCI_0_2_FN_SYSTEM_OFF:
> + case KVM_PSCI_0_2_FN_SYSTEM_RESET:
> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND:
> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO:
> + case KVM_PSCI_0_2_FN64_MIGRATE:
> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
> + val = KVM_PSCI_RET_NOT_SUPPORTED;
> + break;
> + default:
> + return false;
> + }
> +
> + *vcpu_reg(vcpu, 0) = val;
> + return true;
> +}
> +
> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
> {
> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
> unsigned long val;
> @@ -109,9 +141,8 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
> break;
> case KVM_PSCI_FN_CPU_SUSPEND:
> case KVM_PSCI_FN_MIGRATE:
> - val = KVM_PSCI_RET_NI;
> + val = KVM_PSCI_RET_NOT_SUPPORTED;
> break;
> -
> default:
> return false;
> }
> @@ -119,3 +150,21 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
> *vcpu_reg(vcpu, 0) = val;
> return true;
> }
> +
> +/**
> + * kvm_psci_call - handle PSCI call if r0 value is in range
> + * @vcpu: Pointer to the VCPU struct
> + *
> + * Handle PSCI calls from guests through traps from HVC instructions.
> + * The calling convention is similar to SMC calls to the secure world where
> + * the function number is placed in r0 and this function returns true if the
> + * function number specified in r0 is withing the PSCI range, and false
> + * otherwise.
> + */
> +bool kvm_psci_call(struct kvm_vcpu *vcpu)
> +{
> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
> + return kvm_psci_0_2_call(vcpu);
> +
> + return kvm_psci_0_1_call(vcpu);
> +}
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 0a1d697..92242ce 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -39,7 +39,7 @@
> #include <kvm/arm_vgic.h>
> #include <kvm/arm_arch_timer.h>
>
> -#define KVM_VCPU_MAX_FEATURES 2
> +#define KVM_VCPU_MAX_FEATURES 3
>
> struct kvm_vcpu;
> int kvm_target_cpu(void);
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index d9f026b..0eb254d 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -77,6 +77,7 @@ struct kvm_regs {
>
> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
> #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
> +#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
>
> struct kvm_vcpu_init {
> __u32 target;
> @@ -150,7 +151,7 @@ struct kvm_arch_memory_slot {
> /* Highest supported SPI, from VGIC_NR_IRQS */
> #define KVM_ARM_IRQ_GIC_MAX 127
>
> -/* PSCI interface */
> +/* PSCI v0.1 interface */
> #define KVM_PSCI_FN_BASE 0x95c1ba5e
> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>
> @@ -159,10 +160,42 @@ struct kvm_arch_memory_slot {
> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>
> +/* PSCI v0.2 interface */
> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
> +
> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
> + KVM_PSCI_0_2_FN(6)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN(7)
> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
> +
> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN64(7)
> +
> +/* PSCI return values */
> #define KVM_PSCI_RET_SUCCESS 0
> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>
> #endif
>
> --
> 1.7.9.5
With the above remarks fixed, I think we'll have a good base for future
developments. Looking forward to the next version.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH 2/9] ARM: dts: imx6sl: remove the use of pingrp macros
From: Shawn Guo @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5923680.sl3G3EgCsY@phil>
On Tue, Jan 28, 2014 at 11:17:22AM +0100, Heiko St?bner wrote:
> [... and so on for the other groups ... ]
>
> I'm confused now :-) . Current linux-next [0] shows the pin-settings as part
> of imx6sl.dtsi - a way a lot of other architectures organize their pingroups
> too, with the board file only referencing the relevant pingroups from the
> predefined ones of the soc.
>
> So I guess your move to the pingrp-header moved them out of the imx6sl.dtsi to
> the .h and is not part of linux-next;
Yes, my for-next branch was excluded from linux-next temporarily for
some reason. I will ask Stephen to add it back once v3.14-rc1 is out.
That said, you can see nothing we developed in this cycle on linux-next
for now.
> but this patch (and the others in this
> series) now moves the definitions into the individual board files. Can't you
> just move them back to the soc-dtsi files to prevent each board duplicating
> them?
No. That will bring back the problem we try to solve from the
beginning [1].
Shawn
[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/275912/
^ permalink raw reply
* [PATCH v9 6/6] arm64: KGDB: Add KGDB config
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add HAVE_ARCH_KGDB for arm64 Kconfig
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
arch/arm64/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6d4dd22..c7a08e0 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -28,6 +28,7 @@ config ARM64
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_MEMBLOCK
select HAVE_PERF_EVENTS
+ select HAVE_ARCH_KGDB
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select NO_BOOTMEM
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 5/6] misc: debug: remove compilation warnings
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
typecast instruction_pointer macro to unsigned long to
resolve following compiler warnings like
warning: format '%lx' expects argument of type 'long unsigned int',
but argument 2 has type 'u64' [-Wformat]
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
arch/arm64/include/asm/ptrace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0e7fa49..5233966 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -164,7 +164,7 @@ static inline int valid_user_regs(struct user_pt_regs *regs)
return 0;
}
-#define instruction_pointer(regs) (regs)->pc
+#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 4/6] KGDB: make kgdb_breakpoint() as noinline
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
The function kgdb_breakpoint() sets up break point at
compile time by calling arch_kgdb_breakpoint();
Though this call is surrounded by wmb() barrier,
the compile can still re-order the break point,
because this scheduling barrier is not a code motion
barrier in gcc.
Making kgdb_breakpoint() as noinline solves this problem
of code reording around break point instruction and also
avoids problem of being called as inline function from
other places
More details about discussion on this can be found here
http://comments.gmane.org/gmane.linux.ports.arm.kernel/269732
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Acked-by: Jason Wessel <jason.wessel@windriver.com>
---
kernel/debug/debug_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 7d2f35e..cf04798 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -1034,7 +1034,7 @@ int dbg_io_get_char(void)
* otherwise as a quick means to stop program execution and "break" into
* the debugger.
*/
-void kgdb_breakpoint(void)
+noinline void kgdb_breakpoint(void)
{
atomic_inc(&kgdb_setting_breakpoint);
wmb(); /* Sync point before breakpoint */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 3/6] arm64: KGDB: Add step debugging support
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add KGDB software step debugging support for EL1 debug
in AArch64 mode.
KGDB registers step debug handler with debug monitor.
On receiving 'step' command from GDB tool, target enables
software step debugging and step address is updated in ELR.
Software Step debugging is disabled when 'continue' command
is received
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/kgdb.c | 64 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 56 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index 4b7a569..75c9cf1 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -137,13 +137,26 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
static int compiled_break;
+static void kgdb_arch_update_addr(struct pt_regs *regs,
+ char *remcom_in_buffer)
+{
+ unsigned long addr;
+ char *ptr;
+
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &addr))
+ kgdb_arch_set_pc(regs, addr);
+ else if (compiled_break == 1)
+ kgdb_arch_set_pc(regs, regs->pc + 4);
+
+ compiled_break = 0;
+}
+
int kgdb_arch_handle_exception(int exception_vector, int signo,
int err_code, char *remcom_in_buffer,
char *remcom_out_buffer,
struct pt_regs *linux_regs)
{
- unsigned long addr;
- char *ptr;
int err;
switch (remcom_in_buffer[0]) {
@@ -162,13 +175,36 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
* to the next instruction else we will just breakpoint
* over and over again.
*/
- ptr = &remcom_in_buffer[1];
- if (kgdb_hex2long(&ptr, &addr))
- kgdb_arch_set_pc(linux_regs, addr);
- else if (compiled_break == 1)
- kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4);
+ kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
+ atomic_set(&kgdb_cpu_doing_single_step, -1);
+ kgdb_single_step = 0;
+
+ /*
+ * Received continue command, disable single step
+ */
+ if (kernel_active_single_step())
+ kernel_disable_single_step();
+
+ err = 0;
+ break;
+ case 's':
+ /*
+ * Update step address value with address passed
+ * with step packet.
+ * On debug exception return PC is copied to ELR
+ * So just update PC.
+ * If no step address is passed, resume from the address
+ * pointed by PC. Do not update PC
+ */
+ kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
+ atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
+ kgdb_single_step = 1;
- compiled_break = 0;
+ /*
+ * Enable single step handling
+ */
+ if (!kernel_active_single_step())
+ kernel_enable_single_step(linux_regs);
err = 0;
break;
default:
@@ -191,6 +227,12 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
return 0;
}
+static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
+{
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+ return 0;
+}
+
static struct break_hook kgdb_brkpt_hook = {
.esr_mask = 0xffffffff,
.esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
@@ -203,6 +245,10 @@ static struct break_hook kgdb_compiled_brkpt_hook = {
.fn = kgdb_compiled_brk_fn
};
+static struct step_hook kgdb_step_hook = {
+ .fn = kgdb_step_brk_fn
+};
+
static void kgdb_call_nmi_hook(void *ignored)
{
kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
@@ -259,6 +305,7 @@ int kgdb_arch_init(void)
register_break_hook(&kgdb_brkpt_hook);
register_break_hook(&kgdb_compiled_brkpt_hook);
+ register_step_hook(&kgdb_step_hook);
return 0;
}
@@ -271,6 +318,7 @@ void kgdb_arch_exit(void)
{
unregister_break_hook(&kgdb_brkpt_hook);
unregister_break_hook(&kgdb_compiled_brkpt_hook);
+ unregister_step_hook(&kgdb_step_hook);
unregister_die_notifier(&kgdb_notifier);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 2/6] arm64: KGDB: Add Basic KGDB support
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add KGDB debug support for kernel debugging.
With this patch, basic KGDB debugging is possible.GDB register
layout is updated and GDB tool can establish connection with
target and can set/clear breakpoints.
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/debug-monitors.h | 47 +++++
arch/arm64/include/asm/kgdb.h | 84 +++++++++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/kgdb.c | 288 +++++++++++++++++++++++++++++++
4 files changed, 420 insertions(+)
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index ee9f28e..6e9b5b3 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -26,6 +26,53 @@
#define DBG_ESR_EVT_HWWP 0x2
#define DBG_ESR_EVT_BRK 0x6
+/*
+ * Break point instruction encoding
+ */
+#define BREAK_INSTR_SIZE 4
+
+/*
+ * ESR values expected for dynamic and compile time BRK instruction
+ */
+#define DBG_ESR_VAL_BRK(x) (0xf2000000 | ((x) & 0xfffff))
+
+/*
+ * #imm16 values used for BRK instruction generation
+ * Allowed values for kgbd are 0x400 - 0x7ff
+ * 0x400: for dynamic BRK instruction
+ * 0x401: for compile time BRK instruction
+ */
+#define KGDB_DYN_DGB_BRK_IMM 0x400
+#define KDBG_COMPILED_DBG_BRK_IMM 0x401
+
+/*
+ * BRK instruction encoding
+ * The #imm16 value should be placed at bits[20:5] within BRK ins
+ */
+#define AARCH64_BREAK_MON 0xd4200000
+
+/*
+ * Extract byte from BRK instruction
+ */
+#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \
+ ((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff)
+
+/*
+ * Extract byte from BRK #imm16
+ */
+#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \
+ (((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff)
+
+#define KGDB_DYN_DGB_BRK_BYTE(x) \
+ (KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x))
+
+#define KGDB_DYN_BRK_INS_BYTE0 KGDB_DYN_DGB_BRK_BYTE(0)
+#define KGDB_DYN_BRK_INS_BYTE1 KGDB_DYN_DGB_BRK_BYTE(1)
+#define KGDB_DYN_BRK_INS_BYTE2 KGDB_DYN_DGB_BRK_BYTE(2)
+#define KGDB_DYN_BRK_INS_BYTE3 KGDB_DYN_DGB_BRK_BYTE(3)
+
+#define CACHE_FLUSH_IS_SAFE 1
+
enum debug_el {
DBG_ACTIVE_EL0 = 0,
DBG_ACTIVE_EL1,
diff --git a/arch/arm64/include/asm/kgdb.h b/arch/arm64/include/asm/kgdb.h
new file mode 100644
index 0000000..3c8aafc
--- /dev/null
+++ b/arch/arm64/include/asm/kgdb.h
@@ -0,0 +1,84 @@
+/*
+ * AArch64 KGDB support
+ *
+ * Based on arch/arm/include/kgdb.h
+ *
+ * Copyright (C) 2013 Cavium Inc.
+ * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_KGDB_H
+#define __ARM_KGDB_H
+
+#include <linux/ptrace.h>
+#include <asm/debug-monitors.h>
+
+#ifndef __ASSEMBLY__
+
+static inline void arch_kgdb_breakpoint(void)
+{
+ asm ("brk %0" : : "I" (KDBG_COMPILED_DBG_BRK_IMM));
+}
+
+extern void kgdb_handle_bus_error(void);
+extern int kgdb_fault_expected;
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * gdb is expecting the following registers layout.
+ *
+ * General purpose regs:
+ * r0-r30: 64 bit
+ * sp,pc : 64 bit
+ * pstate : 64 bit
+ * Total: 34
+ * FPU regs:
+ * f0-f31: 128 bit
+ * Total: 32
+ * Extra regs
+ * fpsr & fpcr: 32 bit
+ * Total: 2
+ *
+ */
+
+#define _GP_REGS 34
+#define _FP_REGS 32
+#define _EXTRA_REGS 2
+/*
+ * general purpose registers size in bytes.
+ * pstate is only 4 bytes. subtract 4 bytes
+ */
+#define GP_REG_BYTES (_GP_REGS * 8)
+#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
+
+/*
+ * Size of I/O buffer for gdb packet.
+ * considering to hold all register contents, size is set
+ */
+
+#define BUFMAX 2048
+
+/*
+ * Number of bytes required for gdb_regs buffer.
+ * _GP_REGS: 8 bytes, _FP_REGS: 16 bytes and _EXTRA_REGS: 4 bytes each
+ * GDB fails to connect for size beyond this with error
+ * "'g' packet reply is too long"
+ */
+
+#define NUMREGBYTES ((_GP_REGS * 8) + (_FP_REGS * 16) + \
+ (_EXTRA_REGS * 4))
+
+#endif /* __ASM_KGDB_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 5ba2fd4..b9b87fa 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -18,6 +18,7 @@ arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o
arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+arm64-obj-$(CONFIG_KGDB) += kgdb.o
obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
new file mode 100644
index 0000000..4b7a569
--- /dev/null
+++ b/arch/arm64/kernel/kgdb.c
@@ -0,0 +1,288 @@
+/*
+ * AArch64 KGDB support
+ *
+ * Based on arch/arm/kernel/kgdb.c
+ *
+ * Copyright (C) 2013 Cavium Inc.
+ * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/irq.h>
+#include <linux/kdebug.h>
+#include <linux/kgdb.h>
+#include <asm/traps.h>
+
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
+ { "x0", 8, offsetof(struct pt_regs, regs[0])},
+ { "x1", 8, offsetof(struct pt_regs, regs[1])},
+ { "x2", 8, offsetof(struct pt_regs, regs[2])},
+ { "x3", 8, offsetof(struct pt_regs, regs[3])},
+ { "x4", 8, offsetof(struct pt_regs, regs[4])},
+ { "x5", 8, offsetof(struct pt_regs, regs[5])},
+ { "x6", 8, offsetof(struct pt_regs, regs[6])},
+ { "x7", 8, offsetof(struct pt_regs, regs[7])},
+ { "x8", 8, offsetof(struct pt_regs, regs[8])},
+ { "x9", 8, offsetof(struct pt_regs, regs[9])},
+ { "x10", 8, offsetof(struct pt_regs, regs[10])},
+ { "x11", 8, offsetof(struct pt_regs, regs[11])},
+ { "x12", 8, offsetof(struct pt_regs, regs[12])},
+ { "x13", 8, offsetof(struct pt_regs, regs[13])},
+ { "x14", 8, offsetof(struct pt_regs, regs[14])},
+ { "x15", 8, offsetof(struct pt_regs, regs[15])},
+ { "x16", 8, offsetof(struct pt_regs, regs[16])},
+ { "x17", 8, offsetof(struct pt_regs, regs[17])},
+ { "x18", 8, offsetof(struct pt_regs, regs[18])},
+ { "x19", 8, offsetof(struct pt_regs, regs[19])},
+ { "x20", 8, offsetof(struct pt_regs, regs[20])},
+ { "x21", 8, offsetof(struct pt_regs, regs[21])},
+ { "x22", 8, offsetof(struct pt_regs, regs[22])},
+ { "x23", 8, offsetof(struct pt_regs, regs[23])},
+ { "x24", 8, offsetof(struct pt_regs, regs[24])},
+ { "x25", 8, offsetof(struct pt_regs, regs[25])},
+ { "x26", 8, offsetof(struct pt_regs, regs[26])},
+ { "x27", 8, offsetof(struct pt_regs, regs[27])},
+ { "x28", 8, offsetof(struct pt_regs, regs[28])},
+ { "x29", 8, offsetof(struct pt_regs, regs[29])},
+ { "x30", 8, offsetof(struct pt_regs, regs[30])},
+ { "sp", 8, offsetof(struct pt_regs, sp)},
+ { "pc", 8, offsetof(struct pt_regs, pc)},
+ { "pstate", 8, offsetof(struct pt_regs, pstate)},
+ { "v0", 16, -1 },
+ { "v1", 16, -1 },
+ { "v2", 16, -1 },
+ { "v3", 16, -1 },
+ { "v4", 16, -1 },
+ { "v5", 16, -1 },
+ { "v6", 16, -1 },
+ { "v7", 16, -1 },
+ { "v8", 16, -1 },
+ { "v9", 16, -1 },
+ { "v10", 16, -1 },
+ { "v11", 16, -1 },
+ { "v12", 16, -1 },
+ { "v13", 16, -1 },
+ { "v14", 16, -1 },
+ { "v15", 16, -1 },
+ { "v16", 16, -1 },
+ { "v17", 16, -1 },
+ { "v18", 16, -1 },
+ { "v19", 16, -1 },
+ { "v20", 16, -1 },
+ { "v21", 16, -1 },
+ { "v22", 16, -1 },
+ { "v23", 16, -1 },
+ { "v24", 16, -1 },
+ { "v25", 16, -1 },
+ { "v26", 16, -1 },
+ { "v27", 16, -1 },
+ { "v28", 16, -1 },
+ { "v29", 16, -1 },
+ { "v30", 16, -1 },
+ { "v31", 16, -1 },
+ { "fpsr", 4, -1 },
+ { "fpcr", 4, -1 },
+};
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+ else
+ memset(mem, 0, dbg_reg_def[regno].size);
+ return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return -EINVAL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+ return 0;
+}
+
+void
+sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
+{
+ struct pt_regs *thread_regs;
+
+ /* Initialize to zero */
+ memset((char *)gdb_regs, 0, NUMREGBYTES);
+ thread_regs = task_pt_regs(task);
+ memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES);
+}
+
+void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+{
+ regs->pc = pc;
+}
+
+static int compiled_break;
+
+int kgdb_arch_handle_exception(int exception_vector, int signo,
+ int err_code, char *remcom_in_buffer,
+ char *remcom_out_buffer,
+ struct pt_regs *linux_regs)
+{
+ unsigned long addr;
+ char *ptr;
+ int err;
+
+ switch (remcom_in_buffer[0]) {
+ case 'D':
+ case 'k':
+ /*
+ * Packet D (Detach), k (kill). No special handling
+ * is required here. Handle same as c packet.
+ */
+ case 'c':
+ /*
+ * Packet c (Continue) to continue executing.
+ * Set pc to required address.
+ * Try to read optional parameter and set pc.
+ * If this was a compiled breakpoint, we need to move
+ * to the next instruction else we will just breakpoint
+ * over and over again.
+ */
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &addr))
+ kgdb_arch_set_pc(linux_regs, addr);
+ else if (compiled_break == 1)
+ kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4);
+
+ compiled_break = 0;
+ err = 0;
+ break;
+ default:
+ err = -1;
+ }
+ return err;
+}
+
+static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr)
+{
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+ return 0;
+}
+
+static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
+{
+ compiled_break = 1;
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
+ return 0;
+}
+
+static struct break_hook kgdb_brkpt_hook = {
+ .esr_mask = 0xffffffff,
+ .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
+ .fn = kgdb_brk_fn
+};
+
+static struct break_hook kgdb_compiled_brkpt_hook = {
+ .esr_mask = 0xffffffff,
+ .esr_val = DBG_ESR_VAL_BRK(KDBG_COMPILED_DBG_BRK_IMM),
+ .fn = kgdb_compiled_brk_fn
+};
+
+static void kgdb_call_nmi_hook(void *ignored)
+{
+ kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+ local_irq_enable();
+ smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+ local_irq_disable();
+}
+
+static int __kgdb_notify(struct die_args *args, unsigned long cmd)
+{
+ struct pt_regs *regs = args->regs;
+
+ if (kgdb_handle_exception(1, args->signr, cmd, regs))
+ return NOTIFY_DONE;
+ return NOTIFY_STOP;
+}
+
+static int
+kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ ret = __kgdb_notify(ptr, cmd);
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+static struct notifier_block kgdb_notifier = {
+ .notifier_call = kgdb_notify,
+ /*
+ * Want to be lowest priority
+ */
+ .priority = -INT_MAX,
+};
+
+/*
+ * kgdb_arch_init - Perform any architecture specific initalization.
+ * This function will handle the initalization of any architecture
+ * specific callbacks.
+ */
+int kgdb_arch_init(void)
+{
+ int ret = register_die_notifier(&kgdb_notifier);
+
+ if (ret != 0)
+ return ret;
+
+ register_break_hook(&kgdb_brkpt_hook);
+ register_break_hook(&kgdb_compiled_brkpt_hook);
+ return 0;
+}
+
+/*
+ * kgdb_arch_exit - Perform any architecture specific uninitalization.
+ * This function will handle the uninitalization of any architecture
+ * specific callbacks, for dynamic registration and unregistration.
+ */
+void kgdb_arch_exit(void)
+{
+ unregister_break_hook(&kgdb_brkpt_hook);
+ unregister_break_hook(&kgdb_compiled_brkpt_hook);
+ unregister_die_notifier(&kgdb_notifier);
+}
+
+/*
+ * ARM instructions are always in LE.
+ * Break instruction is encoded in LE format
+ */
+struct kgdb_arch arch_kgdb_ops = {
+ .gdb_bpt_instr = {
+ KGDB_DYN_BRK_INS_BYTE0,
+ KGDB_DYN_BRK_INS_BYTE1,
+ KGDB_DYN_BRK_INS_BYTE2,
+ KGDB_DYN_BRK_INS_BYTE3,
+ }
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 1/6] arm64: Add macros to manage processor debug state
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add macros to enable and disable to manage PSTATE.D
for debugging. The macros local_dbg_save and local_dbg_restore
are moved to irqflags.h file
KGDB boot tests fail because of PSTATE.D is masked.
unmask it for debugging support
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
arch/arm64/include/asm/debug-monitors.h | 17 -----------------
arch/arm64/include/asm/irqflags.h | 23 +++++++++++++++++++++++
arch/arm64/kernel/debug-monitors.c | 1 +
3 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 6231479..ee9f28e 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -43,23 +43,6 @@ enum debug_el {
#ifndef __ASSEMBLY__
struct task_struct;
-#define local_dbg_save(flags) \
- do { \
- typecheck(unsigned long, flags); \
- asm volatile( \
- "mrs %0, daif // local_dbg_save\n" \
- "msr daifset, #8" \
- : "=r" (flags) : : "memory"); \
- } while (0)
-
-#define local_dbg_restore(flags) \
- do { \
- typecheck(unsigned long, flags); \
- asm volatile( \
- "msr daif, %0 // local_dbg_restore\n" \
- : : "r" (flags) : "memory"); \
- } while (0)
-
#define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
#define DBG_HOOK_HANDLED 0
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index b2fcfbc..11cc941 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -90,5 +90,28 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
return flags & PSR_I_BIT;
}
+/*
+ * save and restore debug state
+ */
+#define local_dbg_save(flags) \
+ do { \
+ typecheck(unsigned long, flags); \
+ asm volatile( \
+ "mrs %0, daif // local_dbg_save\n" \
+ "msr daifset, #8" \
+ : "=r" (flags) : : "memory"); \
+ } while (0)
+
+#define local_dbg_restore(flags) \
+ do { \
+ typecheck(unsigned long, flags); \
+ asm volatile( \
+ "msr daif, %0 // local_dbg_restore\n" \
+ : : "r" (flags) : "memory"); \
+ } while (0)
+
+#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory")
+#define local_dbg_disable() asm("msr daifset, #8" : : : "memory")
+
#endif
#endif
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 23586bd..a86e5b1 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -138,6 +138,7 @@ static void clear_os_lock(void *unused)
{
asm volatile("msr oslar_el1, %0" : : "r" (0));
isb();
+ local_dbg_enable();
}
static int os_lock_notify(struct notifier_block *self,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 0/6] arm64: KGDB Support
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Based on the step-handler and break-handler hooks patch from
Sandeepa, KGDB debugging support is added for EL1
debug in AArch64 mode.
In first patch, PSTATE.D is set correctly
In second patch,register layout is updated to be inline with GDB tool.
Basic GDB connection, break point set/clear and info commands
are supported except step/next debugging
With second patch, step/next debugging support is added, where in
pc is updated to point to the instruction to be stepped and
stopped.
With third patch, the compile time breakpoint instruction
reordering is fixed by making kgbd_breakpoint() as noinline
Tested with ARM64 simulator
v9:
- minor code movement comments fix
v8:
- fixed comments on local_dbg_{save,restore} macros
- instruction_pointer() macro to return unsigned long to fix
compilation warnings
v7:
- Changes made to set PSTATE.D properly
- Performed KGDB boot tests
- Fixed compilation warnings in driver/misc/kgbdts.c
Results:
kgdb boot test:
[32927.237895] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[32927.266066] kgdb: Registered I/O driver kgdbts.
[32927.266419] kgdb: Waiting for connection from remote gdb...
[32927.268598] kgdbts:RUN plant and detach test
[32927.270683] kgdbts:RUN sw breakpoint test
[32927.287659] kgdbts:RUN bad memory access test
[32927.290322] kgdbts:RUN singlestep test 1000 iterations
[32927.330342] kgdbts:RUN singlestep [0/1000]
[32931.286356] kgdbts:RUN singlestep [100/1000]
[32935.242536] kgdbts:RUN singlestep [200/1000]
[32939.205392] kgdbts:RUN singlestep [300/1000]
[32943.169522] kgdbts:RUN singlestep [400/1000]
[32947.231868] kgdbts:RUN singlestep [500/1000]
[32951.188008] kgdbts:RUN singlestep [600/1000]
[32955.332243] kgdbts:RUN singlestep [700/1000]
[32959.467109] kgdbts:RUN singlestep [800/1000]
[32963.430888] kgdbts:RUN singlestep [900/1000]
[32967.346992] kgdbts:RUN do_fork for 100 breakpoints
kgdb test from sysfs:
~ # echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
[33231.554237] kgdb: Registered I/O driver kgdbts.
[33231.554677] kgdbts:RUN plant and detach test
[33231.557072] kgdbts:RUN sw breakpoint test
[33231.576980] kgdbts:RUN bad memory access test
[33231.580022] kgdbts:RUN singlestep test 1000 iterations
[33231.627056] kgdbts:RUN singlestep [0/1000]
[33235.954027] kgdbts:RUN singlestep [100/1000]
[33240.429086] kgdbts:RUN singlestep [200/1000]
[33244.687118] kgdbts:RUN singlestep [300/1000]
[33248.945191] kgdbts:RUN singlestep [400/1000]
[33253.203751] kgdbts:RUN singlestep [500/1000]
[33257.462019] kgdbts:RUN singlestep [600/1000]
[33261.817809] kgdbts:RUN singlestep [700/1000]
[33266.081268] kgdbts:RUN singlestep [800/1000]
[33270.339813] kgdbts:RUN singlestep [900/1000]
[33274.712404] kgdbts:RUN do_fork for 1000 breakpoints
~ #
v6:
- Change pstate register to 8 bytes to make endian nuetral.
Use GDB below GDB patch to display pstate in Big endian mode.
https://sourceware.org/ml/gdb-patches/2013-12/msg00720.html
Thanks to Andrew.
v5:
- Updated BRK #imm16 value to 0x400 & 0x401 as per recommendation
as per Marcus recommendataion
http://patchwork.ozlabs.org/patch/290801/
- Rebased to 3.13 AArch64 kernel
v4:
- Updated kgdb_single_step and kgdb_cpu_doing_single_step
variables properly based on gdb state
v3:
- Rebased to v4 version of Sandeepa Prabhu's patch (patch 1)
- Made dynamic break point instruction encoding generic
- Made ESR value encoding generic for dynamic and compile break point
- Used memcpy and memset to copy register contents to gdb buffer
- Fixed reordering of break point instruction by compiler with
patch 3
- Rebased against AAach64 upstream kernel
v2:
- Moved break instruction encoding to debug-monitors.h file
- Fixed endianess of compile break instruction encoding
- Updated I/O buffer sizes
- Updated register buffer size
- Remove changes to debug_exception handler in entry.S for
- ELR update and step debugging with update pc instead of ELR
- Rebased against AArch64 upstream kernel
v1:
- Initial patch-set
Vijaya Kumar K (6):
arm64: Add macros to manage processor debug state
arm64: KGDB: Add Basic KGDB support
arm64: KGDB: Add step debugging support
KGDB: make kgdb_breakpoint() as noinline
misc: debug: remove compilation warnings
arm64: KGDB: Add KGDB config
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/debug-monitors.h | 64 ++++--
arch/arm64/include/asm/irqflags.h | 23 +++
arch/arm64/include/asm/kgdb.h | 84 ++++++++
arch/arm64/include/asm/ptrace.h | 2 +-
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/debug-monitors.c | 1 +
arch/arm64/kernel/kgdb.c | 336 +++++++++++++++++++++++++++++++
kernel/debug/debug_core.c | 2 +-
9 files changed, 495 insertions(+), 19 deletions(-)
create mode 100644 arch/arm64/include/asm/kgdb.h
create mode 100644 arch/arm64/kernel/kgdb.c
--
1.7.9.5
^ permalink raw reply
* [Patch v3 2/2] dmaengine: qcom_bam_dma: Add device tree binding
From: Russell King - ARM Linux @ 2014-01-28 11:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4697306.PPWWh8UGTE@wuerfel>
On Tue, Jan 28, 2014 at 10:16:53AM +0100, Arnd Bergmann wrote:
> On Tuesday 28 January 2014 10:05:35 Lars-Peter Clausen wrote:
> > Why does the direction needs to be specified in specifier? I see two
> > options, either the direction per is fixed in hardware. In that case the DMA
> > controller node should describe which channel is which direction. Or the
> > direction is not fixed in hardware and can be changed at runtime in which
> > case it should be set on a per descriptor basis.
>
> Normally the direction is implied by dmaengine_slave_config().
No. The direction argument in there is deprecated - we've been talking
about removing it for some time.
DMA engine drivers should store all parameters of the configuration, and
then select the appropriate ones when preparing a transfer (which itself
involves a direction.)
Not doing this implies that if you have a half-duplex device, you have to
repeatedly issue a dmaengine_slave_config() call, a prepare call, and a
submit call to the DMA engine code for every segment you want to transfer.
We don't need that kind of DMA engine specific behaviour in DMA engine
users.
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply
* [alsa-devel] [PATCH 4/4] ASoC: tda998x: adjust the audio hw parameters from EDID
From: Takashi Iwai @ 2014-01-28 11:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128110051.GI11841@sirena.org.uk>
At Tue, 28 Jan 2014 11:00:51 +0000,
Mark Brown wrote:
>
> On Tue, Jan 28, 2014 at 10:23:57AM +0100, Takashi Iwai wrote:
> > Mark Brown wrote:
> > > On Mon, Jan 27, 2014 at 08:49:15PM +0000, Russell King - ARM Linux wrote:
>
> > > > Yes, preferably as a generic ALSA helper rather than an ASoC helper -
> > > > I don't see any need for this to be ASoC specific (I have a pure ALSA
> > > > driver which has very similar code in it.)
>
> > > Indeed, definitely ALSA generic - ideally we could factor a lot of the
> > > integration with the video side out.
>
> > Yes, indeed.
>
> > OTOH, as discussed recently, we're heading to move from ELD parsing to
> > more direct communication between video and audio drivers for
> > HD-audio. ELD will be still provided to user-space, but not evaluated
> > any longer in the new scenario.
>
> That sort of refactoring being one of the best reasons to keep things
> out of individual drivers! Having said all this I don't know if it's
> worth blocking Jean-Francois' work on that, it's an improvement in
> itself. Splitting the code out a bit would be good to help prepare but
> having the full refactoring done might be too much of a blocker.
I just rather wanted to point out the general direction for the
further development, didn't mean NAK. Jean-Francois' patch itself
looks simple enough, so I see no problem to take it for now as is.
Takashi
^ permalink raw reply
* [PATCH v11] clk: add MOXA ART SoCs clock driver
From: Jonas Jensen @ 2014-01-28 11:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390308261-4026-1-git-send-email-jonas.jensen@gmail.com>
MOXA ART SoCs allow to determine PLL output and APB frequencies
by reading registers holding multiplier and divisor information.
Add a clock driver for this SoC.
Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---
Notes:
Thanks for the replies,
Changes since v10:
1. add clock-specifier to DT binding description
2. remove local variable "rate"
3. add local variable "parent_name"
4. use clk_register_fixed_factor() instead of clk_register_fixed_rate()
5. remove flag CLK_IS_ROOT
Applies to next-20140128
.../bindings/clock/moxa,moxart-clock.txt | 48 +++++++++++
drivers/clk/Makefile | 1 +
drivers/clk/clk-moxart.c | 97 ++++++++++++++++++++++
3 files changed, 146 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
create mode 100644 drivers/clk/clk-moxart.c
diff --git a/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt b/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
new file mode 100644
index 0000000..fedea84
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
@@ -0,0 +1,48 @@
+Device Tree Clock bindings for arch-moxart
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+MOXA ART SoCs allow to determine PLL output and APB frequencies
+by reading registers holding multiplier and divisor information.
+
+
+PLL:
+
+Required properties:
+- compatible : Must be "moxa,moxart-pll-clock"
+- #clock-cells : Should be 0
+- reg : Should contain registers location and length
+- clocks : Should contain phandle + clock-specifier for the parent clock
+
+Optional properties:
+- clock-output-names : Should contain clock name
+
+
+APB:
+
+Required properties:
+- compatible : Must be "moxa,moxart-apb-clock"
+- #clock-cells : Should be 0
+- reg : Should contain registers location and length
+- clocks : Should contain phandle + clock-specifier for the parent clock
+
+Optional properties:
+- clock-output-names : Should contain clock name
+
+
+For example:
+
+ clk_pll: clk_pll at 98100000 {
+ compatible = "moxa,moxart-pll-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ };
+
+ clk_apb: clk_apb at 98100000 {
+ compatible = "moxa,moxart-apb-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ clocks = <&clk_pll>;
+ };
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 0faf730..7940d0c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-composite.o
# SoCs specific
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
+obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c
new file mode 100644
index 0000000..30a3b69
--- /dev/null
+++ b/drivers/clk/clk-moxart.c
@@ -0,0 +1,97 @@
+/*
+ * MOXA ART SoCs clock driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/clkdev.h>
+
+void __init moxart_of_pll_clk_init(struct device_node *node)
+{
+ static void __iomem *base;
+ struct clk *clk, *ref_clk;
+ unsigned int mul;
+ const char *name = node->name;
+ const char *parent_name;
+
+ of_property_read_string(node, "clock-output-names", &name);
+ parent_name = of_clk_get_parent_name(node, 0);
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: of_iomap failed\n", node->full_name);
+ return;
+ }
+
+ mul = readl(base + 0x30) >> 3 & 0x3f;
+ iounmap(base);
+
+ ref_clk = of_clk_get(node, 0);
+ if (IS_ERR(ref_clk)) {
+ pr_err("%s: of_clk_get failed\n", node->full_name);
+ return;
+ }
+
+ clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock\n", node->full_name);
+ return;
+ }
+
+ clk_register_clkdev(clk, NULL, name);
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
+ moxart_of_pll_clk_init);
+
+void __init moxart_of_apb_clk_init(struct device_node *node)
+{
+ static void __iomem *base;
+ struct clk *clk, *pll_clk;
+ unsigned int div, val;
+ unsigned int div_idx[] = { 2, 3, 4, 6, 8};
+ const char *name = node->name;
+ const char *parent_name;
+
+ of_property_read_string(node, "clock-output-names", &name);
+ parent_name = of_clk_get_parent_name(node, 0);
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: of_iomap failed\n", node->full_name);
+ return;
+ }
+
+ val = readl(base + 0xc) >> 4 & 0x7;
+ iounmap(base);
+
+ if (val > 4)
+ val = 0;
+ div = div_idx[val] * 2;
+
+ pll_clk = of_clk_get(node, 0);
+ if (IS_ERR(pll_clk)) {
+ pr_err("%s: of_clk_get failed\n", node->full_name);
+ return;
+ }
+
+ clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock\n", node->full_name);
+ return;
+ }
+
+ clk_register_clkdev(clk, NULL, name);
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
+ moxart_of_apb_clk_init);
--
1.8.2.1
^ permalink raw reply related
* [PATCH 2/9] ARM: dts: imx6sl: remove the use of pingrp macros
From: Sascha Hauer @ 2014-01-28 11:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5923680.sl3G3EgCsY@phil>
On Tue, Jan 28, 2014 at 11:17:22AM +0100, Heiko St?bner wrote:
> Hi Shawn,
>
> On Sunday, 26. January 2014 00:43:04 Shawn Guo wrote:
> > We created the pingrp macros in imx6sl-pingrp.h for purpose of less LOC
> > when same pin group is used by multiple boards. However, DT maintainers
> > take it as an abuse of DTC macro support. So let's get rid of it to
> > make the pins used by given device more intuitive.
> >
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> > arch/arm/boot/dts/imx6sl-evk.dts | 120 ++++++++++++++++++++++++++----
> > arch/arm/boot/dts/imx6sl-pingrp.h | 148
> > ------------------------------------- arch/arm/boot/dts/imx6sl.dtsi |
> > 1 -
> > 3 files changed, 107 insertions(+), 162 deletions(-)
> > delete mode 100644 arch/arm/boot/dts/imx6sl-pingrp.h
> >
> > diff --git a/arch/arm/boot/dts/imx6sl-evk.dts
> > b/arch/arm/boot/dts/imx6sl-evk.dts index f5e4513..8594d13 100644
> > --- a/arch/arm/boot/dts/imx6sl-evk.dts
> > +++ b/arch/arm/boot/dts/imx6sl-evk.dts
> > @@ -86,55 +86,149 @@
> > };
> >
> > pinctrl_ecspi1: ecspi1grp {
> > - fsl,pins = <MX6SL_ECSPI1_PINGRP1>;
> > + fsl,pins = <
> > + MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
> > + MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
> > + MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
> > + >;
> > };
> >
> > pinctrl_fec: fecgrp {
> > - fsl,pins = <MX6SL_FEC_PINGRP1>;
> > + fsl,pins = <
> > + MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
> > + MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
> > + MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
> > + MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
> > + MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
> > + MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
> > + MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
> > + MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
> > + MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
> > + >;
> > };
>
> [... and so on for the other groups ... ]
>
> I'm confused now :-) . Current linux-next [0] shows the pin-settings as part
> of imx6sl.dtsi - a way a lot of other architectures organize their pingroups
> too, with the board file only referencing the relevant pingroups from the
> predefined ones of the soc.
Current mainline has all groups under the iomux node which has the
effect that all possible groups are compiled into every dtb resulting in
very bloated dtbs. So Shawn changed it to what's currently in next, but
this hasn't been accepted by the dt maintainers. Now this series tries
to address the concerns of the dt maintainers by not using macros that
expand to other macros.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH v3 1/3] ARM: sun7i/sun6i: irqchip: Add irqchip driver for NMI controller
From: Hans de Goede @ 2014-01-28 11:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128104044.GC3867@lukather>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
On 01/28/2014 11:40 AM, Maxime Ripard wrote:
Jumping in here to try and clarify things, or so I hope at least :)
> On Fri, Jan 17, 2014 at 09:54:55AM +0100, Carlo Caione wrote:
>>>> +/* + * Ack level interrupts right before unmask + * + * In case of level-triggered interrupt, IRQ line must be acked before it + * is unmasked or else a double-interrupt is triggered + */ + +static void sunxi_sc_nmi_ack_and_unmask(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct irq_chip_type *ct = irq_data_get_chip_type(d); + u32 mask = d->mask; + + if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK) + ct->chip.irq_ack(d); + + irq_gc_lock(gc); + irq_reg_writel(mask, gc->reg_base + ct->regs.mask); +
>>>> irq_gc_unlock(gc); +}
>>>
>>> Hmmm, handle_level_irq seems to be doing exactly that already. It first masks and acks the interrupts, and then unmask it, so we should be fine, don't we?
>>
>> We don't, or at least handle_level_irq doesn't work for all the cases.
>
> This is what I find weird :)
>
>> Let's say (i.e. this is the cubieboard2 case) that to the irqchip is connected to the IRQ line of a PMIC accessed by I2C. In this case we cannot mask/ack the interrupt on the originating device in the hard interrupt handler (in which handle_level_irq is) since we need to access the I2C bus in an non-interrupt context.
>
> We agree here.
>
>> ACKing the IRQ in handle_level_irq at this point is pretty much useless since we still have to ACK the IRQs on the originating device and this will be done in a IRQ thread started after the hard IRQ handler.
>
> Ok, so what you're saying is that you want to adress this case:
>
> handle_level_irq | device device | mask ack handler irq acked unmask | | | | | | v v v v v v
>
> NMI -> GIC: +--------+ +----------------- ---------------+ +-----+
>
> PMIC -> NMI: +-+ +-+ ------------+ +-----------+ +--------------------
>
> Right?
No, the IRQ from the PMIC is a level sensitive IRQ, so it would look like this:
> handle_level_irq | device device | mask ack handler irq acked unmask | | | | | | v v v v v v
>
> NMI -> GIC: +------------------------------+ ---------------+ +--
>
> PMIC -> NMI: +-------------------------+ ------------+ +----------
The PMIC irq line won't go low until an i2c write to its irq status
registers write-clears all status bits for which the corresponding
bit in the irq-mask register is set.
And the only reason the NMI -> GIC also goes low is because the unmask
operation writes a second ack to the NMI controller in the unmask
callback of the NMI controller driver.
Note that we cannot use edge triggered interrupts here because the PMIC
has the typical setup with multiple irq status bits driving a single
irq line, so the irq handler does read irq-status, handle stuff,
write-clear irq-status. And if any other irq-status bits get set
between the read and write-clear the PMIC -> NMI line will stay
high, as it should since there are more interrupts to handle.
> But in this case, you would have two events coming from your device (the two rising edges), so you'd expect two interrupts. And in the case of a level triggered interrupt, the device would keep the interrupt line active until it's unmasked, so we wouldn't end up with this either.
>
>> sunxi_sc_nmi_ack_and_unmask is therefore called (by irq_finalize_oneshot) after the IRQ thread has been executed. After the IRQ thread has ACKed the IRQs on the originating device we can finally ACK and unmask again the NMI.
>
> And what happens if you get a new interrupt right between the end of the handler and the unmask?
The implicit ack done by the unmask will be ignored if the NMI line is still
high, just like the initial ack is ignored (which is why we need the mask),
and when the unmask completes the irq will immediately retrigger, as it should.
<snip>
>>> I really wonder whether it makes sense to have a generic chip here. It seems to be much more complicated than it should. It's only about a single interrupt interrupt chip here.
>>
>> I agree but is there any other way to manage the NMI without the driver of the device connected to NMI having to worry about acking/masking/unmasking/ etc..?
>
> Yes, just declare a "raw" irqchip. Pretty much like we do on irq-sun4i for example.
Hmm, I'm not going to say that using a raw irqchip here is a bad idea, it
sounds like it would be better.
But I don't think this will solve the need the mask / umask. The problem is
we need to do an i2c write to clear the interrupt source, which needs to
be done from a thread / workqueue. So when the interrupt handler finishes
the source won't be cleared yet, and AFAIK then only way to deal with this
is to mask the interrupt until we've cleared the interrupt source.
I agree that ideally we would be able to hide all this inside the NMI
controller driver, but I'm not sure if we can.
Regards,
Hans
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iEYEARECAAYFAlLnjj8ACgkQF3VEtJrzE/skqACgjGLU2QLQUq9o0pU1DuuWIUpx
YngAoJmbmCGEhkRBy5xFmKuXapilqzmM
=BoL/
-----END PGP SIGNATURE-----
^ permalink raw reply
* [alsa-devel] [PATCH 4/4] ASoC: tda998x: adjust the audio hw parameters from EDID
From: Mark Brown @ 2014-01-28 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <s5hppncihn6.wl%tiwai@suse.de>
On Tue, Jan 28, 2014 at 10:23:57AM +0100, Takashi Iwai wrote:
> Mark Brown wrote:
> > On Mon, Jan 27, 2014 at 08:49:15PM +0000, Russell King - ARM Linux wrote:
> > > Yes, preferably as a generic ALSA helper rather than an ASoC helper -
> > > I don't see any need for this to be ASoC specific (I have a pure ALSA
> > > driver which has very similar code in it.)
> > Indeed, definitely ALSA generic - ideally we could factor a lot of the
> > integration with the video side out.
> Yes, indeed.
> OTOH, as discussed recently, we're heading to move from ELD parsing to
> more direct communication between video and audio drivers for
> HD-audio. ELD will be still provided to user-space, but not evaluated
> any longer in the new scenario.
That sort of refactoring being one of the best reasons to keep things
out of individual drivers! Having said all this I don't know if it's
worth blocking Jean-Francois' work on that, it's an improvement in
itself. Splitting the code out a bit would be good to help prepare but
having the full refactoring done might be too much of a blocker.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140128/6ec7cfaf/attachment.sig>
^ permalink raw reply
* [PATCH v3 02/11] iommu/arm-smmu: Introduce iommu_group notifier block
From: Varun Sethi @ 2014-01-28 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140123195718.GC26399@alberich>
> -----Original Message-----
> From: iommu-bounces at lists.linux-foundation.org [mailto:iommu-
> bounces at lists.linux-foundation.org] On Behalf Of Andreas Herrmann
> Sent: Friday, January 24, 2014 1:27 AM
> To: Sethi Varun-B16395
> Cc: Andreas Herrmann; iommu at lists.linux-foundation.org; Will Deacon;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 02/11] iommu/arm-smmu: Introduce iommu_group
> notifier block
>
> On Wed, Jan 22, 2014 at 07:07:40PM +0000, Varun Sethi wrote:
> > > -----Original Message-----
> > > From: Will Deacon [mailto:will.deacon at arm.com]
> > > Sent: Wednesday, January 22, 2014 9:04 PM
> > > To: Sethi Varun-B16395
> > > Cc: Andreas Herrmann; iommu at lists.linux-foundation.org; linux-arm-
> > > kernel at lists.infradead.org; Andreas Herrmann
> > > Subject: Re: [PATCH v3 02/11] iommu/arm-smmu: Introduce iommu_group
> > > notifier block
> > >
> > > On Wed, Jan 22, 2014 at 01:54:11PM +0000, Varun Sethi wrote:
> > > > > > > Ok, so are you suggesting that we perform the isolation
> > > > > > > mapping in arm_smmu_add_device and drop the notifier
> altogether?
> > > > > > I think that should be fine, until we want to delay mapping
> > > > > > creation till driver bind time.
> > > > >
> > > > > Is there a hard dependency on that?
> > > > >
> > > > Not sure, may be Andreas can answer that.
> > >
> > > Ok. Andreas? I would have thought doing this *earlier* shouldn't be
> > > a problem (the DMA ops must be swizzled before the driver is probed).
> > >
> > > > > > But the "isolate device" property should dictate iommu group
> > > creation.
> > > > >
> > > > > The reason we added automatic group creation (per-device) is for
> > > > > VFIO, which expects all devices to be in a group regardless of
> > > > > the device isolation configuration.
> > > > >
> > > > IIUC, with the "isolate devices" property we ensure that there
> > > > would be independent SMR and S2CR per device. Is that correct?
> > >
> > > Yes, as part of giving them independent sets of page tables.
> > > Initially these tables don't have any valid mappings, but the
> > > dma-mapping API will populate them in response to
> dma_map_*/dma_alloc/etc.
> > >
> > > Not sure what this has to do with us putting devices into their own
> > > groups...
>
> > [Sethi Varun-B16395] Devices in an iommu group would share the dma
> > mapping, so shouldn't they be sharing the SMR and context registers?
>
> I aggree with the context but SMRs won't be shared. I think you just can
> say that a certain subset of the available SMRs will be used to map all
> devices in an iommu group to the same context. Depending on what
> streamIDs each device has you might have to use separate SMRs for each
> device to map it to the same context.
[Sethi Varun-B16395] IIUC the SMRs would unique per device, but there is a possibility where the number of context registers are restricted?
In that case IOMMU groups should correspond to unique stream IDs (and corresponding SMRs).
>
> > In case of the "isolate devices" property, each device would have its
> > own SMR and context registers, thus allowing the devices to have
> > independent mappings and allowing them to fall in separate iommu
> > groups.
>
> I aggree with Varun's view here. (Now that I take iommu groups into
> consideration.)
>
> But my goal with the "isolate devices" thing was twofold:
>
> 1. actual make use of SMMU for address translation for all master
> devices (instead of just bypassing the SMMU)
[Sethi Varun-B16395] even if masters have to share translation? But from the patch it seemed that we are creating mapping only if we find the isolate devices property.
>
> plus
>
> 2. put each master into it's own domain to isolate it
>
> The latter matches usage of separate iommu groups for devices. If we now
> use the isolate devices property to just control whether master devices
> fall into the same or separate iommu groups it seems to me we would need
> to have another mechanism that triggers the creation of a mapping for a
> group.
>
> What do you think?
>
[Sethi Varun-B16395] As mentioned before, we should be having iommu group per device (having a unique stream id). Isolate devices property just ensures that each device has a unique context. Now, for the devices for which we don't have the isolate device property, can't we have the multiple devices point to a common mapping.
-Varun
^ permalink raw reply
* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Arnd Bergmann @ 2014-01-28 10:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPDyKFpOhQtiyCmzie3=sfg42Vv5_rReRNgUf8kALoE6TBe2cw@mail.gmail.com>
On Tuesday 28 January 2014, Ulf Hansson wrote:
> On 28 January 2014 01:59, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> > On 27.01.2014 11:19, Ulf Hansson wrote:
> >> There is already a host capability that I think we could use to handle
> >> this. MMC_CAP_NONREMOVABLE, the corresponding DT binding string is
> >> "non-removable", and it may be set per host device.
> >>
> >> Using this cap means the mmc_rescan process that runs to detect new
> >> cards, will only be executed once and during boot. So, we need to make
> >> sure all resources and powers are provided to the card at this point.
> >> Otherwise the card will not be detected.
> >
> > I don't quite like this requirement, especially if you consider
> > multi-platform kernels where a lot of drivers is going to be provided as
> > modules. WLAN drivers are especially good candidates. This means that even
> > if the card is powered off at boot-up, if user (or init system) loads
> > appropriate module, which powers the chip on, MMC core must be able to
> > notice this.
>
> To be able to detect the card, the WLAN driver doesn't have to be
> probed, only the "power controller" driver. I suppose this is were it
> becomes a bit tricky.
>
> Somehow the mmc core needs to be involved in the probe process of the
> power controller driver. Could perhaps the power controller bus be
> located in the mmc core and thus the power controller driver needs to
> register itself by using a new API from the mmc core? Similar how SDIO
> func driver's register themselves.
I think there is another option, which does have its own pros and cons:
We could move all the power handling back into the sdio function driver
if we allow a secondary detection path using DT rather than the probing
of the SDIO bus. Essentially you'd have to list the class/vendor/device
ID for each function that cannot be autodetected in DT, and have the
SDIO core pretend that it found the device just by looking at the
device nodes, and register the struct sdio_func so it can be bound to
the driver. The driver then does all the power handling in a device
specific way. At some point the hardware gets registered at the
mmc host, and the sdio core connects the bus state to the already present
sdio_func, possibly notifying the function driver that it has become
usable.
Obviously, this can only work for CAP_NONREMOVABLE devices, but those
are exactly the ones we are worried about here. The advantage is that
the power sequencing for a particular device can then be in device
specific code and can have an arbitrarily complex in the driver without
needing the mmc code to handle all possible corner cases.
Arnd
^ permalink raw reply
* [PATCH] clk: divider: fix rate calculation for fractional rates
From: Tomi Valkeinen @ 2014-01-28 10:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128103253.GD15937@n2100.arm.linux.org.uk>
On 2014-01-28 12:32, Russell King - ARM Linux wrote:
>> Why I'm asking this is that for me (and probably for others also if
>> you've seen it used in the kernel code) it feels natural to have code like:
>>
>> rate = clk_round_rate(clk, rate);
>>
>> /* Verify the rounded rate here to see it's ok for the IP etc */
>>
>> /* The rate is ok, so set it */
>> clk_set_rate(clk, rate);
>
> If you want to do something with the rounded rate, then that's fine,
> you have a reason to do it this way. However, what I was referring to
> are drivers which literally do this:
>
> clk_set_rate(clk, clk_round_rate(clk, rate));
Thanks for clarification. Agreed, that's pointless. I gave the sequence
in the patch description just as an example for the sake of discussion
about the bug.
I didn't realize people actually do that in real code =).
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140128/97c9c93c/attachment.sig>
^ permalink raw reply
* [PATCH v3 1/3] ARM: sun7i/sun6i: irqchip: Add irqchip driver for NMI controller
From: Maxime Ripard @ 2014-01-28 10:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOQ7t2ay6UM-YAUSypRzC=_oSY=0L5RhD6FziG96j4aoK6RHsQ@mail.gmail.com>
On Fri, Jan 17, 2014 at 09:54:55AM +0100, Carlo Caione wrote:
> >> +/*
> >> + * Ack level interrupts right before unmask
> >> + *
> >> + * In case of level-triggered interrupt, IRQ line must be acked before it
> >> + * is unmasked or else a double-interrupt is triggered
> >> + */
> >> +
> >> +static void sunxi_sc_nmi_ack_and_unmask(struct irq_data *d)
> >> +{
> >> + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> >> + struct irq_chip_type *ct = irq_data_get_chip_type(d);
> >> + u32 mask = d->mask;
> >> +
> >> + if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK)
> >> + ct->chip.irq_ack(d);
> >> +
> >> + irq_gc_lock(gc);
> >> + irq_reg_writel(mask, gc->reg_base + ct->regs.mask);
> >> + irq_gc_unlock(gc);
> >> +}
> >
> > Hmmm, handle_level_irq seems to be doing exactly that already. It
> > first masks and acks the interrupts, and then unmask it, so we should
> > be fine, don't we?
>
> We don't, or at least handle_level_irq doesn't work for all the cases.
This is what I find weird :)
> Let's say (i.e. this is the cubieboard2 case) that to the irqchip is
> connected to the IRQ line of a PMIC accessed by I2C. In this case we
> cannot mask/ack the interrupt on the originating device in the hard
> interrupt handler (in which handle_level_irq is) since we need to
> access the I2C bus in an non-interrupt context.
We agree here.
> ACKing the IRQ in handle_level_irq at this point is pretty much
> useless since we still have to ACK the IRQs on the originating
> device and this will be done in a IRQ thread started after the hard
> IRQ handler.
Ok, so what you're saying is that you want to adress this case:
handle_level_irq
| device device
| mask ack handler irq acked unmask
| | | | | |
v v v v v v
NMI -> GIC:
+--------+ +-----------------
---------------+ +-----+
PMIC -> NMI:
+-+ +-+
------------+ +-----------+ +--------------------
Right?
But in this case, you would have two events coming from your device
(the two rising edges), so you'd expect two interrupts. And in the
case of a level triggered interrupt, the device would keep the
interrupt line active until it's unmasked, so we wouldn't end up with
this either.
> sunxi_sc_nmi_ack_and_unmask is therefore called (by
> irq_finalize_oneshot) after the IRQ thread has been executed. After
> the IRQ thread has ACKed the IRQs on the originating device we can
> finally ACK and unmask again the NMI.
And what happens if you get a new interrupt right between the end of
the handler and the unmask?
>
> >> +static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off,
> >> + u32 val)
> >> +{
> >> + irq_reg_writel(val, gc->reg_base + off);
> >> +}
> >> +
> >> +static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off)
> >> +{
> >> + return irq_reg_readl(gc->reg_base + off);
> >> +}
> >> +
> >> +static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc)
> >> +{
> >> + struct irq_domain *domain = irq_desc_get_handler_data(desc);
> >> + struct irq_chip *chip = irq_get_chip(irq);
> >> + unsigned int virq = irq_find_mapping(domain, 0);
> >> +
> >> + chained_irq_enter(chip, desc);
> >> + generic_handle_irq(virq);
> >> + chained_irq_exit(chip, desc);
> >> +}
> >> +
> >> +static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type)
> >> +{
> >> + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
> >> + struct irq_chip_type *ct = gc->chip_types;
> >> + u32 src_type_reg;
> >> + u32 ctrl_off = ct->regs.type;
> >> + unsigned int src_type;
> >> + unsigned int i;
> >> +
> >> + irq_gc_lock(gc);
> >> +
> >> + switch (flow_type & IRQF_TRIGGER_MASK) {
> >> + case IRQ_TYPE_EDGE_FALLING:
> >> + src_type = SUNXI_SRC_TYPE_EDGE_FALLING;
> >> + break;
> >> + case IRQ_TYPE_EDGE_RISING:
> >> + src_type = SUNXI_SRC_TYPE_EDGE_RISING;
> >> + break;
> >> + case IRQ_TYPE_LEVEL_HIGH:
> >> + src_type = SUNXI_SRC_TYPE_LEVEL_HIGH;
> >> + break;
> >> + case IRQ_TYPE_NONE:
> >> + case IRQ_TYPE_LEVEL_LOW:
> >> + src_type = SUNXI_SRC_TYPE_LEVEL_LOW;
> >> + break;
> >> + default:
> >> + irq_gc_unlock(gc);
> >> + pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n",
> >> + __func__, data->irq);
> >> + return -EBADR;
> >> + }
> >> +
> >> + irqd_set_trigger_type(data, flow_type);
> >> + irq_setup_alt_chip(data, flow_type);
> >> +
> >> + for (i = 0; i <= gc->num_ct; i++, ct++)
> >> + if (ct->type & flow_type)
> >> + ctrl_off = ct->regs.type;
> >> +
> >> + src_type_reg = sunxi_sc_nmi_read(gc, ctrl_off);
> >> + src_type_reg &= ~SUNXI_NMI_SRC_TYPE_MASK;
> >> + src_type_reg |= src_type;
> >> + sunxi_sc_nmi_write(gc, ctrl_off, src_type_reg);
> >> +
> >> + irq_gc_unlock(gc);
> >> +
> >> + return IRQ_SET_MASK_OK;
> >> +}
> >> +
> >> +static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
> >> + struct sunxi_sc_nmi_reg_offs *reg_offs)
> >> +{
> >> + struct irq_domain *domain;
> >> + struct irq_chip_generic *gc;
> >> + unsigned int irq;
> >> + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
> >> + int ret;
> >> +
> >> +
> >> + domain = irq_domain_add_linear(node, 1, &irq_generic_chip_ops, NULL);
> >> + if (!domain) {
> >> + pr_err("%s: Could not register interrupt domain.\n", node->name);
> >> + return -ENOMEM;
> >> + }
> >> +
> >> + ret = irq_alloc_domain_generic_chips(domain, 1, 2, node->name,
> >> + handle_level_irq, clr, 0,
> >> + IRQ_GC_INIT_MASK_CACHE);
> >> + if (ret) {
> >> + pr_err("%s: Could not allocate generic interrupt chip.\n",
> >> + node->name);
> >> + goto fail_irqd_remove;
> >> + }
> >> +
> >> + irq = irq_of_parse_and_map(node, 0);
> >> + if (irq <= 0) {
> >> + pr_err("%s: unable to parse irq\n", node->name);
> >> + ret = -EINVAL;
> >> + goto fail_irqd_remove;
> >> + }
> >> +
> >> + gc = irq_get_domain_generic_chip(domain, 0);
> >> + gc->reg_base = of_iomap(node, 0);
> >> + if (!gc->reg_base) {
> >> + pr_err("%s: unable to map resource\n", node->name);
> >> + ret = -ENOMEM;
> >> + goto fail_irqd_remove;
> >> + }
> >> +
> >> + gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK;
> >> + gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
> >> + gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
> >> + gc->chip_types[0].chip.irq_unmask = sunxi_sc_nmi_ack_and_unmask;
> >> + gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type;
> >> + gc->chip_types[0].regs.ack = reg_offs->pend;
> >> + gc->chip_types[0].regs.mask = reg_offs->enable;
> >> + gc->chip_types[0].regs.type = reg_offs->ctrl;
> >> +
> >> + gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
> >> + gc->chip_types[1].chip.name = gc->chip_types[0].chip.name;
> >> + gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit;
> >> + gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit;
> >> + gc->chip_types[1].chip.irq_unmask = sunxi_sc_nmi_ack_and_unmask;
> >> + gc->chip_types[1].chip.irq_set_type = sunxi_sc_nmi_set_type;
> >> + gc->chip_types[1].regs.ack = reg_offs->pend;
> >> + gc->chip_types[1].regs.mask = reg_offs->enable;
> >> + gc->chip_types[1].regs.type = reg_offs->ctrl;
> >> + gc->chip_types[1].handler = handle_edge_irq;
> >> +
> >> + irq_set_handler_data(irq, domain);
> >> + irq_set_chained_handler(irq, sunxi_sc_nmi_handle_irq);
> >> +
> >> + sunxi_sc_nmi_write(gc, reg_offs->enable, 0);
> >> + sunxi_sc_nmi_write(gc, reg_offs->pend, 0x1);
> >
> > I really wonder whether it makes sense to have a generic chip here. It
> > seems to be much more complicated than it should. It's only about a
> > single interrupt interrupt chip here.
>
> I agree but is there any other way to manage the NMI without the
> driver of the device connected to NMI having to worry about
> acking/masking/unmasking/ etc..?
Yes, just declare a "raw" irqchip. Pretty much like we do on irq-sun4i
for example.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140128/416961c6/attachment.sig>
^ permalink raw reply
* [PATCH] clk: divider: fix rate calculation for fractional rates
From: Russell King - ARM Linux @ 2014-01-28 10:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52E76E3A.8030807@ti.com>
On Tue, Jan 28, 2014 at 10:45:46AM +0200, Tomi Valkeinen wrote:
> Russell, I'd like to understand why you think the original example is bad:
>
> rate = clk_round_rate(clk, rate);
> clk_set_rate(clk, rate);
It's needlessly wasteful. All the processing for setting the rate is
repeated.
> If the definition of clk_round_rate is basically "clk_set_rate without
> actually setting the rate", I agree that the above code is not good as
> it might not work correctly.
>
> However, if the following code you gave should work:
>
> rate = clk_get_rate(clk);
> clk_set_rate(clk, rate);
> assert(clk_get_rate(clk) == rate);
>
> then the original example should also always work, as it's almost the
> same as:
>
> /* this is the "round" part */
> clk_set_rate(clk, rate);
> rate = clk_get_rate(clk);
>
> clk_set_rate(clk, rate);
> assert(clk_get_rate(clk) == rate);
Okay, now ask yourself this - would you code the above into your driver
with no processing between the two? It seems that some people would!
> Why I'm asking this is that for me (and probably for others also if
> you've seen it used in the kernel code) it feels natural to have code like:
>
> rate = clk_round_rate(clk, rate);
>
> /* Verify the rounded rate here to see it's ok for the IP etc */
>
> /* The rate is ok, so set it */
> clk_set_rate(clk, rate);
If you want to do something with the rounded rate, then that's fine,
you have a reason to do it this way. However, what I was referring to
are drivers which literally do this:
clk_set_rate(clk, clk_round_rate(clk, rate));
In other words, they think that they must always round the rate before
passing it into clk_set_rate() even though they make no other use of
the rounded rate. That is completely wasteful and unnecessary. It
might as well have clk_round_rate() replaced by a udelay() to waste
some CPU cycles just for the hell of it.
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply
* [PATCH v5 01/20] ARM: Introduce atomic MMIO modify
From: Ezequiel Garcia @ 2014-01-28 10:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390836440-12744-2-git-send-email-ezequiel.garcia@free-electrons.com>
On Mon, Jan 27, 2014 at 12:27:01PM -0300, Ezequiel Garcia wrote:
> Some SoC have MMIO regions that are shared across orthogonal
> subsystems. This commit implements a possible solution for the
> thread-safe access of such regions through a spinlock-protected API.
>
> Concurrent access is protected with a single spinlock for the
> entire MMIO address space. While this protects shared-registers,
> it also serializes access to unrelated/unshared registers.
>
> We add relaxed and non-relaxed variants, by using writel_relaxed and writel,
> respectively. The rationale for this is that some users may not require
> register write completion but only thread-safe access to a register.
>
> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
> Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> ---
> Russell,
>
> Can you confirm this patch is on its way to v3.14?
>
ping?
--
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH 1/9] ARM: dts: imx6qdl: remove the use of pingrp macros
From: Shawn Guo @ 2014-01-28 10:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127143745.GM15937@n2100.arm.linux.org.uk>
On Mon, Jan 27, 2014 at 02:37:45PM +0000, Russell King - ARM Linux wrote:
> On Sun, Jan 26, 2014 at 12:43:03AM +0800, Shawn Guo wrote:
> > arch/arm/boot/dts/imx6dl-hummingboard.dts | 5 +-
> > arch/arm/boot/dts/imx6qdl-microsom.dtsi | 5 +-
>
> I've merged your changes here into my local copy of these just to reduce
> the conflicts - unfortunately, it's taken soo long to deal with the above
> that the cubox-i has now been released, which has prompted some
> reorganisation between the above two files.
>
> I would much rather you dropped these two entirely, and let me push them
> upstream, rather than having some nasty conflicts which result from this.
Dropped hummingboard from my tree.
Shawn
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox